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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#!/usr/bin/env python3
# Startdate: 2024-03-08-6 15:28
# File: srb_lib.py
# Purpose: frontend for srb_lib
# History:
# Usage:
# Reference:
# blog posts 2024-03
# delsum from github
# bgconf.py
# WORKHERE: right now, this only just corrects any file. in the future, offer options like --profile 1 --set-money 3045 --give-plane all or --give-plane marcie
# or --take-plan marcie or --set-rank-level 1,general --set-rank-level 1,none --set-rank-level all,general
# or --give-weapon pumpkin --take-weapon bees
# or --give-balloons-level 10 --take-balloons-level 11
# make chart of level numbers, which ones have balloons
# or --reset-level 5 (which zeros out all info about completion of that level)
# --set-plane-health 1 (through 4)
# --set-plane-weapon 1 (through 4)
# --set-plane-stunt 1 (through 4)
# --set-profile-name "asdbdf"
import srb_lib, argparse, sys
from srb_lib import ferror, debuglev
HELP_WEAPONS = ""
for w in srb_lib.WEAPONS:
HELP_WEAPONS += str(w["id"]) + "," + w["name"] + ','
HELP_WEAPONS = HELP_WEAPONS.rstrip(",")
parser = argparse.ArgumentParser(description="Cli tool for manipulating savegame files for srb.exe",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=f"""LEVELS include {[i['name'] for i in srb_lib.LEVELS]+list(range(0,len(srb_lib.LEVELS)))}
WEAPONS include {HELP_WEAPONS}
NAME_CHARS include "{srb_lib.NAME_CHARS}"
""")
parser.add_argument("-V","--version",action="version",version="%(prog)s " + srb_lib.srb_lib_version)
parser.add_argument("-d","--debug",nargs='?',default=0,type=int,choices=range(0,11),help="Set debug level")
parser.add_argument("--profile",type=int,choices=range(1,4),help="Profile in user menu.")
parser.add_argument("--get-money",action="store_true",help="Print current money for profile.")
parser.add_argument("--set-money",type=int,help="Set money for profile.")
parser.add_argument("--get-weapon",action="store_true",help="Print currently equipped weapon for profile.")
# choices seems to be too strict here for the numbers. We can live with just the
#choices=[i for i in srb_lib.WEAPONS if i != "undefined"]+list(range(0,16))
#parser.add_argument("--set-weapon",choices=[i for i in srb_lib.WEAPONS if i != "undefined"],help="Print currently equipped weapon for profile.")
parser.add_argument("--set-weapon",help="Set currently equipped weapon for profile.")
parser.add_argument("--get-purchased-weapons",action="store_true",help="Print currently purchased weapon for profile.")
parser.add_argument("--add-purchased-weapons",action="append",help="For profile, add these purchased weapons. Can be used multiple times.")
parser.add_argument("--remove-purchased-weapons",action="append",help="For profile, add these purchased weapons. Can be used multiple times.")
parser.add_argument("--get-level",help="Print status for this level for profile.")
parser.add_argument("--get-name",action="store_true",help="Print name for profile.")
parser.add_argument("--set-name",help="Set name for profile.")
parser.add_argument("--get-profile-in-use",action="store_true",help="Print if profile is in use.")
parser.add_argument("--get-tutorial-completed",action="store_true",help="Print if profile has completed the tutorial.")
parser.add_argument("--set-tutorial-completed",choices=["True","False"],help="Set tutorial-completed for profile.")
parser.add_argument("--checksum",action=argparse.BooleanOptionalAction,default=True,help="Correct checksum. Default is to do this. It happens at the end of everything else.")
parser.add_argument("file",default="Profile 1.sav")
args = parser.parse_args()
debuglevel = 0
if args.debug:
debuglevel = args.debug
if debuglev(1,debuglevel):
ferror("debug level", debuglevel)
if debuglev(8,debuglevel):
ferror(args)
# common parameters
profile_id = args.profile
#print(f"profile_id={profile_id}")
# WORKHERE: new actions that need --profile must be added here.
if not profile_id and (args.get_money or args.set_money or args.get_weapon or args.set_weapon or args.get_level or args.get_name or args.set_name or args.get_profile_in_use or args.get_purchased_weapons or args.get_tutorial_completed or args.add_purchased_weapons or args.remove_purchased_weapons):
ferror("Warning: Cannot perform most actions without --profile. Not all tasks may run.")
else:
if args.get_money:
money = srb_lib.get_money(args.file, profile_id)
print(f"Profile {profile_id} has {money} money.")
if args.set_money:
if args.set_money > 0xFFFF:
ferror(f"Warning: Do not set money higher than 65535. While it can technically work, there's no need for that in-game anyways. Continuing...")
else:
data = srb_lib.set_money(args.file, profile_id, args.set_money)
srb_lib.write_file(args.file,0,data)
if args.get_weapon:
print(f"Profile {profile_id} has weapon {srb_lib.get_weapon(args.file, profile_id)}")
if args.set_weapon:
try:
args.set_weapon = int(args.set_weapon)
except:
pass
data = srb_lib.set_weapon(args.file, profile_id, args.set_weapon)
if type(data) == int and data == -1:
# error is printed in the function
pass
else:
srb_lib.write_file(args.file,0,data)
if args.get_level:
print(f"Profile {profile_id} has level {args.get_level} status {srb_lib.get_level_status(args.file,profile_id,args.get_level)}")
if args.get_name:
print(f"Profile {profile_id} has name {srb_lib.get_name(args.file,profile_id)}")
if args.set_name:
data, message = srb_lib.set_name(args.file, profile_id, args.set_name)
if (type(data) == int and data == -1) or message != "":
ferror(f"Failed to set profile {profile_id} name to {args.set_name} because {message}")
else:
srb_lib.write_file(args.file,0,data)
if args.get_profile_in_use:
print(f"Profile {profile_id} in use is {srb_lib.get_profile_in_use(args.file,profile_id)}")
if args.get_purchased_weapons:
print(f"Profile {profile_id} has weapons {srb_lib.get_purchased_weapons(args.file,profile_id)}")
if args.add_purchased_weapons:
data, message = srb_lib.set_purchased_weapons(args.file,profile_id,"add",args.add_purchased_weapons)
if (type(data) == int and data == -1) or message != "":
ferror(f"Failed to add purchased weapons {args.add_purchased_weapons} because {message}")
else:
srb_lib.write_file(args.file,0,data)
if args.remove_purchased_weapons:
data, message = srb_lib.set_purchased_weapons(args.file,profile_id,"remove",args.remove_purchased_weapons)
if (type(data) == int and data == -1) or message != "":
ferror(f"Failed to add purchased weapons {args.remove_purchased_weapons} because {message}")
else:
srb_lib.write_file(args.file,0,data)
if args.get_tutorial_completed:
print(f"Profile {profile_id} completed-tutorial is {srb_lib.get_tutorial_completed(args.file,profile_id)}")
if args.set_tutorial_completed:
thisbool = False if args.set_tutorial_completed == "False" else True
data, newstatus = srb_lib.set_tutorial_completed(args.file,profile_id,thisbool)
srb_lib.write_file(args.file,0,data)
if args.checksum:
f = args.file
#for f in args.file:
if debuglev(1,debuglevel):
ferror(f"Fixing checksum for file {f}")
srb_lib.correct_file(f,debuglevel)
|