-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathachievement_reconstructor.py
More file actions
113 lines (87 loc) · 3.36 KB
/
achievement_reconstructor.py
File metadata and controls
113 lines (87 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from pathlib import Path
import argparse, sys, re
from ruamel.yaml import YAML
from lib.dumpers import BinaryDumper, YamlDumper
yaml = YAML()
yaml.encoding = "utf-8"
yaml.preserve_quotes = True
def main() -> None:
argparser = argparse.ArgumentParser(prog = sys.argv[0])
group = argparser.add_mutually_exclusive_group(required = True)
group.add_argument(
"-d", "--deconstruct",
action = "store",
metavar= "PATH",
type = Path,
help = "parse .bin file containing achievement schema and output into readable YAML format"
)
group.add_argument(
"-r", "--reconstruct",
action = "store",
metavar = "PATH",
type = Path,
help = "parse YAML file containing achievement schema and output into encoded .bin format"
)
argparser.add_argument(
"-o", "--output",
action = "store",
required = False,
metavar = "PATH",
default = ".",
type = Path,
help = "destination folder (defaults to working directory)"
)
args = argparser.parse_args(sys.argv[1:])
in_file : Path
data : dict[str, object]
if (in_file := args.deconstruct):
if not in_file.exists():
print("[ERROR]\tPath to schema does not exist.");
sys.exit(1)
if not re.match(r"UserGameStatsSchema_\d+.bin", in_file.name):
print("[ERROR]\tFile name does not conform to schema name.")
sys.exit(1)
dumper = BinaryDumper(in_file)
try:
data = dumper.dump()
except Exception as e :
print(f"[ERROR]\t{ e.args[0] }")
sys.exit(1)
out_file : Path
filename : str = in_file.name.rstrip(".bin") + ".yaml"
if args.output.is_dir():
out_file = args.output / filename
else:
print("[WARN]\tFile path specified; Ignoring supplied filename.")
out_file = args.output.with_name(filename)
with open(out_file, "w", encoding = "utf-8") as fl:
yaml.dump(data, fl) # type: ignore
print(f"[INFO]\tSuccessfully extracted game achievement schema to { out_file.relative_to(Path("."), walk_up = True) }.")
elif (in_file := args.reconstruct):
if not in_file.exists():
print("[ERROR]\tPath to schema does not exist.");
sys.exit(1)
if not re.match(r"UserGameStatsSchema_\d+.yaml", in_file.name):
print("[ERROR]\tFile name does not conform to schema name.")
sys.exit(1)
try:
with open(in_file, "r", encoding = "utf-8") as fl:
data = yaml.load(fl)
except:
raise
out_file : Path
filename : str = in_file.name.rstrip(".yaml") + ".bin"
if args.output.is_dir():
out_file = args.output / filename
else:
print("[WARN]\tFile path specified; Ignoring supplied filename.")
out_file = args.output.with_name(filename)
dumper = YamlDumper(out_file)
try:
dumper.dump(data)
except Exception as e:
print(f"[ERROR]\t{ e.args[0] }")
sys.exit(1)
print(f"[INFO]\tSuccessfully encoded game achievement schema to { out_file.relative_to(Path("."), walk_up = True) }.")
if __name__ == "__main__":
main()