Files

165 lines
4.5 KiB
Python

import io
import struct
from datetime import datetime
from pathlib import Path
from typing import BinaryIO, Optional, cast
import lzokay # pyright: ignore[reportMissingTypeStubs]
from .XRIO import XRReader, XRStream
from .XRObject import XRCreatureActor, XRFlag
class XRSave:
filepath: Path
player: XRCreatureActor
_factions = {
0: "Loner",
1: "Monster",
2: "Trader",
3: "Army",
4: "Sin",
5: "Bandit",
6: "Duty",
7: "Ecologist",
8: "Freedom",
9: "Mercenary",
10: "Army",
11: "Monolith",
12: "Sin",
13: "Loner",
14: "Zombified",
15: "Clear Sky",
16: "UNISG",
17: "Renegade",
18: "Loner",
19: "Bandit",
20: "Duty",
21: "Freedom",
22: "Clear Sky",
23: "Ecologist",
24: "Mercenary",
25: "Military",
26: "Monolith",
27: "Zombified",
28: "Sin",
29: "UNISG",
30: "Renegade",
31: "Participant",
}
_ranks = {
1999: "Novice",
3999: "Trainee",
6999: "Experienced",
9999: "Professional",
14999: "Veteran",
20999: "Expert",
27999: "Master",
"max": "Legend",
}
_reputation = {
-2000: "Terrible",
-1500: "Really Bad",
-1000: "Very Bad",
-500: "Bad",
499: "Netural",
999: "Good",
1499: "Very Good",
1999: "Really Good",
"max": "Excellent",
}
def __init__(self, filepath: Path):
self.filepath = filepath
self.fetchInfo()
with open(filepath, "rb") as file:
stream = self.readFile(file)
if stream:
self.readObject(stream)
def fetchInfo(self):
self.splitInfo()
self.time = self.filepath.stat().st_mtime
self.time_date = datetime.fromtimestamp(self.time)
self.time_fmt = self.time_date.strftime("%I:%M %m/%d/%Y")
def splitInfo(self):
save_clean = self.filepath.name.split(".scop", 1)[0]
save_split = save_clean.split(" - ", 1)
self.user = save_split[0]
if len(save_split) > 1:
save_end = save_split[1].split("_", 1)
if len(save_end) > 1:
self.save_fmt = f"{save_end[0]} (#{save_end[1]})".title()
else:
self.save_fmt = f"{save_end[0]}".title()
else:
self.save_fmt = "Unknown"
def readFile(self, file: BinaryIO) -> Optional[XRStream]:
size = self.filepath.stat().st_size
if size < 8:
return None
(start, version, source) = struct.unpack("@iii", file.read(12))
if (start == -1) and (version >= 6):
file.seek(12)
data = file.read(size - 12)
return XRStream(
cast(
bytes,
lzokay.decompress( # pyright: ignore[reportUnknownMemberType]
data, source
),
)
)
return None
def readObject(self, stream: XRStream):
chunk = stream.open_chunk(XRFlag.CHUNK_OBJECT)
if chunk:
chunk.seek(4, io.SEEK_CUR) # obj_count
count_spawn = chunk.u16()
spawn = XRReader(chunk.read(count_spawn))
actor = XRCreatureActor()
actor.read_spawn(spawn)
count_update = chunk.u16()
update = XRReader(chunk.read(count_update))
actor.read_update(update)
if actor:
self.player = actor
return None
def getFaction(self) -> str:
player = self.player
if player:
player_faction = player.community_index
for faction in self._factions:
if player_faction == faction:
return self._factions[faction]
return "Unknown"
def getRank(self) -> str:
player = self.player
if player:
player_rank = player.rank
for rank in self._ranks:
if isinstance(rank, int):
if player_rank <= rank:
return self._ranks[rank]
return self._ranks["max"]
def getReputation(self) -> str:
player = self.player
if player:
player_rep = player.reputation
for rep in self._reputation:
if isinstance(rep, int):
if player_rep <= rep:
return self._reputation[rep]
return self._reputation["max"]