1- from collections .abc import Mapping , Sequence
2- from datetime import datetime
3- from functools import cached_property
4- from io import BytesIO
5- from typing import Any
6- from pathlib import Path
71import json
82import math
93import os
104import shutil
115import struct
126import zlib
7+ from collections .abc import Mapping , Sequence
8+ from datetime import datetime
9+ from functools import cached_property
10+ from io import BytesIO
11+ from pathlib import Path
12+ from typing import Any
1313
14- import mobase
1514from PyQt6 .QtCore import QDir , QFileInfo
1615
16+ import mobase
17+
1718from ..basic_features import BasicLocalSavegames
18- from ..basic_features .basic_save_game_info import (BasicGameSaveGame ,BasicGameSaveGameInfo )
19+ from ..basic_features .basic_save_game_info import (
20+ BasicGameSaveGame ,
21+ BasicGameSaveGameInfo ,
22+ )
1923from ..basic_game import BasicGame
2024
2125
@@ -26,14 +30,17 @@ def json_get_me(value: Any, path: Sequence[str | int], /, default: Any) -> Any:
2630 value = value [part ]
2731 return value
2832
33+
2934class CassetteBeastsModDataChecker (mobase .ModDataChecker ):
3035 def __init__ (self , organizer : mobase .IOrganizer ):
3136 super ().__init__ ()
3237 self .organizer : mobase .IOrganizer = organizer
3338
34- def dataLooksValid (self , filetree : mobase .IFileTree ) -> mobase .ModDataChecker .CheckReturn :
39+ def dataLooksValid (
40+ self , filetree : mobase .IFileTree
41+ ) -> mobase .ModDataChecker .CheckReturn :
3542 for e in filetree :
36- if e .suffix ().casefold () == "pck" :
43+ if e .suffix ().casefold () == "pck" :
3744 return mobase .ModDataChecker .VALID
3845 return mobase .ModDataChecker .FIXABLE
3946
@@ -45,9 +52,16 @@ def fix(self, filetree: mobase.IFileTree) -> mobase.IFileTree | None:
4552 if mod_name == "" :
4653 mod_name = branch .name ()
4754 mod_path = os .path .join (self .organizer .modsPath (), mod_name )
48- if not filetree .createOrphanTree ("OrphanTree" ) and os .path .exists (mod_path ) and branch .suffix ().casefold () == "pck" :
55+ if (
56+ not filetree .createOrphanTree ("OrphanTree" )
57+ and os .path .exists (mod_path )
58+ and branch .suffix ().casefold () == "pck"
59+ ):
4960 os .makedirs (os .path .join (mod_path , GameDataPath ), exist_ok = True )
50- shutil .move (os .path .join (mod_path , branch .name ()), os .path .join (mod_path , GameDataPath , branch .name ()))
61+ shutil .move (
62+ os .path .join (mod_path , branch .name ()),
63+ os .path .join (mod_path , GameDataPath , branch .name ()),
64+ )
5165 treefixed = 1
5266 else :
5367 if isinstance (branch , mobase .IFileTree ):
@@ -56,15 +70,17 @@ def fix(self, filetree: mobase.IFileTree) -> mobase.IFileTree | None:
5670 filetree .move (e , GameDataPath , mobase .IFileTree .MERGE )
5771 treefixed = 1
5872 elif branch .suffix ().casefold () == "pck" :
59- filetree .move (branch , GameDataPath , mobase .IFileTree .MERGE )
60- treefixed = 1
73+ filetree .move (branch , GameDataPath , mobase .IFileTree .MERGE )
74+ treefixed = 1
6175 if treefixed == 0 :
6276 return None
6377 return filetree
6478
79+
6580class CassetteBlock :
6681 compressed_size : int = 0
67- data : bytes = b''
82+ data : bytes = b""
83+
6884
6985class CassetteBeastsSaveGame (BasicGameSaveGame ):
7086 def __init__ (self , filepath : Path ):
@@ -81,7 +97,7 @@ def __init__(self, filepath: Path):
8197 try :
8298 info = bytearray ()
8399 data = bytes ()
84- with open (filepath , 'rb' ) as infile :
100+ with open (filepath , "rb" ) as infile :
85101 infile .read (4 )
86102
87103 blocksize , raw_size = struct .unpack ("III" , infile .read (12 ))
@@ -106,7 +122,7 @@ def __init__(self, filepath: Path):
106122 save_data = json .load (BytesIO (info ))
107123 except (OSError , struct .error , ValueError ) as err :
108124 s = str (err )
109- self .errorMessage = (' {0}: {1}' if s else ' {0}' ).format (
125+ self .errorMessage = (" {0}: {1}" if s else " {0}" ).format (
110126 err .__class__ .__name__ , s
111127 )
112128 return
@@ -120,13 +136,14 @@ def __init__(self, filepath: Path):
120136 except OSError :
121137 pass
122138 else :
123- self .lastsave = "{0:d}-{1:02d}-{2:02d} at {3:02d}:{4:02d}:{5:02d}" .format (
124- dt .year , dt .month , dt .day ,
125- dt .hour , dt .minute , dt .second
139+ self .lastsave = (
140+ "{0:d}-{1:02d}-{2:02d} at {3:02d}:{4:02d}:{5:02d}" .format (
141+ dt .year , dt .month , dt .day , dt .hour , dt .minute , dt .second
142+ )
126143 )
127144 x = json_get_me (save_data , ["play_time" ], None )
128145 if type (x ) in (int , float ):
129- a = [ 0 , 0 , 0 , int (x * 10 ) ]
146+ a = [0 , 0 , 0 , int (x * 10 )]
130147 a [2 :4 ] = divmod (a [3 ], 10 )
131148 a [1 :3 ] = divmod (a [2 ], 60 )
132149 a [0 :2 ] = divmod (a [1 ], 60 )
@@ -147,19 +164,20 @@ def getLastSaved(self) -> str:
147164 def getPlayTime (self ) -> str :
148165 return self .elapsed
149166
167+
150168def getMetadata (p : Path , save : mobase .ISaveGame ) -> Mapping [str , str ] | None :
151169 err = getattr (save , "errorMessage" , "" )
152170 if err :
153171 return {"Error loading file:" : err }
154172
155173 # If this is our concrete save-game class, the type checker knows the methods.
156174 if isinstance (save , BasicGameSaveGame ):
157- return
175+ return
158176 {
159177 "Character" : save .getName (),
160178 "Last Saved" : save .getLastSaved (),
161179 "Play Time" : save .getPlayTime (),
162- "Cheated" : save .getCheated ()
180+ "Cheated" : save .getCheated (),
163181 }
164182 else :
165183 return None
@@ -182,10 +200,8 @@ def init(self, organizer: mobase.IOrganizer) -> bool:
182200 super ().init (organizer )
183201 self .dataChecker = CassetteBeastsModDataChecker (organizer )
184202 self ._register_feature (self .dataChecker )
185- self ._register_feature (BasicLocalSavegames (QDir (self .GameSavesDirectory ))) # type: ignore
186- self ._register_feature (
187- BasicGameSaveGameInfo (None , getMetadata )
188- )
203+ self ._register_feature (BasicLocalSavegames (QDir (self .GameSavesDirectory ))) # type: ignore
204+ self ._register_feature (BasicGameSaveGameInfo (None , getMetadata ))
189205 return True
190206
191207 def executables (self ):
@@ -218,15 +234,23 @@ def executableForcedLoads(self) -> list[mobase.ExecutableForcedLoadSetting]:
218234 except AttributeError :
219235 efls = []
220236 libs : set [str ] = set ()
221- tree : mobase .IFileTree | mobase .FileTreeEntry | None = self ._organizer .virtualFileTree ()
237+ tree : mobase .IFileTree | mobase .FileTreeEntry | None = (
238+ self ._organizer .virtualFileTree ()
239+ )
222240 if type (tree ) is not mobase .IFileTree :
223241 return efls
224242 for e in tree :
225243 relpath = e .pathFrom (tree )
226244 if relpath and e .hasSuffix ("dll" ) and relpath not in self ._base_dlls :
227245 libs .add (relpath )
228246 exes = self .executables ()
229- efls = efls + [mobase .ExecutableForcedLoadSetting (exe .binary ().fileName (), lib ).withEnabled (True ) for lib in libs for exe in exes ]
247+ efls = efls + [
248+ mobase .ExecutableForcedLoadSetting (
249+ exe .binary ().fileName (), lib
250+ ).withEnabled (True )
251+ for lib in libs
252+ for exe in exes
253+ ]
230254 return efls
231255
232256 def iniFiles (self ):
0 commit comments