PyLibMS 4.2.3__tar.gz → 4.2.5__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.2.3 → pylibms-4.2.5}/PKG-INFO +17 -7
- {pylibms-4.2.3 → pylibms-4.2.5}/PyLibMS.egg-info/PKG-INFO +17 -7
- {pylibms-4.2.3 → pylibms-4.2.5}/README.md +16 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/field/io.py +17 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/field/lms_datatype.py +4 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/field/lms_field.py +20 -10
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/lms_constants.py +1 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/stream/fileinfo.py +12 -3
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/stream/hashtable.py +6 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/stream/section.py +7 -7
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/fileio/encoding.py +1 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/fileio/io.py +1 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/definitions/flowchart.py +11 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/definitions/node.py +125 -91
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/definitions/node_type.py +22 -9
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/flw3.py +111 -47
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/msbf.py +37 -10
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/msbfio.py +30 -20
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/lms_messagetext.py +21 -13
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/msbt.py +27 -18
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/msbtentry.py +10 -10
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/msbtio.py +32 -18
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/section/atr1.py +7 -8
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/section/txt2.py +1 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/tag/io/param_io.py +6 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/tag/io/tag_io.py +17 -16
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/tag/lms_tag.py +26 -16
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/definitions/tag.py +19 -17
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/msbp.py +7 -7
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/msbpread.py +5 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/config.py +16 -17
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/definitions/attribute.py +0 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/definitions/nodes.py +62 -29
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/definitions/tags.py +4 -2
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Tomodachi Life NA-EU.yaml +57 -6
- {pylibms-4.2.3 → pylibms-4.2.5}/pyproject.toml +1 -1
- {pylibms-4.2.3 → pylibms-4.2.5}/LICENSE +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/MANIFEST.in +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/PyLibMS.egg-info/SOURCES.txt +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/PyLibMS.egg-info/dependency_links.txt +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/PyLibMS.egg-info/requires.txt +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/PyLibMS.egg-info/top_level.txt +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/field/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/lms_exceptions.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/common/lms_fileinfo.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/definitions/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/flowchart/definitions/lms_nodeexceptions.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/definitions/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/definitions/field/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/section/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/section/nli1.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/section/tsy1.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/tag/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/message/tag/lms_tagexceptions.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/definitions/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/definitions/attribute.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/definitions/color.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/definitions/style.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/ali2.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/ati2.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/clr1.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/string.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/syl3.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/tag2.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/tgg2.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/project/section/tgp2.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/definitions/__init__.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/definitions/value.py +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Badge Arcade.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Brain Age Concentration Training.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Kirby Planet Robobot.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Super Mario 3D Land.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Super Mario Odyssey.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/lms/titleconfig/presets/Tomodachi Life Living The Dream.yaml +0 -0
- {pylibms-4.2.3 → pylibms-4.2.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.5
|
|
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
|
|
@@ -20,10 +20,13 @@ Requires-Dist: requests>=2.34.0
|
|
|
20
20
|
Dynamic: license-file
|
|
21
21
|
|
|
22
22
|
# PyLibMS
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/PyLibMS/)
|
|
25
|
+

|
|
24
26
|
[](https://badge.fury.io/py/PyLibMS)
|
|
25
27
|
|
|
26
|
-
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
28
|
+
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
29
|
+
formats from Nintendo.
|
|
27
30
|
|
|
28
31
|
The following is supported
|
|
29
32
|
| Format | Read | Write | Configuration Support |
|
|
@@ -32,7 +35,9 @@ The following is supported
|
|
|
32
35
|
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
33
36
|
| `MSBP` | ✅ | ❌ | Generating configuration files for use with `MSBT` files. |
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
|
|
39
|
+
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
40
|
+
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
36
41
|
|
|
37
42
|
# Features and Usage
|
|
38
43
|
|
|
@@ -50,25 +55,27 @@ msbt = read_msbt_path("Text.msbt")
|
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
### MSBP
|
|
58
|
+
|
|
53
59
|
```py
|
|
54
60
|
from lms.project.msbpread import read_msbp_path
|
|
55
61
|
|
|
56
62
|
msbp = read_msbp_path("Project.msbp")
|
|
57
63
|
```
|
|
58
64
|
|
|
59
|
-
|
|
60
65
|
### MSBF
|
|
66
|
+
|
|
61
67
|
```py
|
|
62
68
|
from lms.flowchart.msbfio import read_msbf_path
|
|
63
69
|
|
|
64
70
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
|
|
68
73
|
## Writing
|
|
74
|
+
|
|
69
75
|
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
70
76
|
|
|
71
77
|
### MSBT
|
|
78
|
+
|
|
72
79
|
```py
|
|
73
80
|
from lms.message.msbtio import write_msbt_path
|
|
74
81
|
|
|
@@ -76,6 +83,7 @@ write_msbt_path("Out_text.msbt")
|
|
|
76
83
|
```
|
|
77
84
|
|
|
78
85
|
### MSBF
|
|
86
|
+
|
|
79
87
|
```py
|
|
80
88
|
from lms.flowchart.msbfio import write_msbf_path
|
|
81
89
|
|
|
@@ -107,7 +115,9 @@ pip install -e .
|
|
|
107
115
|
```
|
|
108
116
|
|
|
109
117
|
# Credits & Sources
|
|
110
|
-
|
|
118
|
+
|
|
119
|
+
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
120
|
+
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
111
121
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
112
122
|
formats.
|
|
113
123
|
* [Trippixyz](https://github.com/Trippixyz): For helping me get started general decompilation of the formats and general
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.5
|
|
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
|
|
@@ -20,10 +20,13 @@ Requires-Dist: requests>=2.34.0
|
|
|
20
20
|
Dynamic: license-file
|
|
21
21
|
|
|
22
22
|
# PyLibMS
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/PyLibMS/)
|
|
25
|
+

|
|
24
26
|
[](https://badge.fury.io/py/PyLibMS)
|
|
25
27
|
|
|
26
|
-
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
28
|
+
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
29
|
+
formats from Nintendo.
|
|
27
30
|
|
|
28
31
|
The following is supported
|
|
29
32
|
| Format | Read | Write | Configuration Support |
|
|
@@ -32,7 +35,9 @@ The following is supported
|
|
|
32
35
|
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
33
36
|
| `MSBP` | ✅ | ❌ | Generating configuration files for use with `MSBT` files. |
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
|
|
39
|
+
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
40
|
+
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
36
41
|
|
|
37
42
|
# Features and Usage
|
|
38
43
|
|
|
@@ -50,25 +55,27 @@ msbt = read_msbt_path("Text.msbt")
|
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
### MSBP
|
|
58
|
+
|
|
53
59
|
```py
|
|
54
60
|
from lms.project.msbpread import read_msbp_path
|
|
55
61
|
|
|
56
62
|
msbp = read_msbp_path("Project.msbp")
|
|
57
63
|
```
|
|
58
64
|
|
|
59
|
-
|
|
60
65
|
### MSBF
|
|
66
|
+
|
|
61
67
|
```py
|
|
62
68
|
from lms.flowchart.msbfio import read_msbf_path
|
|
63
69
|
|
|
64
70
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
65
71
|
```
|
|
66
72
|
|
|
67
|
-
|
|
68
73
|
## Writing
|
|
74
|
+
|
|
69
75
|
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
70
76
|
|
|
71
77
|
### MSBT
|
|
78
|
+
|
|
72
79
|
```py
|
|
73
80
|
from lms.message.msbtio import write_msbt_path
|
|
74
81
|
|
|
@@ -76,6 +83,7 @@ write_msbt_path("Out_text.msbt")
|
|
|
76
83
|
```
|
|
77
84
|
|
|
78
85
|
### MSBF
|
|
86
|
+
|
|
79
87
|
```py
|
|
80
88
|
from lms.flowchart.msbfio import write_msbf_path
|
|
81
89
|
|
|
@@ -107,7 +115,9 @@ pip install -e .
|
|
|
107
115
|
```
|
|
108
116
|
|
|
109
117
|
# Credits & Sources
|
|
110
|
-
|
|
118
|
+
|
|
119
|
+
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
120
|
+
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
111
121
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
112
122
|
formats.
|
|
113
123
|
* [Trippixyz](https://github.com/Trippixyz): For helping me get started general decompilation of the formats and general
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# PyLibMS
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/PyLibMS/)
|
|
4
|
+

|
|
3
5
|
[](https://badge.fury.io/py/PyLibMS)
|
|
4
6
|
|
|
5
|
-
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
7
|
+
PyLibMS is a library built in Python 3.10 and above for reading and writing of libMessageStudio (LMS) proprietary file
|
|
8
|
+
formats from Nintendo.
|
|
6
9
|
|
|
7
10
|
The following is supported
|
|
8
11
|
| Format | Read | Write | Configuration Support |
|
|
@@ -11,7 +14,9 @@ The following is supported
|
|
|
11
14
|
| `MSBF` | ✅ | ✅ | Support for custom node definitions, attaching names and descriptions to nodes. Altering parameter datatypes for flexibility between games. |
|
|
12
15
|
| `MSBP` | ✅ | ❌ | Generating configuration files for use with `MSBT` files. |
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
|
|
18
|
+
This library is designed to support LMS revision >=3.0. These include files generated for late **Wii** titles,
|
|
19
|
+
**Nintendo 3DS**, **Wii U**, **Mobile**, **Nintendo Switch** and **Nintendo Switch 2** games.
|
|
15
20
|
|
|
16
21
|
# Features and Usage
|
|
17
22
|
|
|
@@ -29,25 +34,27 @@ msbt = read_msbt_path("Text.msbt")
|
|
|
29
34
|
```
|
|
30
35
|
|
|
31
36
|
### MSBP
|
|
37
|
+
|
|
32
38
|
```py
|
|
33
39
|
from lms.project.msbpread import read_msbp_path
|
|
34
40
|
|
|
35
41
|
msbp = read_msbp_path("Project.msbp")
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
39
44
|
### MSBF
|
|
45
|
+
|
|
40
46
|
```py
|
|
41
47
|
from lms.flowchart.msbfio import read_msbf_path
|
|
42
48
|
|
|
43
49
|
msbf = read_msbf_path("Flowchart.msbf")
|
|
44
50
|
```
|
|
45
51
|
|
|
46
|
-
|
|
47
52
|
## Writing
|
|
53
|
+
|
|
48
54
|
There is no writing for `MSBP` files as most of the time it acts as leftover metadata and not actually loaded by games.
|
|
49
55
|
|
|
50
56
|
### MSBT
|
|
57
|
+
|
|
51
58
|
```py
|
|
52
59
|
from lms.message.msbtio import write_msbt_path
|
|
53
60
|
|
|
@@ -55,6 +62,7 @@ write_msbt_path("Out_text.msbt")
|
|
|
55
62
|
```
|
|
56
63
|
|
|
57
64
|
### MSBF
|
|
65
|
+
|
|
58
66
|
```py
|
|
59
67
|
from lms.flowchart.msbfio import write_msbf_path
|
|
60
68
|
|
|
@@ -86,7 +94,9 @@ pip install -e .
|
|
|
86
94
|
```
|
|
87
95
|
|
|
88
96
|
# Credits & Sources
|
|
89
|
-
|
|
97
|
+
|
|
98
|
+
* [SS-Decomp](https://github.com/zeldaret/ss): Referenced some parts of their MSBF decomp when adding the format
|
|
99
|
+
to [Nintendo-File-Formats](https://nintendo-formats.com) and this library.
|
|
90
100
|
* [Nintendo-File-Formats](https://nintendo-formats.com) by Kinnay: For existing information on the MSBT and MSBP file
|
|
91
101
|
formats.
|
|
92
102
|
* [Trippixyz](https://github.com/Trippixyz): For helping me get started general decompilation of the formats and general
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
from typing import Callable
|
|
2
2
|
|
|
3
|
-
from lms.common.field.lms_datatype import (
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
from lms.common.field.lms_datatype import (
|
|
4
|
+
LMS_DataType,
|
|
5
|
+
is_bool_datatype,
|
|
6
|
+
is_bytes_datatype,
|
|
7
|
+
is_list_datatype,
|
|
8
|
+
is_number_datatype,
|
|
9
|
+
)
|
|
6
10
|
from lms.common.field.lms_field import LMS_Field
|
|
7
11
|
from lms.fileio.io import FileReader, FileWriter
|
|
8
12
|
from lms.titleconfig.definitions.value import ValueDefinition
|
|
9
13
|
|
|
10
14
|
|
|
11
|
-
def read_field(
|
|
12
|
-
|
|
15
|
+
def read_field(
|
|
16
|
+
reader: FileReader,
|
|
17
|
+
definition: ValueDefinition,
|
|
18
|
+
read_variable_width_value: Callable | None = None,
|
|
19
|
+
) -> LMS_Field:
|
|
13
20
|
# String is excluded as their reading varies between MSBT/MSBF
|
|
14
21
|
match definition.datatype:
|
|
15
22
|
case LMS_DataType.UINT8:
|
|
@@ -43,7 +50,11 @@ def read_field(reader: FileReader, definition: ValueDefinition,
|
|
|
43
50
|
return LMS_Field(value, definition) # type: ignore
|
|
44
51
|
|
|
45
52
|
|
|
46
|
-
def write_field(
|
|
53
|
+
def write_field(
|
|
54
|
+
writer: FileWriter,
|
|
55
|
+
field: LMS_Field,
|
|
56
|
+
write_variable_width_value: Callable | None = None,
|
|
57
|
+
) -> None:
|
|
47
58
|
if is_number_datatype(field.value, field.datatype):
|
|
48
59
|
write_functions: dict[LMS_DataType, Callable] = {
|
|
49
60
|
LMS_DataType.UINT8: writer.write_uint8,
|
|
@@ -119,9 +119,7 @@ class LMS_DataType(Enum):
|
|
|
119
119
|
try:
|
|
120
120
|
return sizes[self]
|
|
121
121
|
except KeyError:
|
|
122
|
-
raise TypeError(
|
|
123
|
-
f"Stream size is not defined for '{self.to_string()}'."
|
|
124
|
-
)
|
|
122
|
+
raise TypeError(f"Stream size is not defined for '{self.to_string()}'.")
|
|
125
123
|
|
|
126
124
|
@classmethod
|
|
127
125
|
def from_string(cls, string: str):
|
|
@@ -138,8 +136,8 @@ class LMS_DataType(Enum):
|
|
|
138
136
|
|
|
139
137
|
|
|
140
138
|
def verify_number_from_datatype(
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
value: int | float,
|
|
140
|
+
datatype: LMS_DataType,
|
|
143
141
|
):
|
|
144
142
|
if datatype is LMS_DataType.FLOAT32:
|
|
145
143
|
max_value = FLOAT32_MAX
|
|
@@ -150,7 +148,7 @@ def verify_number_from_datatype(
|
|
|
150
148
|
max_value = 2 ** (bits - 1)
|
|
151
149
|
min_value = -max_value
|
|
152
150
|
else:
|
|
153
|
-
min_value, max_value = 0, (2
|
|
151
|
+
min_value, max_value = 0, (2**bits) - 1
|
|
154
152
|
|
|
155
153
|
if not min_value <= value <= max_value:
|
|
156
154
|
raise ValueError(
|
|
@@ -36,20 +36,28 @@ class LMS_FieldMap:
|
|
|
36
36
|
"""Converts the field map to a regular dictionary."""
|
|
37
37
|
return {field.name: field.value for field in self.fields.values()}
|
|
38
38
|
|
|
39
|
-
@
|
|
40
|
-
def
|
|
41
|
-
|
|
39
|
+
@staticmethod
|
|
40
|
+
def create_default_dict_map(
|
|
41
|
+
definitions: list[ValueDefinition],
|
|
42
|
+
) -> dict[str, FieldValue]:
|
|
43
|
+
map = {}
|
|
42
44
|
for definition in definitions:
|
|
43
45
|
match definition.datatype:
|
|
46
|
+
case LMS_DataType.STRING:
|
|
47
|
+
map[definition.name] = ""
|
|
44
48
|
case LMS_DataType.LIST:
|
|
45
|
-
|
|
49
|
+
map[definition.name] = definition.list_items[0]
|
|
46
50
|
case LMS_DataType.BOOL:
|
|
47
|
-
|
|
51
|
+
map[definition.name] = False
|
|
48
52
|
case LMS_DataType.FLOAT32:
|
|
49
|
-
|
|
53
|
+
map[definition.name] = 0.0
|
|
50
54
|
case _:
|
|
51
|
-
|
|
52
|
-
return
|
|
55
|
+
map[definition.name] = 0
|
|
56
|
+
return map
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def create_default_map(cls, definitions: list[ValueDefinition]):
|
|
60
|
+
return cls.from_dict(LMS_FieldMap.create_default_map(definitions), definitions)
|
|
53
61
|
|
|
54
62
|
@classmethod
|
|
55
63
|
def from_dict(cls, data: dict[str, FieldValue], definitions: list[ValueDefinition]):
|
|
@@ -95,7 +103,9 @@ class LMS_Field:
|
|
|
95
103
|
"""
|
|
96
104
|
|
|
97
105
|
def __init__(
|
|
98
|
-
|
|
106
|
+
self,
|
|
107
|
+
value: int | str | float | bytes | bool,
|
|
108
|
+
definition: ValueDefinition,
|
|
99
109
|
):
|
|
100
110
|
_verify_value_from_definition(value, definition)
|
|
101
111
|
self._definition = definition
|
|
@@ -139,7 +149,7 @@ class LMS_Field:
|
|
|
139
149
|
|
|
140
150
|
|
|
141
151
|
def _verify_value_from_definition(
|
|
142
|
-
|
|
152
|
+
value: int | str | float | bytes | bool, definition: ValueDefinition
|
|
143
153
|
) -> None:
|
|
144
154
|
datatype = definition.datatype
|
|
145
155
|
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
from lms.common import lms_exceptions
|
|
2
|
-
from lms.common.lms_constants import
|
|
2
|
+
from lms.common.lms_constants import (
|
|
3
|
+
BIG_ENDIAN_BOM,
|
|
4
|
+
SECTION_DATA_START,
|
|
5
|
+
LITTLE_ENDIAN_BOM,
|
|
6
|
+
SIZE_OFFSET,
|
|
7
|
+
)
|
|
3
8
|
from lms.common.lms_fileinfo import LMS_FileInfo
|
|
4
9
|
from lms.fileio.encoding import FileEncoding
|
|
5
10
|
from lms.fileio.io import FileReader, FileWriter
|
|
@@ -25,7 +30,9 @@ def read_file_info(reader: FileReader, expected_magic: str) -> LMS_FileInfo:
|
|
|
25
30
|
version = reader.read_uint8()
|
|
26
31
|
|
|
27
32
|
if version < 3:
|
|
28
|
-
raise lms_exceptions.LMS_UnsupportedFileVersionError(
|
|
33
|
+
raise lms_exceptions.LMS_UnsupportedFileVersionError(
|
|
34
|
+
"Only version 3+ files are supported!"
|
|
35
|
+
)
|
|
29
36
|
|
|
30
37
|
section_count = reader.read_uint16()
|
|
31
38
|
|
|
@@ -34,7 +41,9 @@ def read_file_info(reader: FileReader, expected_magic: str) -> LMS_FileInfo:
|
|
|
34
41
|
|
|
35
42
|
reader.seek(0, 2)
|
|
36
43
|
if file_size != (real_size := reader.tell()):
|
|
37
|
-
raise lms_exceptions.LMS_MisalignedSizeError(
|
|
44
|
+
raise lms_exceptions.LMS_MisalignedSizeError(
|
|
45
|
+
f"File size is misaligned!` Got {file_size} expected {real_size}."
|
|
46
|
+
)
|
|
38
47
|
|
|
39
48
|
reader.seek(SECTION_DATA_START)
|
|
40
49
|
|
|
@@ -27,7 +27,12 @@ def read_labels(reader: FileReader) -> tuple[dict, int]:
|
|
|
27
27
|
return sorted_labels, slot_count
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def write_labels(
|
|
30
|
+
def write_labels(
|
|
31
|
+
writer: FileWriter,
|
|
32
|
+
labels: list[str],
|
|
33
|
+
slot_count: int,
|
|
34
|
+
index_map: dict[str, int] = None,
|
|
35
|
+
) -> None:
|
|
31
36
|
writer.write_uint32(slot_count)
|
|
32
37
|
|
|
33
38
|
hash_slots = {}
|
|
@@ -2,12 +2,12 @@ from typing import Any, Callable, Generator
|
|
|
2
2
|
|
|
3
3
|
from lms.fileio.io import FileReader, FileWriter
|
|
4
4
|
|
|
5
|
-
SECTION_PADDING_BYTE = b"\
|
|
5
|
+
SECTION_PADDING_BYTE = b"\xab"
|
|
6
6
|
SECTION_ALIGNMENT = 16
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def read_section_data(
|
|
10
|
-
|
|
10
|
+
reader: FileReader, section_count: int
|
|
11
11
|
) -> Generator[tuple[str, int], Any, None]:
|
|
12
12
|
reader.seek(0x20)
|
|
13
13
|
for _ in range(section_count):
|
|
@@ -24,11 +24,11 @@ def read_section_data(
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def write_section(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
writer: FileWriter,
|
|
28
|
+
magic: str,
|
|
29
|
+
section_call: Callable,
|
|
30
|
+
data: list[Any],
|
|
31
|
+
*write_arguments: Any,
|
|
32
32
|
) -> None:
|
|
33
33
|
writer.write_string(magic)
|
|
34
34
|
size_offset = writer.tell()
|
|
@@ -10,7 +10,7 @@ class FileEncoding(IntEnum):
|
|
|
10
10
|
UTF32 = 0x02
|
|
11
11
|
|
|
12
12
|
def to_string_format(
|
|
13
|
-
|
|
13
|
+
self, is_big_endian: bool = False
|
|
14
14
|
) -> Literal["UTF-8", "UTF-16-BE", "UTF-16-LE", "UTF-32-BE", "UTF-32-LE"]:
|
|
15
15
|
"""Converts the FileEncoding to string format."""
|
|
16
16
|
match self:
|
|
@@ -106,7 +106,7 @@ class FileReader:
|
|
|
106
106
|
def read_encoded_string(self):
|
|
107
107
|
message = b""
|
|
108
108
|
while (
|
|
109
|
-
|
|
109
|
+
raw_char := self.read_bytes(self.encoding.width)
|
|
110
110
|
) != self.encoding.terminator:
|
|
111
111
|
message += raw_char
|
|
112
112
|
return message.decode(self.encoding.to_string_format(self.is_big_endian))
|
|
@@ -7,7 +7,9 @@ from lms.flowchart.definitions.node import LMS_EntryNode, LMS_BranchNode, LMS_Ba
|
|
|
7
7
|
class LMS_Flowchart:
|
|
8
8
|
"""Class that represents a flowchart in a MSBF file."""
|
|
9
9
|
|
|
10
|
-
def __init__(
|
|
10
|
+
def __init__(
|
|
11
|
+
self, entry_point: LMS_EntryNode, id_generator: Callable[[], int]
|
|
12
|
+
) -> None:
|
|
11
13
|
self._entry_node = entry_point
|
|
12
14
|
self._nodes: dict[int, LMS_BaseNode] = {}
|
|
13
15
|
self._id_generator = id_generator
|
|
@@ -16,7 +18,6 @@ class LMS_Flowchart:
|
|
|
16
18
|
for node in entry_point.get_descendents():
|
|
17
19
|
self._nodes[node.id] = node
|
|
18
20
|
|
|
19
|
-
|
|
20
21
|
def __iter__(self) -> Iterator[LMS_BaseNode]:
|
|
21
22
|
return iter(self._nodes.values())
|
|
22
23
|
|
|
@@ -28,7 +29,7 @@ class LMS_Flowchart:
|
|
|
28
29
|
|
|
29
30
|
@property
|
|
30
31
|
def name(self) -> str:
|
|
31
|
-
"""The name of the flowchart.
|
|
32
|
+
"""The name of the flowchart."""
|
|
32
33
|
return self._entry_node.flowchart_name
|
|
33
34
|
|
|
34
35
|
@name.setter
|
|
@@ -41,7 +42,7 @@ class LMS_Flowchart:
|
|
|
41
42
|
return self._entry_node
|
|
42
43
|
|
|
43
44
|
@property
|
|
44
|
-
def nodes(self) -> MappingProxyType[LMS_BaseNode]:
|
|
45
|
+
def nodes(self) -> MappingProxyType[int, LMS_BaseNode]:
|
|
45
46
|
"""All nodes in the flowchart instance."""
|
|
46
47
|
return MappingProxyType(self._nodes)
|
|
47
48
|
|
|
@@ -52,10 +53,14 @@ class LMS_Flowchart:
|
|
|
52
53
|
:param node: the node to add.
|
|
53
54
|
"""
|
|
54
55
|
if not isinstance(node, LMS_BaseNode):
|
|
55
|
-
raise TypeError(
|
|
56
|
+
raise TypeError(
|
|
57
|
+
f"Node type '{type(node).__name__}' is not a child of LMS_BaseNode!"
|
|
58
|
+
)
|
|
56
59
|
|
|
57
60
|
if node in self._nodes.values():
|
|
58
|
-
raise ValueError(
|
|
61
|
+
raise ValueError(
|
|
62
|
+
f"Node of ID '{node.id}' is already registered to this flowchart!"
|
|
63
|
+
)
|
|
59
64
|
|
|
60
65
|
node.id = self._id_generator()
|
|
61
66
|
self._nodes[node.id] = node
|