mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2024-11-12 23:58:07 +01:00
Add controller config, multi lang achievements, DLC to generate_emu_config.
This commit is contained in:
parent
5ce4ac8429
commit
e0726f2e9d
3 changed files with 207 additions and 115 deletions
|
@ -53,125 +53,128 @@ def add_input_bindings(group, bindings, force_binding=None, keymap=keymap_digita
|
|||
bindings[action_name] = [binding]
|
||||
return bindings
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("format: {} xbox_controller_config.vdf".format(sys.argv[0]))
|
||||
exit(0)
|
||||
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
t = f.read().decode('utf-8')
|
||||
def generate_controller_config(controller_vdf, config_dir):
|
||||
d = vdf.loads(controller_vdf, mapper=vdf.VDFDict, merge_duplicate_keys=False)
|
||||
|
||||
d = vdf.loads(t, mapper=vdf.VDFDict, merge_duplicate_keys=False)
|
||||
controller_mappings = d["controller_mappings"]
|
||||
|
||||
controller_mappings = d["controller_mappings"]
|
||||
groups = controller_mappings.get_all_for("group")
|
||||
groups_byid = {}
|
||||
for g in groups:
|
||||
groups_byid[g["id"]] = g
|
||||
|
||||
groups = controller_mappings.get_all_for("group")
|
||||
groups_byid = {}
|
||||
for g in groups:
|
||||
groups_byid[g["id"]] = g
|
||||
actions = controller_mappings.get_all_for("actions")
|
||||
action_list = []
|
||||
for a in actions:
|
||||
for k in a:
|
||||
action_list.append(k)
|
||||
|
||||
actions = controller_mappings.get_all_for("actions")
|
||||
action_list = []
|
||||
for a in actions:
|
||||
for k in a:
|
||||
action_list.append(k)
|
||||
|
||||
presets = controller_mappings.get_all_for("preset")
|
||||
all_bindings = {}
|
||||
for p in presets:
|
||||
name = p["name"]
|
||||
if name not in action_list:
|
||||
continue
|
||||
group_bindings = p["group_source_bindings"]
|
||||
bindings = {}
|
||||
for number in group_bindings:
|
||||
s = group_bindings[number].split()
|
||||
if s[1] != "active":
|
||||
presets = controller_mappings.get_all_for("preset")
|
||||
all_bindings = {}
|
||||
for p in presets:
|
||||
name = p["name"]
|
||||
if name not in action_list:
|
||||
continue
|
||||
group_bindings = p["group_source_bindings"]
|
||||
bindings = {}
|
||||
for number in group_bindings:
|
||||
s = group_bindings[number].split()
|
||||
if s[1] != "active":
|
||||
continue
|
||||
|
||||
#print(s)
|
||||
if s[0] in ["switch", "button_diamond", "dpad"]:
|
||||
group = groups_byid[number]
|
||||
#print(group)
|
||||
bindings = add_input_bindings(group, bindings)
|
||||
#print(s)
|
||||
if s[0] in ["switch", "button_diamond", "dpad"]:
|
||||
group = groups_byid[number]
|
||||
#print(group)
|
||||
bindings = add_input_bindings(group, bindings)
|
||||
|
||||
if s[0] in ["left_trigger", "right_trigger"]:
|
||||
group = groups_byid[number]
|
||||
if group["mode"] == "trigger":
|
||||
for g in group:
|
||||
if g == "gameactions":
|
||||
#print(group)
|
||||
action_name = group["gameactions"][name]
|
||||
if s[0] == "left_trigger":
|
||||
binding = "LTRIGGER"
|
||||
else:
|
||||
binding = "RTRIGGER"
|
||||
if action_name in bindings:
|
||||
if binding not in bindings[action_name] and (binding + "=trigger") not in bindings[action_name]:
|
||||
bindings[action_name].insert(0, binding)
|
||||
else:
|
||||
bindings[action_name] = [binding + "=trigger"]
|
||||
if g == "inputs":
|
||||
if s[0] == "left_trigger":
|
||||
binding = "DLTRIGGER"
|
||||
else:
|
||||
binding = "DRTRIGGER"
|
||||
bindings = add_input_bindings(group, bindings, binding)
|
||||
if s[0] in ["left_trigger", "right_trigger"]:
|
||||
group = groups_byid[number]
|
||||
if group["mode"] == "trigger":
|
||||
for g in group:
|
||||
if g == "gameactions":
|
||||
#print(group)
|
||||
action_name = group["gameactions"][name]
|
||||
if s[0] == "left_trigger":
|
||||
binding = "LTRIGGER"
|
||||
else:
|
||||
binding = "RTRIGGER"
|
||||
if action_name in bindings:
|
||||
if binding not in bindings[action_name] and (binding + "=trigger") not in bindings[action_name]:
|
||||
bindings[action_name].insert(0, binding)
|
||||
else:
|
||||
bindings[action_name] = [binding + "=trigger"]
|
||||
if g == "inputs":
|
||||
if s[0] == "left_trigger":
|
||||
binding = "DLTRIGGER"
|
||||
else:
|
||||
binding = "DRTRIGGER"
|
||||
bindings = add_input_bindings(group, bindings, binding)
|
||||
|
||||
else:
|
||||
print("unhandled trigger mode", group["mode"])
|
||||
if s[0] in ["joystick", "right_joystick", "dpad"]:
|
||||
group = groups_byid[number]
|
||||
if group["mode"] == "joystick_move":
|
||||
for g in group:
|
||||
if g == "gameactions":
|
||||
#print(group)
|
||||
action_name = group["gameactions"][name]
|
||||
if s[0] == "joystick":
|
||||
binding = "LJOY"
|
||||
elif s[0] == "right_joystick":
|
||||
binding = "RJOY"
|
||||
elif s[0] == "dpad":
|
||||
binding = "DPAD"
|
||||
else:
|
||||
print("could not handle", s[0])
|
||||
if action_name in bindings:
|
||||
if binding not in bindings[action_name] and (binding + "=joystick_move") not in bindings[action_name]:
|
||||
bindings[action_name].insert(0, binding)
|
||||
else:
|
||||
bindings[action_name] = [binding + "=joystick_move"]
|
||||
if g == "inputs":
|
||||
if s[0] == "joystick":
|
||||
binding = "LSTICK"
|
||||
else:
|
||||
binding = "RSTICK"
|
||||
bindings = add_input_bindings(group, bindings, binding)
|
||||
|
||||
elif group["mode"] == "dpad":
|
||||
if s[0] == "joystick":
|
||||
binding_map = {"dpad_north":"DLJOYUP", "dpad_south": "DLJOYDOWN", "dpad_west": "DLJOYLEFT", "dpad_east": "DLJOYRIGHT", "click": "LSTICK"}
|
||||
bindings = add_input_bindings(group, bindings, keymap=binding_map)
|
||||
elif s[0] == "right_joystick":
|
||||
binding_map = {"dpad_north":"DRJOYUP", "dpad_south": "DRJOYDOWN", "dpad_west": "DRJOYLEFT", "dpad_east": "DRJOYRIGHT", "click": "RSTICK"}
|
||||
bindings = add_input_bindings(group, bindings, keymap=binding_map)
|
||||
else:
|
||||
if s[0] != "dpad":
|
||||
print("no pad", s[0])
|
||||
else:
|
||||
print("unhandled joy mode", group["mode"])
|
||||
print("unhandled trigger mode", group["mode"])
|
||||
if s[0] in ["joystick", "right_joystick", "dpad"]:
|
||||
group = groups_byid[number]
|
||||
if group["mode"] == "joystick_move":
|
||||
for g in group:
|
||||
if g == "gameactions":
|
||||
#print(group)
|
||||
action_name = group["gameactions"][name]
|
||||
if s[0] == "joystick":
|
||||
binding = "LJOY"
|
||||
elif s[0] == "right_joystick":
|
||||
binding = "RJOY"
|
||||
elif s[0] == "dpad":
|
||||
binding = "DPAD"
|
||||
else:
|
||||
print("could not handle", s[0])
|
||||
if action_name in bindings:
|
||||
if binding not in bindings[action_name] and (binding + "=joystick_move") not in bindings[action_name]:
|
||||
bindings[action_name].insert(0, binding)
|
||||
else:
|
||||
bindings[action_name] = [binding + "=joystick_move"]
|
||||
if g == "inputs":
|
||||
if s[0] == "joystick":
|
||||
binding = "LSTICK"
|
||||
else:
|
||||
binding = "RSTICK"
|
||||
bindings = add_input_bindings(group, bindings, binding)
|
||||
|
||||
all_bindings[name] = bindings
|
||||
elif group["mode"] == "dpad":
|
||||
if s[0] == "joystick":
|
||||
binding_map = {"dpad_north":"DLJOYUP", "dpad_south": "DLJOYDOWN", "dpad_west": "DLJOYLEFT", "dpad_east": "DLJOYRIGHT", "click": "LSTICK"}
|
||||
bindings = add_input_bindings(group, bindings, keymap=binding_map)
|
||||
elif s[0] == "right_joystick":
|
||||
binding_map = {"dpad_north":"DRJOYUP", "dpad_south": "DRJOYDOWN", "dpad_west": "DRJOYLEFT", "dpad_east": "DRJOYRIGHT", "click": "RSTICK"}
|
||||
bindings = add_input_bindings(group, bindings, keymap=binding_map)
|
||||
else:
|
||||
if s[0] != "dpad":
|
||||
print("no pad", s[0])
|
||||
else:
|
||||
print("unhandled joy mode", group["mode"])
|
||||
|
||||
all_bindings[name] = bindings
|
||||
|
||||
#print(controller_mappings["preset"][(0, "group_source_bindings")])
|
||||
|
||||
#print(all_bindings)
|
||||
|
||||
if not os.path.exists(config_dir):
|
||||
os.makedirs(config_dir)
|
||||
|
||||
for k in all_bindings:
|
||||
with open(os.path.join(config_dir, k + '.txt'), 'w') as f:
|
||||
for b in all_bindings[k]:
|
||||
f.write(b + "=" + ','.join(all_bindings[k][b]) + "\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print("format: {} xbox_controller_config.vdf".format(sys.argv[0]))
|
||||
exit(0)
|
||||
|
||||
#print(controller_mappings["preset"][(0, "group_source_bindings")])
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
t = f.read().decode('utf-8')
|
||||
|
||||
#print(all_bindings)
|
||||
|
||||
config_directory = sys.argv[1] + "_config/steam_settings" + "/controller/"
|
||||
if not os.path.exists(config_directory):
|
||||
os.makedirs(config_directory)
|
||||
|
||||
for k in all_bindings:
|
||||
with open(config_directory + k + '.txt', 'w') as f:
|
||||
for b in all_bindings[k]:
|
||||
f.write(b + "=" + ','.join(all_bindings[k][b]) + "\n")
|
||||
generate_controller_config(t, os.path.join(sys.argv[1] + "_config/steam_settings", "controller"))
|
||||
|
|
|
@ -3,9 +3,10 @@ USERNAME = ""
|
|||
PASSWORD = ""
|
||||
|
||||
#steam ids with public profiles that own a lot of games
|
||||
TOP_OWNER_IDS = [76561198028121353, 76561198001237877, 76561198355625888, 76561198001678750, 76561198237402290]
|
||||
TOP_OWNER_IDS = [76561198028121353, 76561198001237877, 76561198355625888, 76561198001678750, 76561198237402290, 76561197979911851, 76561198152618007, 76561197969050296, 76561198213148949, 76561198037867621, 76561198108581917]
|
||||
|
||||
from stats_schema_achievement_gen import achievements_gen
|
||||
from controller_config_generator import parse_controller_vdf
|
||||
from steam.client import SteamClient
|
||||
from steam.client.cdn import CDNClient
|
||||
from steam.enums import common
|
||||
|
@ -15,6 +16,7 @@ from steam.core.msg import MsgProto
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import urllib.request
|
||||
|
||||
prompt_for_unavailable = True
|
||||
|
||||
|
@ -35,6 +37,7 @@ if (len(USERNAME) == 0 or len(PASSWORD) == 0):
|
|||
client.cli_login()
|
||||
else:
|
||||
result = client.login(USERNAME, password=PASSWORD)
|
||||
auth_code, two_factor_code = None, None
|
||||
while result in (EResult.AccountLogonDenied, EResult.InvalidLoginAuthCode,
|
||||
EResult.AccountLoginDeniedNeedTwoFactor, EResult.TwoFactorCodeMismatch,
|
||||
EResult.TryAnotherCM, EResult.ServiceUnavailable,
|
||||
|
@ -92,6 +95,65 @@ def generate_achievement_stats(client, game_id, output_directory, backup_directo
|
|||
else:
|
||||
print("no schema", out)
|
||||
|
||||
def get_ugc_info(client, published_file_id):
|
||||
return client.send_um_and_wait('PublishedFile.GetDetails#1', {
|
||||
'publishedfileids': [published_file_id],
|
||||
'includetags': False,
|
||||
'includeadditionalpreviews': False,
|
||||
'includechildren': False,
|
||||
'includekvtags': False,
|
||||
'includevotes': False,
|
||||
'short_description': True,
|
||||
'includeforsaledata': False,
|
||||
'includemetadata': False,
|
||||
'language': 0
|
||||
})
|
||||
|
||||
def download_published_file(client, published_file_id, backup_directory):
|
||||
ugc_info = get_ugc_info(client, published_file_id)
|
||||
|
||||
if (ugc_info is None):
|
||||
print("failed getting published file", published_file_id)
|
||||
return None
|
||||
|
||||
file_details = ugc_info.body.publishedfiledetails[0]
|
||||
if (file_details.result != EResult.OK):
|
||||
print("failed getting published file", published_file_id, file_details.result)
|
||||
return None
|
||||
|
||||
if not os.path.exists(backup_directory):
|
||||
os.makedirs(backup_directory)
|
||||
|
||||
with open(os.path.join(backup_directory, "info.txt"), "w") as f:
|
||||
f.write(str(ugc_info.body))
|
||||
|
||||
with urllib.request.urlopen(file_details.file_url) as response:
|
||||
data = response.read()
|
||||
with open(os.path.join(backup_directory, file_details.filename.replace("/", "_").replace("\\", "_")), "wb") as f:
|
||||
f.write(data)
|
||||
return data
|
||||
return None
|
||||
|
||||
def get_dlc(raw_infos):
|
||||
try:
|
||||
try:
|
||||
dlc_list = set(map(lambda a: int(a), raw_infos["extended"]["listofdlc"].split(",")))
|
||||
except:
|
||||
dlc_list = set()
|
||||
depot_app_list = set()
|
||||
if "depots" in raw_infos:
|
||||
depots = raw_infos["depots"]
|
||||
for dep in depots:
|
||||
depot_info = depots[dep]
|
||||
if "dlcappid" in depot_info:
|
||||
dlc_list.add(int(depot_info["dlcappid"]))
|
||||
if "depotfromapp" in depot_info:
|
||||
depot_app_list.add(int(depot_info["depotfromapp"]))
|
||||
return (dlc_list, depot_app_list)
|
||||
except:
|
||||
print("could not get dlc infos, are there any dlcs ?")
|
||||
return (set(), set())
|
||||
|
||||
for appid in appids:
|
||||
backup_dir = os.path.join("backup","{}".format(appid))
|
||||
out_dir = os.path.join("{}".format( "{}_output".format(appid)), "steam_settings")
|
||||
|
@ -123,6 +185,40 @@ for appid in appids:
|
|||
with open(os.path.join(out_dir, "build_id.txt"), 'w') as f:
|
||||
f.write(str(buildid))
|
||||
|
||||
dlc_config_list = []
|
||||
dlc_list, depot_app_list = get_dlc(game_info)
|
||||
if (len(dlc_list) > 0):
|
||||
dlc_raw = client.get_product_info(apps=dlc_list)["apps"]
|
||||
for dlc in dlc_raw:
|
||||
try:
|
||||
dlc_config_list.append((dlc, dlc_raw[dlc]["common"]["name"]))
|
||||
except:
|
||||
dlc_config_list.append((dlc, None))
|
||||
|
||||
with open(os.path.join(out_dir, "DLC.txt"), 'w') as f:
|
||||
for x in dlc_config_list:
|
||||
if (x[1] is not None):
|
||||
f.write("{}={}\n".format(x[0], x[1]))
|
||||
|
||||
config_generated = False
|
||||
if "config" in game_info:
|
||||
if "steamcontrollerconfigdetails" in game_info["config"]:
|
||||
controller_details = game_info["config"]["steamcontrollerconfigdetails"]
|
||||
for id in controller_details:
|
||||
details = controller_details[id]
|
||||
controller_type = ""
|
||||
enabled_branches = ""
|
||||
if "controller_type" in details:
|
||||
controller_type = details["controller_type"]
|
||||
if "enabled_branches" in details:
|
||||
enabled_branches = details["enabled_branches"]
|
||||
print(id, controller_type)
|
||||
out_vdf = download_published_file(client, int(id), os.path.join(backup_dir, controller_type + str(id)))
|
||||
if out_vdf is not None and not config_generated:
|
||||
if (controller_type in ["controller_xbox360", "controller_xboxone"] and (("default" in enabled_branches) or ("public" in enabled_branches))):
|
||||
parse_controller_vdf.generate_controller_config(out_vdf.decode('utf-8'), os.path.join(out_dir, "controller"))
|
||||
config_generated = True
|
||||
|
||||
game_info_backup = json.dumps(game_info, indent=4)
|
||||
with open(os.path.join(backup_dir, "product_info.json"), "w") as f:
|
||||
f.write(game_info_backup)
|
||||
|
|
|
@ -4,8 +4,6 @@ import os
|
|||
import json
|
||||
|
||||
|
||||
language = 'english'
|
||||
|
||||
STAT_TYPE_INT = '1'
|
||||
STAT_TYPE_FLOAT = '2'
|
||||
STAT_TYPE_AVGRATE = '3'
|
||||
|
@ -35,11 +33,6 @@ def generate_stats_achievements(schema, config_directory):
|
|||
x = 'description'
|
||||
if x == 'Hidden':
|
||||
x = 'hidden'
|
||||
if type(value) is dict:
|
||||
if language in value:
|
||||
value = value[language]
|
||||
else:
|
||||
value = ''
|
||||
out[x] = value
|
||||
out['name'] = ach['name']
|
||||
if 'progress' in ach:
|
||||
|
|
Loading…
Reference in a new issue