PyLibMS 2.1.2__tar.gz → 2.1.4__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-2.1.2 → pylibms-2.1.4}/LMS/Common/LMS_DataType.py +9 -4
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/Field/LMS_Field.py +2 -4
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/LMS_MessageText.py +28 -21
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/MSBT.py +1 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/MSBTStream.py +1 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Section/TXT2.py +3 -3
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/LMS_Tag.py +2 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/Stream.py +3 -3
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/System_Definitions.py +14 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Config.py +6 -15
- {pylibms-2.1.2 → pylibms-2.1.4}/PKG-INFO +1 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/PyLibMS.egg-info/PKG-INFO +1 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/pyproject.toml +1 -1
- {pylibms-2.1.2 → pylibms-2.1.4}/LICENSE +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/LMS_Exceptions.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/LMS_FileInfo.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/Stream/FileInfo.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/Stream/Hashtable.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/Stream/Section.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Common/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/FileIO/Encoding.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/FileIO/Stream.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/Field/LMS_FieldMap.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/Field/Stream.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/Field/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Definitions/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/MSBTEntry.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Section/ATR1.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Section/TSY1.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Section/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/LMS_TagExceptions.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/Tag_Formats.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/Tag/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Message/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Definitions/Attribute.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Definitions/Color.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Definitions/Style.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Definitions/Tag.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Definitions/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/MSBP.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/MSBPRead.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/ALI2.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/ATI2.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/CLR1.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/SYL3.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/String.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/TAG2.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/TGG2.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/Section/TGP2.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/Project/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Definitions/Attributes.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Definitions/Tags.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Definitions/Value.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Definitions/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Badge Arcade.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Brain Age Concentration Training.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Kirby Planet Robobot.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Super Mario 3D Land.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Tomodachi Life.yaml +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/LMS/__init__.py +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/MANIFEST.in +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/PyLibMS.egg-info/SOURCES.txt +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/PyLibMS.egg-info/dependency_links.txt +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/PyLibMS.egg-info/requires.txt +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/PyLibMS.egg-info/top_level.txt +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/README.md +0 -0
- {pylibms-2.1.2 → pylibms-2.1.4}/setup.cfg +0 -0
|
@@ -3,7 +3,7 @@ from typing import Literal, Type
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class LMS_DataType(Enum):
|
|
6
|
-
|
|
6
|
+
"""Enum that represents a datatype for a value entry in a MSBT/MSBP file."""
|
|
7
7
|
UINT8 = 0
|
|
8
8
|
UINT16 = 1
|
|
9
9
|
UINT32 = 2
|
|
@@ -15,12 +15,17 @@ class LMS_DataType(Enum):
|
|
|
15
15
|
FLOAT32 = 6
|
|
16
16
|
|
|
17
17
|
# Unknown 16 bit type (value of 6) has yet to be documented
|
|
18
|
+
# Might be some sort of 2 byte integer, float, or may be an array.
|
|
19
|
+
# We wont ever know cause no game (yet that has been found) has utilized this type
|
|
20
|
+
# Thanks Nintendo.
|
|
18
21
|
...
|
|
19
22
|
|
|
20
23
|
STRING = 8
|
|
21
24
|
LIST = 9
|
|
22
|
-
|
|
23
|
-
#
|
|
25
|
+
|
|
26
|
+
# These types are not offical, but allow for abstraction from the value of the actual type
|
|
27
|
+
# As an example, BOOL can be utilized for UInt8 values that act like a bool
|
|
28
|
+
# Byte types can also be used for when the type/value is unknown or if there is extra data in the tag.
|
|
24
29
|
BOOL = "bool"
|
|
25
30
|
BYTE = "byte"
|
|
26
31
|
|
|
@@ -59,7 +64,7 @@ class LMS_DataType(Enum):
|
|
|
59
64
|
|
|
60
65
|
@property
|
|
61
66
|
def stream_size(self) -> Literal[1, 2, 4]:
|
|
62
|
-
"""The size the datatype takes up in a
|
|
67
|
+
"""The size the datatype takes up in a stream."""
|
|
63
68
|
return {
|
|
64
69
|
LMS_DataType.UINT8: 1,
|
|
65
70
|
LMS_DataType.UINT16: 2,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from dataclasses import dataclass, field
|
|
2
1
|
|
|
3
2
|
from LMS.Common.LMS_DataType import LMS_DataType
|
|
4
3
|
from LMS.TitleConfig.Definitions.Value import ValueDefinition
|
|
@@ -17,14 +16,13 @@ class LMS_Field:
|
|
|
17
16
|
self._value = value
|
|
18
17
|
|
|
19
18
|
def __repr__(self):
|
|
20
|
-
|
|
21
|
-
if typename == "LIST":
|
|
19
|
+
if self.datatype is LMS_DataType.LIST:
|
|
22
20
|
if len(self.list_items) > 6:
|
|
23
21
|
preview = self.list_items[:3] + ["..."]
|
|
24
22
|
else:
|
|
25
23
|
preview = self.list_items
|
|
26
24
|
return f"LMS_Field(value={self._value}, options={preview})"
|
|
27
|
-
return f"LMS_Field(value={self._value
|
|
25
|
+
return f"LMS_Field(value={self._value}, type={self.datatype.name})"
|
|
28
26
|
|
|
29
27
|
@property
|
|
30
28
|
def name(self) -> str:
|
|
@@ -2,7 +2,9 @@ import re
|
|
|
2
2
|
from typing import overload
|
|
3
3
|
|
|
4
4
|
from LMS.Message.Definitions.Field.LMS_Field import LMS_Field
|
|
5
|
+
from LMS.Message.Definitions.Field.LMS_FieldMap import LMS_FieldMap
|
|
5
6
|
from LMS.Message.Tag.LMS_Tag import LMS_DecodedTag, LMS_EncodedTag, LMS_TagBase
|
|
7
|
+
from LMS.Message.Tag.System_Definitions import get_system_tag
|
|
6
8
|
from LMS.Message.Tag.Tag_Formats import (DECODED_FORMAT, ENCODED_FORMAT,
|
|
7
9
|
TAG_FORMAT)
|
|
8
10
|
from LMS.TitleConfig.Config import TagConfig
|
|
@@ -44,27 +46,29 @@ class LMS_MessageText:
|
|
|
44
46
|
|
|
45
47
|
@overload
|
|
46
48
|
def append_encoded_tag(
|
|
47
|
-
self, group: int, tag: int, parameters:
|
|
49
|
+
self, group: int, tag: int, *parameters: tuple[str]
|
|
48
50
|
) -> None: ...
|
|
49
51
|
|
|
50
52
|
@overload
|
|
51
53
|
def append_encoded_tag(
|
|
52
|
-
self, group: str, tag: str, parameters:
|
|
54
|
+
self, group: str, tag: str, *parameters: tuple[str]
|
|
53
55
|
) -> None: ...
|
|
54
56
|
|
|
55
57
|
def append_encoded_tag(
|
|
56
|
-
self, group: int | str, tag: int | str, parameters:
|
|
58
|
+
self, group: int | str, tag: int | str, *parameters: tuple[str]
|
|
57
59
|
):
|
|
58
60
|
"""Appends an encoded tag to the current message.
|
|
59
61
|
|
|
60
62
|
:param group: the group name or index.
|
|
61
63
|
:param tag: the group tag or index:
|
|
62
64
|
:param parameters: a list of hex strings.
|
|
65
|
+
|
|
66
|
+
message.append_encoded_tag(1, 2, "01", "00", "00", "CD")
|
|
63
67
|
"""
|
|
64
68
|
if isinstance(group, int) and isinstance(tag, int):
|
|
65
69
|
self._parts.append(LMS_EncodedTag(group, tag, parameters))
|
|
66
70
|
return
|
|
67
|
-
|
|
71
|
+
|
|
68
72
|
definition = self._config.get_definition_by_names(group, tag)
|
|
69
73
|
self._parts.append(
|
|
70
74
|
LMS_EncodedTag(
|
|
@@ -72,35 +76,38 @@ class LMS_MessageText:
|
|
|
72
76
|
)
|
|
73
77
|
)
|
|
74
78
|
|
|
75
|
-
def append_decoded_tag(
|
|
76
|
-
self,
|
|
77
|
-
group_name: str,
|
|
78
|
-
tag_name: str,
|
|
79
|
-
parameters: dict[str, int | float | str | bytes | bool] | None = None,
|
|
80
|
-
) -> None:
|
|
79
|
+
def append_decoded_tag(self, group_name: str, tag_name: str, **parameters: LMS_FieldMap) -> None:
|
|
81
80
|
"""Appends an decoded tag to the current message.
|
|
82
81
|
|
|
83
82
|
:param group_name: the group name.
|
|
84
83
|
:param tag_name: the tag name.:
|
|
85
|
-
:param parameters:
|
|
84
|
+
:param parameters: keyword arguments of parameters mapped to their value.
|
|
85
|
+
|
|
86
|
+
## Usage
|
|
87
|
+
```
|
|
88
|
+
message.append_decoded_tag("Mii", "Nickname", buffer=1, type="Voice", conversion="None")
|
|
89
|
+
```
|
|
86
90
|
"""
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
if group_name == "System":
|
|
93
|
+
definition = get_system_tag(tag_name)
|
|
94
|
+
else:
|
|
95
|
+
definition = self._config.get_definition_by_names(group_name, tag_name)
|
|
89
96
|
|
|
90
|
-
# The provided
|
|
97
|
+
# The provided kwargs must match the structure defined in the config in order for value conversion to work
|
|
91
98
|
converted_params = {
|
|
92
99
|
param_def.name: LMS_Field(parameters[param_def.name], param_def)
|
|
93
100
|
for param_def in definition.parameters
|
|
94
101
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)
|
|
102
|
+
|
|
103
|
+
tag = LMS_DecodedTag(
|
|
104
|
+
definition.group_index,
|
|
105
|
+
definition.tag_index,
|
|
106
|
+
group_name,
|
|
107
|
+
tag_name,
|
|
108
|
+
converted_params,
|
|
103
109
|
)
|
|
110
|
+
self._parts.append(tag)
|
|
104
111
|
|
|
105
112
|
def append_tag_string(self, string: str) -> None:
|
|
106
113
|
"""Appends a tag to the current message given a string.
|
|
@@ -59,7 +59,7 @@ def read_msbt(
|
|
|
59
59
|
file.size_per_attribute = size_per_attribute
|
|
60
60
|
file.attr_string_table = string_table
|
|
61
61
|
case "TXT2":
|
|
62
|
-
messages = read_txt2(reader,
|
|
62
|
+
messages = read_txt2(reader, tag_config)
|
|
63
63
|
case "TSY1":
|
|
64
64
|
style_indexes = read_tsy1(reader, len(labels))
|
|
65
65
|
case _:
|
|
@@ -6,9 +6,9 @@ from LMS.Message.Tag.Stream import read_tag, write_tag
|
|
|
6
6
|
from LMS.TitleConfig.Definitions.Tags import TagConfig
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def read_txt2(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
def read_txt2(reader: FileReader, config: TagConfig) -> list[LMS_MessageText]:
|
|
10
|
+
encoding = reader.encoding
|
|
11
|
+
|
|
12
12
|
text_list = []
|
|
13
13
|
count = reader.read_uint32()
|
|
14
14
|
|
|
@@ -10,6 +10,7 @@ from LMS.TitleConfig.Definitions.Tags import TagConfig
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class LMS_TagBase(ABC):
|
|
13
|
+
"""Base class for encoded and decoded tags."""
|
|
13
14
|
def __init__(
|
|
14
15
|
self,
|
|
15
16
|
group_index: int,
|
|
@@ -71,7 +72,7 @@ class LMS_EncodedTag(LMS_TagBase):
|
|
|
71
72
|
self,
|
|
72
73
|
group_index: int,
|
|
73
74
|
tag_index: int,
|
|
74
|
-
parameters: list[str] = None,
|
|
75
|
+
parameters: list[str] | tuple[str] = None,
|
|
75
76
|
group_name: str = None,
|
|
76
77
|
tag_name: str = None,
|
|
77
78
|
):
|
|
@@ -6,7 +6,7 @@ from LMS.Message.Definitions.Field.Stream import read_field, write_field
|
|
|
6
6
|
from LMS.Message.Tag.LMS_Tag import LMS_DecodedTag, LMS_EncodedTag, LMS_TagBase
|
|
7
7
|
from LMS.Message.Tag.LMS_TagExceptions import (LMS_TagReadingError,
|
|
8
8
|
LMS_TagWritingException)
|
|
9
|
-
from LMS.Message.Tag.System_Definitions import
|
|
9
|
+
from LMS.Message.Tag.System_Definitions import get_system_tag
|
|
10
10
|
from LMS.TitleConfig.Definitions.Tags import TagConfig, TagDefinition
|
|
11
11
|
|
|
12
12
|
|
|
@@ -29,12 +29,12 @@ def read_tag(
|
|
|
29
29
|
return LMS_EncodedTag(group_index, tag_index, parameters)
|
|
30
30
|
|
|
31
31
|
if group_index == 0:
|
|
32
|
-
definition =
|
|
32
|
+
definition = get_system_tag(tag_index)
|
|
33
33
|
else:
|
|
34
34
|
definition = config.get_definition_by_indexes(group_index, tag_index)
|
|
35
35
|
|
|
36
36
|
# If the parameters were omitted from the definition but the tag still has defined parameters, add the decoded
|
|
37
|
-
# names but read the tag as encoded. This is to account for encoded tags that group
|
|
37
|
+
# names but read the tag as encoded. This is to account for encoded tags that have group and tag names defined.
|
|
38
38
|
# i.e [Group:Tag 00-00-00-FF]
|
|
39
39
|
if definition.parameters is None and param_size > 0:
|
|
40
40
|
parameters = _read_encoded_parameters(reader, param_size)
|
|
@@ -2,6 +2,11 @@ from LMS.Common.LMS_DataType import LMS_DataType
|
|
|
2
2
|
from LMS.TitleConfig.Definitions.Tags import TagDefinition
|
|
3
3
|
from LMS.TitleConfig.Definitions.Value import ValueDefinition
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
def get_system_tag(group: int | str) -> TagDefinition:
|
|
7
|
+
return SYSTEM_INT_MAP[group] if isinstance(group, int) else SYSTEM_STR_MAP[group]
|
|
8
|
+
|
|
9
|
+
|
|
5
10
|
RUBY_TAG = TagDefinition(
|
|
6
11
|
group_name="System",
|
|
7
12
|
group_index=0,
|
|
@@ -74,10 +79,18 @@ PAGEBREAK_TAG = TagDefinition(
|
|
|
74
79
|
description="Displays text in the same label on different pages.",
|
|
75
80
|
)
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
SYSTEM_INT_MAP = {
|
|
78
83
|
0: RUBY_TAG,
|
|
79
84
|
1: FONT_TAG,
|
|
80
85
|
2: SIZE_TAG,
|
|
81
86
|
3: COLOR_TAG,
|
|
82
87
|
4: PAGEBREAK_TAG,
|
|
83
88
|
}
|
|
89
|
+
|
|
90
|
+
SYSTEM_STR_MAP = {
|
|
91
|
+
"Ruby": RUBY_TAG,
|
|
92
|
+
"Font": FONT_TAG,
|
|
93
|
+
"Size": SIZE_TAG,
|
|
94
|
+
"Color": COLOR_TAG,
|
|
95
|
+
"Pagebreak": PAGEBREAK_TAG,
|
|
96
|
+
}
|
|
@@ -23,9 +23,7 @@ class TitleConfig:
|
|
|
23
23
|
if file.name.endswith(".yaml")
|
|
24
24
|
]
|
|
25
25
|
|
|
26
|
-
def __init__(
|
|
27
|
-
self, attribute_configs: dict[str, AttributeConfig], tag_config: TagConfig
|
|
28
|
-
):
|
|
26
|
+
def __init__(self, attribute_configs: dict[str, AttributeConfig], tag_config: TagConfig):
|
|
29
27
|
self._attribute_configs = attribute_configs
|
|
30
28
|
self._tag_config = tag_config
|
|
31
29
|
|
|
@@ -61,21 +59,16 @@ class TitleConfig:
|
|
|
61
59
|
"""Loads the config of a specified game.
|
|
62
60
|
|
|
63
61
|
:param content: the config content, as a string or loaded as a dictionary."""
|
|
62
|
+
parsed_content = content
|
|
63
|
+
|
|
64
64
|
if isinstance(content, str):
|
|
65
65
|
parsed_content = yaml.safe_load(content)
|
|
66
|
-
else:
|
|
67
|
-
parsed_content = content
|
|
68
66
|
|
|
69
67
|
# Load the attribute definitions
|
|
70
68
|
attribute_configs = {}
|
|
71
69
|
for config in parsed_content[ATTR_KEY]:
|
|
72
|
-
definitions = [
|
|
73
|
-
|
|
74
|
-
for value_def in config["definitions"]
|
|
75
|
-
]
|
|
76
|
-
attribute_configs[config["name"]] = AttributeConfig(
|
|
77
|
-
config["name"], config["description"], definitions
|
|
78
|
-
)
|
|
70
|
+
definitions = [ValueDefinition.from_dict(value_def) for value_def in config["definitions"]]
|
|
71
|
+
attribute_configs[config["name"]] = AttributeConfig(config["name"], config["description"], definitions)
|
|
79
72
|
|
|
80
73
|
# Load the tag definitions
|
|
81
74
|
tag_definitions = []
|
|
@@ -107,9 +100,7 @@ class TitleConfig:
|
|
|
107
100
|
config = {}
|
|
108
101
|
|
|
109
102
|
config[TAG_KEY] = {
|
|
110
|
-
"groups": {
|
|
111
|
-
i: group.name for i, group in enumerate(project.tag_groups, start=1)
|
|
112
|
-
},
|
|
103
|
+
"groups": {i: group.name for i, group in enumerate(project.tag_groups, start=1)},
|
|
113
104
|
"tags": [],
|
|
114
105
|
}
|
|
115
106
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyLibMS"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.4"
|
|
8
8
|
requires-python = ">=3.12"
|
|
9
9
|
description = "Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and MSBF."
|
|
10
10
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pylibms-2.1.2 → pylibms-2.1.4}/LMS/TitleConfig/Presets/Brain Age Concentration Training.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|