koro 2.0.1__py3-none-any.whl → 2.0.3rc1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- koro/py.typed +0 -0
- koro/slot/bin.py +0 -1
- koro/slot/save.py +15 -15
- koro/slot/xml.py +1 -1
- koro/stage/model.py +0 -1
- koro/stage/part.py +1 -2
- {koro-2.0.1.dist-info → koro-2.0.3rc1.dist-info}/METADATA +3 -2
- koro-2.0.3rc1.dist-info/RECORD +15 -0
- {koro-2.0.1.dist-info → koro-2.0.3rc1.dist-info}/WHEEL +1 -1
- koro-2.0.1.dist-info/RECORD +0 -14
- {koro-2.0.1.dist-info → koro-2.0.3rc1.dist-info}/LICENSE +0 -0
- {koro-2.0.1.dist-info → koro-2.0.3rc1.dist-info}/top_level.txt +0 -0
koro/py.typed
ADDED
File without changes
|
koro/slot/bin.py
CHANGED
koro/slot/save.py
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
+
from collections.abc import Mapping, Sequence
|
1
2
|
from enum import Enum, unique
|
2
3
|
from io import BytesIO
|
3
4
|
from operator import index as ix
|
4
5
|
from os.path import basename, dirname, join
|
5
|
-
from typing import TYPE_CHECKING, Annotated, Any, Literal, SupportsIndex
|
6
|
-
from collections.abc import Mapping, Sequence
|
6
|
+
from typing import TYPE_CHECKING, Annotated, Any, Final, Literal, SupportsIndex
|
7
7
|
|
8
8
|
from ..stage import Stage
|
9
|
-
|
10
9
|
from . import Slot
|
11
10
|
from .xml import XmlSlot
|
12
11
|
|
@@ -18,6 +17,8 @@ else:
|
|
18
17
|
|
19
18
|
__all__ = ["EditorPage", "get_slots", "SaveSlot"]
|
20
19
|
|
20
|
+
_SIZE_LIMIT: Final[int] = 156864
|
21
|
+
|
21
22
|
|
22
23
|
@unique
|
23
24
|
class EditorPage(Enum):
|
@@ -30,7 +31,7 @@ class SaveSlot(Slot):
|
|
30
31
|
__match_args__ = ("path", "page", "index")
|
31
32
|
__slots__ = ("_offset", "_path")
|
32
33
|
|
33
|
-
_offset: Literal[8,
|
34
|
+
_offset: Literal[8, 156872, 313736, 470600]
|
34
35
|
_path: str | bytes
|
35
36
|
|
36
37
|
def __init__(
|
@@ -45,8 +46,8 @@ class SaveSlot(Slot):
|
|
45
46
|
],
|
46
47
|
) -> None:
|
47
48
|
index = ix(index) - 1
|
48
|
-
if index in range(
|
49
|
-
self._offset = 8 +
|
49
|
+
if index in range(20):
|
50
|
+
self._offset = 8 + _SIZE_LIMIT * (index & 3) # type: ignore[assignment]
|
50
51
|
self._path = join(path, f"ed{(index >> 2) + 5 * page.value:02}.dat") # type: ignore[arg-type]
|
51
52
|
else:
|
52
53
|
raise ValueError("index must be between 1 and 20")
|
@@ -72,7 +73,7 @@ class SaveSlot(Slot):
|
|
72
73
|
def index(
|
73
74
|
self,
|
74
75
|
) -> Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]:
|
75
|
-
return (int(basename(self._path)[2:4]) % 5 >> 2 | self._offset //
|
76
|
+
return (int(basename(self._path)[2:4]) % 5 >> 2 | self._offset // _SIZE_LIMIT) + 1 # type: ignore[return-value]
|
76
77
|
|
77
78
|
def load(self) -> Stage | None:
|
78
79
|
try:
|
@@ -82,11 +83,8 @@ class SaveSlot(Slot):
|
|
82
83
|
block: bytearray = bytearray()
|
83
84
|
while True:
|
84
85
|
block.clear()
|
85
|
-
block.extend(f.read1())
|
86
|
-
|
87
|
-
if len(b.getbuffer()) + len(block) > 156864:
|
88
|
-
del block[156864 - len(b.getbuffer()) :]
|
89
|
-
if block[-1]:
|
86
|
+
block.extend(f.read1(_SIZE_LIMIT - len(b.getbuffer())))
|
87
|
+
if block and block[-1]:
|
90
88
|
b.write(block)
|
91
89
|
else:
|
92
90
|
while block:
|
@@ -116,11 +114,13 @@ class SaveSlot(Slot):
|
|
116
114
|
|
117
115
|
def save(self, data: Stage | None) -> None:
|
118
116
|
binary: bytes = b"" if data is None else XmlSlot.serialize(data)
|
119
|
-
if len(binary) >
|
117
|
+
if len(binary) > _SIZE_LIMIT:
|
120
118
|
raise ValueError("serialized stage data is too large to save")
|
121
119
|
try:
|
122
120
|
with open(self._path, "xb") as f:
|
123
|
-
f.write(
|
121
|
+
f.write(
|
122
|
+
bytes(638976)
|
123
|
+
) # Weird. Would expect this to be 627464 (8 + 4 * (_SIZE_LIMIT))
|
124
124
|
if data is None:
|
125
125
|
return
|
126
126
|
except FileExistsError:
|
@@ -128,7 +128,7 @@ class SaveSlot(Slot):
|
|
128
128
|
with open(self._path, "r+b") as f:
|
129
129
|
f.seek(self._offset)
|
130
130
|
f.write(binary)
|
131
|
-
f.write(bytes(
|
131
|
+
f.write(bytes(_SIZE_LIMIT - len(binary)))
|
132
132
|
|
133
133
|
|
134
134
|
def get_slots(save: StrOrBytesPath, /) -> Mapping[EditorPage, Sequence[SaveSlot]]:
|
koro/slot/xml.py
CHANGED
@@ -12,7 +12,6 @@ from ..stage.part import (
|
|
12
12
|
BasePart,
|
13
13
|
BlinkingTile,
|
14
14
|
Bumper,
|
15
|
-
TextBox,
|
16
15
|
Cannon,
|
17
16
|
ConveyorBelt,
|
18
17
|
DashTunnel,
|
@@ -41,6 +40,7 @@ from ..stage.part import (
|
|
41
40
|
Speed,
|
42
41
|
Spring,
|
43
42
|
Start,
|
43
|
+
TextBox,
|
44
44
|
Thorn,
|
45
45
|
TimedDevice,
|
46
46
|
ToyTrain,
|
koro/stage/model.py
CHANGED
koro/stage/part.py
CHANGED
@@ -2,14 +2,13 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
4
|
from collections.abc import Iterable, MutableSequence
|
5
|
-
from enum import Enum,
|
5
|
+
from enum import Enum, Flag, unique
|
6
6
|
from operator import index
|
7
7
|
from sys import maxsize
|
8
8
|
from typing import Any, Final, Iterator, Literal, Self, SupportsIndex, overload
|
9
9
|
|
10
10
|
from .model import DecorationModel, DeviceModel, PartModel
|
11
11
|
|
12
|
-
|
13
12
|
__all__ = [
|
14
13
|
"Ant",
|
15
14
|
"BasePart",
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: koro
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.3rc1
|
4
4
|
Summary: Tools for manipulating levels made in Marble Saga: Kororinpa
|
5
5
|
Home-page: https://github.com/DigitalDetective47/koro
|
6
6
|
Author: DigitalDetective47
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Programming Language :: Python :: 3 :: Only
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
17
18
|
Classifier: Topic :: File Formats
|
18
19
|
Classifier: Topic :: Games/Entertainment
|
19
20
|
Classifier: Typing :: Typed
|
@@ -0,0 +1,15 @@
|
|
1
|
+
koro/__init__.py,sha256=5_P8Q_L1Jo-bqMmzAK9tPKkmaSffbuid16voHwj8vys,192
|
2
|
+
koro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
koro/slot/__init__.py,sha256=YJ3FjOF4o1Vo8joMpLTw27-Dwaoxq5YfQSER-ymJjFE,398
|
4
|
+
koro/slot/bin.py,sha256=Q0vKE5hTzGIGER-kpZnRykA3oAkXaK6uSAibS5Y1gBM,6527
|
5
|
+
koro/slot/file.py,sha256=QxBIXzFqzT6mzVZ5bq8xeR8vWfcNFpjHzsEEEqSzlz4,1656
|
6
|
+
koro/slot/save.py,sha256=vgkwqwbB46FK7jS6aMXrtPwksqOZsBsGRhBCyhdPRAg,4514
|
7
|
+
koro/slot/xml.py,sha256=TXogt9AlR93_jG63j2fv3AeEbkB4D8xp3CE1OI_2OjA,42147
|
8
|
+
koro/stage/__init__.py,sha256=xdMGSuI4fNDVSSHnuSwMyzFVyRxpcsSDxCl0EQWGJJM,2448
|
9
|
+
koro/stage/model.py,sha256=ZxmuKceendBqtVgmkJUYwbVzb7lGGhSoeCumgx3zwuQ,8428
|
10
|
+
koro/stage/part.py,sha256=QE7BFltmhm2pTQKjMrH0bxMj5h5Z8neOxxQEMd6RDGw,46885
|
11
|
+
koro-2.0.3rc1.dist-info/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
12
|
+
koro-2.0.3rc1.dist-info/METADATA,sha256=o2UW06QyTHlCHMJkyD2QqPVh43KCwhCvCbsSOMjRjC4,4408
|
13
|
+
koro-2.0.3rc1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
14
|
+
koro-2.0.3rc1.dist-info/top_level.txt,sha256=Msq6ssMwv56hnBQqwaTdJJkxM7x7BZ-3JfQbkepQAEY,5
|
15
|
+
koro-2.0.3rc1.dist-info/RECORD,,
|
koro-2.0.1.dist-info/RECORD
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
koro/__init__.py,sha256=5_P8Q_L1Jo-bqMmzAK9tPKkmaSffbuid16voHwj8vys,192
|
2
|
-
koro/slot/__init__.py,sha256=YJ3FjOF4o1Vo8joMpLTw27-Dwaoxq5YfQSER-ymJjFE,398
|
3
|
-
koro/slot/bin.py,sha256=KaspkI3MZAoUTkVD8cSNP8sjn_ZI9U7qLt885zEK5C0,6528
|
4
|
-
koro/slot/file.py,sha256=QxBIXzFqzT6mzVZ5bq8xeR8vWfcNFpjHzsEEEqSzlz4,1656
|
5
|
-
koro/slot/save.py,sha256=qsY3_HGud0lFYWm3bOPWkq_LMEwj7DT_Z5pwVsnFfCA,4487
|
6
|
-
koro/slot/xml.py,sha256=evjIx-egPC43HqMCtBmmrjggyZ3xjERquqhaSIFQz0I,42147
|
7
|
-
koro/stage/__init__.py,sha256=xdMGSuI4fNDVSSHnuSwMyzFVyRxpcsSDxCl0EQWGJJM,2448
|
8
|
-
koro/stage/model.py,sha256=JNN6xT9o-47oTETu0_bWZpVBPOm2xkRgItKnREExbHo,8429
|
9
|
-
koro/stage/part.py,sha256=zo2uxQ6QccG3Ja7sos6IUiwnjvXJDFoWRcTbUVXeQ5E,46886
|
10
|
-
koro-2.0.1.dist-info/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
11
|
-
koro-2.0.1.dist-info/METADATA,sha256=0hi9LZ1ReMnZQHdGe7MJXqYG5l-1UvF_-dAPKz79mGc,4354
|
12
|
-
koro-2.0.1.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
13
|
-
koro-2.0.1.dist-info/top_level.txt,sha256=Msq6ssMwv56hnBQqwaTdJJkxM7x7BZ-3JfQbkepQAEY,5
|
14
|
-
koro-2.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|