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.
Files changed (73) hide show
  1. {pylibms-3.3.5 → pylibms-3.3.8}/PKG-INFO +1 -1
  2. {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/PKG-INFO +1 -1
  3. {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/SOURCES.txt +1 -0
  4. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/io/param_io.py +3 -1
  5. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/io/tag_io.py +1 -0
  6. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/tag.py +1 -3
  7. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/string.py +2 -1
  8. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/config.py +7 -5
  9. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/tags.py +8 -12
  10. pylibms-3.3.8/lms/titleconfig/presets/Tomodachi Life Living the Dream Demo.yaml +3369 -0
  11. {pylibms-3.3.5 → pylibms-3.3.8}/pyproject.toml +1 -1
  12. pylibms-3.3.5/lms/titleconfig/presets/Tomodachi Life Living the Dream Demo.yaml +0 -13054
  13. {pylibms-3.3.5 → pylibms-3.3.8}/LICENSE +0 -0
  14. {pylibms-3.3.5 → pylibms-3.3.8}/MANIFEST.in +0 -0
  15. {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/dependency_links.txt +0 -0
  16. {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/requires.txt +0 -0
  17. {pylibms-3.3.5 → pylibms-3.3.8}/PyLibMS.egg-info/top_level.txt +0 -0
  18. {pylibms-3.3.5 → pylibms-3.3.8}/README.md +0 -0
  19. {pylibms-3.3.5 → pylibms-3.3.8}/lms/__init__.py +0 -0
  20. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/__init__.py +0 -0
  21. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_datatype.py +0 -0
  22. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_exceptions.py +0 -0
  23. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/lms_fileinfo.py +0 -0
  24. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/fileinfo.py +0 -0
  25. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/hashtable.py +0 -0
  26. {pylibms-3.3.5 → pylibms-3.3.8}/lms/common/stream/section.py +0 -0
  27. {pylibms-3.3.5 → pylibms-3.3.8}/lms/fileio/encoding.py +0 -0
  28. {pylibms-3.3.5 → pylibms-3.3.8}/lms/fileio/io.py +0 -0
  29. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/__init__.py +0 -0
  30. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/__init__.py +0 -0
  31. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/__init__.py +0 -0
  32. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/io.py +0 -0
  33. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/field/lms_field.py +0 -0
  34. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/definitions/lms_messagetext.py +0 -0
  35. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbt.py +0 -0
  36. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbtentry.py +0 -0
  37. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/msbtio.py +0 -0
  38. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/__init__.py +0 -0
  39. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/atr1.py +0 -0
  40. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/nli1.py +0 -0
  41. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/tsy1.py +0 -0
  42. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/section/txt2.py +0 -0
  43. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/__init__.py +0 -0
  44. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/lms_tag.py +0 -0
  45. {pylibms-3.3.5 → pylibms-3.3.8}/lms/message/tag/lms_tagexceptions.py +0 -0
  46. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/__init__.py +0 -0
  47. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/__init__.py +0 -0
  48. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/attribute.py +0 -0
  49. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/color.py +0 -0
  50. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/definitions/style.py +0 -0
  51. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/msbp.py +0 -0
  52. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/msbpread.py +0 -0
  53. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/ali2.py +0 -0
  54. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/ati2.py +0 -0
  55. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/clr1.py +0 -0
  56. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/syl3.py +0 -0
  57. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tag2.py +0 -0
  58. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tgg2.py +0 -0
  59. {pylibms-3.3.5 → pylibms-3.3.8}/lms/project/section/tgp2.py +0 -0
  60. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/__init__.py +0 -0
  61. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/__init__.py +0 -0
  62. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/attribute.py +0 -0
  63. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/definitions/value.py +0 -0
  64. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Badge Arcade.yaml +0 -0
  65. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Brain Age Concentration Training.yaml +0 -0
  66. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Kirby Planet Robobot.yaml +0 -0
  67. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario 3D Land.yaml +0 -0
  68. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml +0 -0
  69. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Super Mario Odyssey.yaml +0 -0
  70. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml +0 -0
  71. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
  72. {pylibms-3.3.5 → pylibms-3.3.8}/lms/titleconfig/presets/Tomodachi Life.yaml +0 -0
  73. {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.5
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.5
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}]', parameter '{param.name}' at offset {param_offset}"
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
- string_list.append(reader.read_encoded_string())
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
- tag_definitions.append(TagDefinition.from_dict(tag_def, group_map))
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 definition["parameters"] is None:
176
- continue
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
- group_index = None
25
+ group_id = None
26
26
  for i, name in self.group_map.items():
27
27
  if name == group_name:
28
- group_index = i
28
+ group_id = i
29
29
  break
30
30
 
31
- if group_index is None:
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.definitions:
37
- if tag_def.group_id == group_index and tag_def.tag_name == tag_name:
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
- for tag_def in self.definitions:
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)