PyLibMS 3.3.5__tar.gz → 3.3.8__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-3.3.5 → pylibms-3.3.8}/PKG-INFO +1 -1
- {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/PKG-INFO +1 -1
- {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/SOURCES.txt +1 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/io/param_io.py +3 -1
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/io/tag_io.py +1 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/tag.py +1 -3
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/string.py +2 -1
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/config.py +7 -5
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/tags.py +8 -12
- pylibms-3.3.8/lms/titleconfig/presets/Tomodachi Life Living the Dream Demo.yaml +3369 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/pyproject.toml +1 -1
- pylibms-3.3.5/lms/titleconfig/presets/Tomodachi Life Living the Dream Demo.yaml +0 -13054
- {pylibms-3.3.5 → pylibms-3.3.8}/LICENSE +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/MANIFEST.in +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/dependency_links.txt +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/requires.txt +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/top_level.txt +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/README.md +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_datatype.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_exceptions.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_fileinfo.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/fileinfo.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/hashtable.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/section.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/fileio/encoding.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/fileio/io.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/io.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/lms_field.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/lms_messagetext.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbt.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbtentry.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbtio.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/atr1.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/nli1.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/tsy1.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/txt2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/lms_tag.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/lms_tagexceptions.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/attribute.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/color.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/style.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/msbp.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/msbpread.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/ali2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/ati2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/clr1.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/syl3.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tag2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tgg2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tgp2.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/__init__.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/attribute.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/value.py +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Badge Arcade.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Brain Age Concentration Training.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Kirby Planet Robobot.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario 3D Land.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario Odyssey.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Tomodachi Life.yaml +0 -0
- {pylibms-3.3.5 → pylibms-3.3.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.8
|
|
4
4
|
Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and soon to be MSBF.
|
|
5
5
|
Author: AbdyyEee
|
|
6
6
|
License: Copyright 2025 AbdyyEee
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyLibMS
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.8
|
|
4
4
|
Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and soon to be MSBF.
|
|
5
5
|
Author: AbdyyEee
|
|
6
6
|
License: Copyright 2025 AbdyyEee
|
|
@@ -66,5 +66,6 @@ lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml
|
|
|
66
66
|
lms/titleconfig/presets/Super Mario Odyssey.yaml
|
|
67
67
|
lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml
|
|
68
68
|
lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml
|
|
69
|
+
lms/titleconfig/presets/Tomodachi Life Living The Dream Demo.yaml
|
|
69
70
|
lms/titleconfig/presets/Tomodachi Life Living the Dream Demo.yaml
|
|
70
71
|
lms/titleconfig/presets/Tomodachi Life.yaml
|
|
@@ -32,7 +32,9 @@ def read_decoded_parameters(
|
|
|
32
32
|
value = read_field(reader, param)
|
|
33
33
|
except Exception as e:
|
|
34
34
|
raise LMS_TagReadingError(
|
|
35
|
-
f"An error occurred reading tag '[{definition.group_name}:{definition.tag_name}]',
|
|
35
|
+
f"""An error occurred reading tag '[{definition.group_name}:{definition.tag_name}]', at offset {param_offset}.
|
|
36
|
+
Parameter details: name='{param.name}', datatype='{param.datatype}'
|
|
37
|
+
"""
|
|
36
38
|
) from e
|
|
37
39
|
|
|
38
40
|
parameters[param.name] = value
|
|
@@ -35,6 +35,7 @@ def read_tag(
|
|
|
35
35
|
if tag_config is None:
|
|
36
36
|
return _read_encoded_tag(reader, group_id, tag_index, is_closing)
|
|
37
37
|
|
|
38
|
+
print(group_id, tag_index, start, reader.tell())
|
|
38
39
|
definition = tag_config.get_definition_by_indexes(group_id, tag_index)
|
|
39
40
|
|
|
40
41
|
# Tags not defined in the config are not considered fallback tags
|
|
@@ -38,9 +38,7 @@ class LMS_TagGroup:
|
|
|
38
38
|
)
|
|
39
39
|
for parameter in tag.parameter_definitions:
|
|
40
40
|
if parameter.datatype is LMS_DataType.LIST:
|
|
41
|
-
parameter.list_items = [
|
|
42
|
-
item for i in parameter.list_indexes for item in list_items[i]
|
|
43
|
-
]
|
|
41
|
+
parameter.list_items = [list_items[i] for i in parameter.list_indexes]
|
|
44
42
|
|
|
45
43
|
|
|
46
44
|
class LMS_TagDefinition:
|
|
@@ -12,6 +12,7 @@ def read_strings(reader: FileReader, four_byte_count: bool) -> list[str]:
|
|
|
12
12
|
|
|
13
13
|
for offset in reader.read_offset_array(count):
|
|
14
14
|
reader.seek(offset)
|
|
15
|
-
|
|
15
|
+
string = reader.read_encoded_string()
|
|
16
|
+
string_list.append(string)
|
|
16
17
|
|
|
17
18
|
return string_list
|
|
@@ -117,11 +117,14 @@ class TitleConfig:
|
|
|
117
117
|
config["name"], config["description"], definitions
|
|
118
118
|
)
|
|
119
119
|
|
|
120
|
-
tag_definitions
|
|
120
|
+
tag_definitions: dict[int, list[TagDefinition]] = {}
|
|
121
121
|
group_map = parsed_content[cls.TAG_KEY]["groups"]
|
|
122
122
|
|
|
123
123
|
for tag_def in parsed_content[cls.TAG_KEY]["tags"]:
|
|
124
|
-
|
|
124
|
+
definition = TagDefinition.from_dict(tag_def, group_map)
|
|
125
|
+
if definition.group_id not in tag_definitions:
|
|
126
|
+
tag_definitions[definition.group_id] = []
|
|
127
|
+
tag_definitions[definition.group_id].append(definition)
|
|
125
128
|
|
|
126
129
|
tag_config = TagConfig(group_map, tag_definitions)
|
|
127
130
|
|
|
@@ -169,11 +172,10 @@ class TitleConfig:
|
|
|
169
172
|
"group_id": group.group_id,
|
|
170
173
|
"tag_index": i,
|
|
171
174
|
"description": "",
|
|
172
|
-
"parameters": None if not tag_def.parameter_definitions else [],
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
if
|
|
176
|
-
|
|
177
|
+
if tag_def.parameter_definitions:
|
|
178
|
+
definition["parameters"] = []
|
|
177
179
|
|
|
178
180
|
for param_def in tag_def.parameter_definitions:
|
|
179
181
|
param_definition: dict[str, str | list] = {
|
|
@@ -9,7 +9,7 @@ from lms.titleconfig.definitions.value import ValueDefinition
|
|
|
9
9
|
class TagConfig:
|
|
10
10
|
"""Class that represents a tag structure definition."""
|
|
11
11
|
|
|
12
|
-
def __init__(self, group_map: dict[int, str], definitions: list[TagDefinition]):
|
|
12
|
+
def __init__(self, group_map: dict[int, str], definitions: dict[int, list[TagDefinition]]):
|
|
13
13
|
self._group_map = group_map
|
|
14
14
|
self._definitions = definitions
|
|
15
15
|
|
|
@@ -18,23 +18,23 @@ class TagConfig:
|
|
|
18
18
|
return self._group_map
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
|
-
def definitions(self) -> list[TagDefinition]:
|
|
21
|
+
def definitions(self) -> dict[int, list[TagDefinition]]:
|
|
22
22
|
return self._definitions
|
|
23
23
|
|
|
24
24
|
def get_definition_by_names(self, group_name: str, tag_name: str) -> TagDefinition:
|
|
25
|
-
|
|
25
|
+
group_id = None
|
|
26
26
|
for i, name in self.group_map.items():
|
|
27
27
|
if name == group_name:
|
|
28
|
-
|
|
28
|
+
group_id = i
|
|
29
29
|
break
|
|
30
30
|
|
|
31
|
-
if
|
|
31
|
+
if group_id is None:
|
|
32
32
|
raise KeyError(
|
|
33
33
|
f"Group name '{group_name}' was not found! Is the group defined?"
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
for tag_def in self.
|
|
37
|
-
if tag_def.group_id ==
|
|
36
|
+
for tag_def in self._definitions[group_id]:
|
|
37
|
+
if tag_def.group_id == group_id and tag_def.tag_name == tag_name:
|
|
38
38
|
return tag_def
|
|
39
39
|
|
|
40
40
|
raise KeyError(
|
|
@@ -47,11 +47,7 @@ class TagConfig:
|
|
|
47
47
|
if group_id not in self._group_map:
|
|
48
48
|
return None
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
if tag_def.group_id == group_id and tag_def.tag_index == tag_index:
|
|
52
|
-
return tag_def
|
|
53
|
-
|
|
54
|
-
return None
|
|
50
|
+
return self._definitions[group_id][tag_index]
|
|
55
51
|
|
|
56
52
|
|
|
57
53
|
@dataclass(frozen=True)
|