Exemple #1
0
def get_client_users():
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "SOFTWARE\Valve\Steam", 0,
                         winreg.KEY_QUERY_VALUE)
    path, t = winreg.QueryValueEx(key, "SteamPath")
    users = {}

    path += "/config/loginusers.vdf"

    with open(path, "r", encoding="utf-8") as file:
        users = vdf.load(file)

    winreg.CloseKey(key)
    users = users["users"]

    rewrite = False
    for key, val in users.items():
        if (users[key]["RememberPassword"] == 0):
            users.pop(key, None)
            continue
        if ("AccountID" not in val):
            users[key]["AccountID"] = str(Sid.SteamID(key).id)
            rewrite = True

    if (rewrite):
        print("重寫 loginusers.")
        with open(path, "w", encoding="utf-8") as file:
            vdf.dump({"users": users}, file)
    return (users)
def main():
    parser = argparse.ArgumentParser(
        description=
        'Creates an update script for GoD-Tony\'s sourcemod plugin updater.')
    parser.add_argument(
        "--sm_path",
        type=Path,
        help=
        "The path to the root sourcemod folder that you bundle with your plugin"
    )
    parser.add_argument("--version",
                        type=str,
                        help="The current version of the plugin")
    parser.add_argument("--mod_path",
                        type=Path,
                        help="The path to the mod root folder",
                        nargs="?")
    parser.add_argument(
        "--notes",
        type=str,
        help="Notes to add to the update scirpt, usually a brief changelog",
        nargs="+")
    parser.add_argument("--output", type=Path, help="Output file")
    args = parser.parse_args()
    sm_path = args.sm_path
    script = god_tony_update_script(Path(args.sm_path), args.mod_path,
                                    list(args.notes), str(args.version))
    with open(str(args.output), "w") as fp:
        vdf.dump(script.build_vdf(), fp, pretty=True)
Exemple #3
0
def set_download_throttle(rate):
    close_steam()

    path = f"{all_steam_directories[0]}\\config\\config.vdf"
    config_vdf = vdf.load(open(path), mapper=vdf.VDFDict)  # Load VDF file
    old_value = config_vdf['InstallConfigStore']['Software']['Valve']['steam'][
        'DownloadThrottleKbps']

    if int(old_value) == rate:
        print(
            f"Your download rate was not changed because it was already set to"
            f" {'unlimited' if old_value == '0' else f'{old_value} Kbps'}.")
        return

    # Delete old value and add new value
    del config_vdf['InstallConfigStore']['Software']['Valve']['steam'][
        'DownloadThrottleKbps']
    config_vdf['InstallConfigStore']['Software']['Valve']['steam'].update(
        {'DownloadThrottleKbps': rate})
    # Backup and then output to file
    Tools.backup_file(path)
    vdf.dump(config_vdf, open(path, "w"), pretty=True)

    print(
        f"Your download rate was change from {'unlimited' if old_value == '0' else f'{old_value} Kbps'} to"
        f" {'unlimited' if rate == 0 else f'{rate} Kbps'}.")
Exemple #4
0
def fix_launch_option(app_id, wm_name, wm_name_alt=''):
    """Add execution of fix-wm-class.sh file with wm_name of game as argument."""
    if not wm_name_alt:
        wm_name_alt = wm_name
    for conf_file in localconfig_paths:
        loaded = vdf.load(open(conf_file))

        steam = loaded['UserLocalConfigStore']['Software']['Valve']['Steam']

        if 'Apps' in steam.keys():
            apps = steam['Apps']
        else:
            apps = steam['apps']

        if app_id in apps.keys():
            app = apps[app_id]
            if 'LaunchOptions' not in app.keys():
                app['LaunchOptions'] = ''
            app['LaunchOptions'] = sub('&\\s/.*fix-wm-class\\.sh.*?;', '', app['LaunchOptions'])
            script = str(WM_CLASS_FIXER_SCRIPT)
            if wm_name_alt != wm_name:
                app['LaunchOptions'] += '& %s "%s" "%s";' % (script, wm_name, wm_name_alt)
            else:
                app['LaunchOptions'] += '& %s "%s";' % (script, wm_name)
        vdf.dump(loaded, open(conf_file, 'w'), pretty=True)
Exemple #5
0
    def restore_config(src, dst):
        """Restore the backup. if dst exists, rename it. The new method."""
        try:
            with open(src, encoding='UTF-8') as backup_file:
                backedup_categories = json.loads(
                    backup_file.read(),
                    object_pairs_hook=collections.OrderedDict)

            with open(dst, encoding='UTF-8') as valves_file:
                content = vdf.loads(valves_file.read(),
                                    mapper=collections.OrderedDict)
                target_categories = content["UserRoamingConfigStore"][
                    "Software"]["Valve"]["Steam"]["Apps"]

                content["UserRoamingConfigStore"]["Software"]["Valve"][
                    "Steam"]["Apps"] = BackupAndRestore.__insert_categories__(
                        target_categories, backedup_categories)

            new_name = dst + " " + str(datetime.datetime.now().strftime(
                "%Y-%m-%d %H;%M;%S %f")) + ".bak"
            os.rename(dst, new_name)
            with open(dst, "w", encoding='UTF-8') as output_file:
                vdf.dump(content, output_file, pretty=True)

        except UnicodeDecodeError:
            raise ParseException("Can't open source file to restore")
        except (FileExistsError, IOError):
            raise ParseException("Can't open target file to restore")
def main():
    steamapps = check_args()
    print('Scanning manifests')
    for manifest in glob(join(steamapps, '*.acf')):
        with open(manifest, 'r') as manifile:
            vdf = load(manifile, mapper=VDFDict)
        changed = False

        # Disable autoupdate
        if vdf[0, 'AppState'][0, 'AutoUpdateBehavior'] != '0':
            vdf[0, 'AppState'][0, 'AutoUpdateBehavior'] = '0'
            print('Disabled', vdf[0, 'AppState'][0, 'name'])
            changed = True
        state_flag = int(vdf[0, 'AppState'][0, 'StateFlags'])

        # If it's in ready state make sure state is 4
        # Sometimes it goes to 6 for some reason
        # See https://github.com/lutris/lutris/blob/master/docs/steam.rst
        if state_flag != 4 and state_flag & 4:
            vdf[0, 'AppState'][0, 'StateFlags'] = '4'
            print('Marking as updated', vdf[0, 'AppState'][0, 'name'])
            changed = True
        if changed:
            with open(manifest, 'w') as manifile:
                dump(vdf, manifile, pretty=True)
    print('Done')
def achievements_po2vdf(vdff, langs):
    english = load_achievements().items()
    dat = {}
    for lang in langs:
        trans = dict((pe.msgid, pe.msgstr) for pe in polib.pofile(os.path.join(ROOT, "lang", lang, "achievements.po")))
        dat[steam_languages[lang]] = {"Tokens":dict((k, trans[v]) for k, v in english)}
    vdf.dump({"lang":dat}, codecs.open(vdff, 'w', 'utf-8'), pretty=True)
    print "wrote " + vdff
Exemple #8
0
	def test_theater_files(self):
		for theater_file in theater_files:
			th = Theater(filename=os.path.join(theater_path,theater_file))
			for out_file in out_files:
				data = getattr(th, out_file)
				out_file_path = os.path.join(out_path,os.path.basename(theater_file).replace(".theater",""),"%s.txt" % out_file)
				if not os.path.exists(os.path.dirname(out_file_path)):
					os.makedirs(os.path.dirname(out_file_path))
				vdf.dump(data, open(out_file_path,'w'), pretty=True)
Exemple #9
0
def restore_launch_options():
    """Removes changes made by "fix_launch_option" function."""
    for conf_file in localconfig_paths:
        loaded = vdf.load(open(conf_file))
        apps = loaded['UserLocalConfigStore']['Software']['Valve']['Steam']['Apps']
        for app_id in apps.keys():
            app = apps[app_id]
            if 'LaunchOptions' in app.keys():
                app['LaunchOptions'] = sub('&\\s/.*fix-wm-class\\.sh.*?;', '', app['LaunchOptions'])
        vdf.dump(loaded, open(conf_file, 'w'), pretty=True)
Exemple #10
0
 def test_dump_params_invalid(self):
     # pretty/escaped only accept bool
     with self.assertRaises(TypeError):
         vdf.dump({'a': 1}, StringIO(), pretty=1)
     with self.assertRaises(TypeError):
         vdf.dumps({'a': 1}, pretty=1)
     with self.assertRaises(TypeError):
         vdf.dump({'a': 1}, StringIO(), escaped=1)
     with self.assertRaises(TypeError):
         vdf.dumps({'a': 1}, escaped=1)
    def change_user(acc: SteamAccount):
        # TODO: Windows need registry edit, no VDF
        with open(STEAMREGISTRY, 'r') as f:
            registry = vdf.load(f, mapper=vdf.VDFDict)

        steam = registry["Registry"]["HKCU"]["Software"]["Valve"]["Steam"]
        steam[(0, "AutoLoginUser")] = acc.get_login()
        steam[(0, "RememberPassword")] = "1"

        with open(STEAMREGISTRY, 'w') as f:
            vdf.dump(registry, f, pretty=True)
Exemple #12
0
    def test_routine_dump_writing(self):
        class CustomDict(dict):
            pass

        for mapper in (dict, CustomDict):
            src = mapper({"asd": "123"})
            expected = vdf.dumps(src)

            vdf.dump(src, self.f)
            self.f.seek(0)

        self.assertEqual(expected, self.f.read())
Exemple #13
0
def del_client_user(steamID):
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "SOFTWARE\Valve\Steam", 0,
                         winreg.KEY_QUERY_VALUE)
    path, t = winreg.QueryValueEx(key, "SteamPath")
    users = {}

    with open(path + "/config/loginusers.vdf", "r", encoding="utf-8") as file:
        users = vdf.load(file)
        del users["users"][steamID]

    with open(path + "/config/loginusers.vdf", "w", encoding="utf-8") as file:
        vdf.dump(users, file)
Exemple #14
0
    def test_routine_dump_writing(self):
        class CustomDict(dict):
            pass

        for mapper in (dict, CustomDict):
            src = mapper({"asd": "123"})
            expected = vdf.dumps(src)

            vdf.dump(src, self.f)
            self.f.seek(0)

        self.assertEqual(expected, self.f.read())
Exemple #15
0
def achievements_po2vdf(vdff, langs):
    english = load_achievements().items()
    dat = {}
    for lang in langs:
        trans = dict((pe.msgid, pe.msgstr) for pe in open_po(
            os.path.join(ROOT, "lang", lang, "achievements.po")))
        dat[steam_languages[lang]] = {
            "Tokens": dict((k, trans[v]) for k, v in english)
        }
    if dryrun:
        return
    vdf.dump({"lang": dat}, io.open(vdff, 'w', encoding='utf-8'), pretty=True)
    print "wrote " + vdff
Exemple #16
0
def set_auto_update_behavior(new_value: str):
    """
    Args:
    new_value (str): A string that is either "0", "1", or "2" which correspond to the accepted AutoUpdateBehavior
    values.
    """
    close_steam()

    # Variables for keeping track of how many acf files were processed
    num_updated_acf_files = 0
    num_total_acf_files = 0

    for steamapp_directory in all_steam_directories:
        os.chdir(steamapp_directory +
                 "\\steamapps")  # TODO: Is this still needed?
        for appmanifest_path in glob.glob("appmanifest_*.acf"):
            num_total_acf_files += 1

            appmanifest_acf = vdf.load(open(appmanifest_path),
                                       mapper=vdf.VDFDict)  # Load VDF file
            old_value = appmanifest_acf["AppState"]["AutoUpdateBehavior"]
            if old_value != new_value:
                # Delete old value and add new value in memory
                del appmanifest_acf["AppState"]["AutoUpdateBehavior"]
                appmanifest_acf["AppState"].update(
                    {'AutoUpdateBehavior': new_value})

                # Only backup and then output to file if it was updated
                Tools.backup_file(appmanifest_path)
                vdf.dump(appmanifest_acf,
                         open(appmanifest_path, "w"),
                         pretty=True)

                num_updated_acf_files += 1

    if num_updated_acf_files == 0:
        print(
            f"All {num_total_acf_files} games already had the requested AutoUpdateBehavior."
        )
    elif num_updated_acf_files == num_total_acf_files:
        print(
            f"All {num_total_acf_files} games were updated to the requested AutoUpdateBehavior."
        )
    else:
        print(
            f"{num_updated_acf_files}/{num_total_acf_files} games were updated to the requested AutoUpdateBehavior.\n"
            f"(some already had the requested AutoUpdateBehavior.)")
    print(
        f"{len(all_steam_directories)} Steam library folder(s) were searched.")
Exemple #17
0
    def _gen_control_file(self, output: Path, files: List[Path]):
        entries = {}
        for f in files:
            # Ensure the control file itself and VPKs are excluded
            if (f.name == output.name or f.name == f"{output.name}.bak"
                    or f.suffix == ".vpk"):
                continue

            rel = str(os.path.relpath(f, self.input_path)).replace("\\", "/")
            entries[rel] = {"destpath": rel, "md5": self._md5_file(str(f))}

        # VPK needs the files to stay in the same order
        res = dict(sorted(entries.items()))
        with output.open("w") as f:
            vdf.dump(res, f, pretty=True)
Exemple #18
0
def app_build_setup():
    plugin_dir = unreal.Paths.project_plugins_dir()
    plugin_dir = unreal.Paths.convert_relative_path_to_full(plugin_dir)

    bitbake_data = load_bitbake_data()
    output_dir = bitbake_data[0][
        'SteamSDKDirectory'] + "/tools/ContentBuilder/output"
    appid = bitbake_data[0]['AppID']
    steam_branch = bitbake_data[0]['SteamBranch']

    description = "Current Changeset: {}".format(check_for_vcs())

    builder_vdf = vdf.load(
        open('{}/generic_app_build.vdf'.format(os.path.dirname(__file__)),
             'r'))
    depot_vdf = "{}BitBaker/Content/Python/custom_depot.vdf".format(plugin_dir)

    # Writes all values to the App Build VDF
    builder_vdf['appbuild']['appid'] = appid
    builder_vdf['appbuild']['desc'] = description
    builder_vdf['appbuild']['buildoutput'] = output_dir
    builder_vdf['appbuild']['setlive'] = steam_branch

    # Deletes all current depots to add new ones
    builder_vdf['appbuild']['depots'].clear()

    # Hack to increase app id by 1, assuming the base Steam Depots are always AppID + 1
    # TODO: Add support for more than 1 depot
    depot_key = int(appid) + 1
    builder_vdf['appbuild']['depots'][str(depot_key)] = depot_vdf

    # Temporarily dumps users parameters on a VDF
    with open('{}/custom_app_build.vdf'.format(os.path.dirname(__file__)),
              'w+') as in_file:
        in_file.truncate()
        vdf.dump(builder_vdf, in_file, pretty=True)

    # Reopens the VDF so its contents are recorded and edits out all \\ from the code
    # This is only needed because stupid VDF Library doesn't dump Paths with regular \ notation
    with open('custom_app_build.vdf', 'r+') as out_file:
        all_lines = []
        for line in out_file:
            line = line.replace(r'\\', '\\')
            all_lines.append(line)
        out_file.seek(0)
        out_file.truncate()
        out_file.writelines(all_lines)
Exemple #19
0
def depot_setup(build_folder):

    bitbake_data = load_bitbake_data()
    depot_id = bitbake_data[0]['AppID']
    build_dir = bitbake_data[0]['BuildDirectory']
    depot_vdf = vdf.load(
        open('{}/generic_depot.vdf'.format(os.path.dirname(__file__)), 'r'))

    # Writes all values to the Depot VDF
    depot_id = int(depot_id) + 1
    depot_vdf['DepotBuildConfig']['DepotID'] = str(depot_id)
    depot_vdf['DepotBuildConfig']['contentroot'] = "{}/{}".format(
        build_dir, build_folder)

    # Dumps users parameters on a VDF
    with open('{}/custom_depot.vdf'.format(os.path.dirname(__file__)),
              'r+') as in_file:
        in_file.truncate()
        vdf.dump(depot_vdf, in_file, pretty=True)
Exemple #20
0
    def __call__(self, handle):
        # language = pycountry.languages.get(alpha_2=self.language)

        # file_base = copy.deepcopy(vdfTranslationBase)
        file_base = vdf.loads(vdf.dumps(vdfTranslationBase)) # copy structure
        # file_base['lang']['Language'] = language.name
        file_base['lang']['Language'] = self.language.capitalize()

        for unit in self.units:
            file_base['lang']['Tokens'][unit.key] = unit.text

        file_content = vdf.dump(file_base, handle, pretty=True)
    def set_app_launchopts(self, appid: int, params: str):
        '''Sets app launch options (commandline parameters)'''
        with open(self.path / "config/localconfig.vdf", 'r') as f:
            cfg = vdf.load(f, mapper=vdf.VDFDict)

        meh = cfg['UserLocalConfigStore']['Software']['Valve']['Steam'][
            'Apps'][str(appid)]
        if 'LaunchOptions' in meh:
            del meh['LaunchOptions']
        meh['LaunchOptions'] = params

        with open(self.path / "config/localconfig.vdf", 'w') as f:
            cfg = vdf.dump(cfg, f, pretty=True)
Exemple #22
0
    def upload_workshopfiles(self,
                             user,
                             password,
                             workshop_vdf_path=None,
                             workshop_vdf=None):
        """
        Uploads workshop items in accordance to the workshop vdf file.
        :param workshop_vdf_path: path to workshop vdf file.
        :param workshop_vdf: Optional, vdf object See https://pypi.org/project/vdf/
        :param user: steam username (required valid user)
        :param password: steam password (required valid user password)
        """
        if workshop_vdf_path:
            vdf_data = self._parse_vdf(vdf_path=workshop_vdf_path)
        elif workshop_vdf:
            vdf_data = self._parse_vdf_text(vdf_data=workshop_vdf)

        with open(
                "{install_path}/workshop.vdf".format(
                    install_path=self.install_path), "w") as vdf_file:
            vdf.dump(vdf_data, vdf_file)

        # Upload the workshop files
        steamcmd_params = (
            self.steamcmd_exe,
            '+login {} {}'.format(user, password),
            '+workshop_build_item',
            '{install_path}/workshop.vdf'.format(
                install_path=self.install_path),
            '+quit',
        )
        try:
            return subprocess.check_call(steamcmd_params)
        except subprocess.CalledProcessError:
            raise SteamcmdException(
                "Steamcmd was unable to run. Did you install your 32-bit libraries?"
            )
Exemple #23
0
def setup_compat_tool_extensions(current_info):
    compat_tool_dest = Path('.local/share/Steam/compatibilitytools.d')
    compat_tool_dest.mkdir(parents=True, exist_ok=True)

    # Copy extensions if they exist
    for compat_tool_ext in Path('/app/compatibilitytools.d').iterdir():
        if not compat_tool_ext.is_dir():
            continue

        compat_tool_ext_id = f'com.valvesoftware.Steam.CompatibilityTool.{compat_tool_ext.name}'
        compat_tool_ext_dest = compat_tool_dest / compat_tool_ext.name
        compat_tool_ext_commit_hash = current_info["app-extensions"][
            compat_tool_ext_id]
        compat_tool_ext_commit_file = compat_tool_ext_dest / '.extension-commit'

        if compat_tool_ext_dest.exists():
            if compat_tool_ext_commit_file.exists():
                with compat_tool_ext_commit_file.open() as fp:
                    if fp.read() == compat_tool_ext_commit_hash:
                        continue

        src_vdf = compat_tool_ext / 'compatibilitytool.vdf'
        dst_vdf = compat_tool_ext_dest / 'compatibilitytool.vdf'

        with src_vdf.open('r') as sf:
            compat_tool_vdf = vdf.load(sf)
        for v in compat_tool_vdf['compatibilitytools']['compat_tools'].values(
        ):
            v['install_path'] = compat_tool_ext

        print(f'Writing {dst_vdf}')
        os.makedirs(os.path.dirname(dst_vdf), exist_ok=True)
        with dst_vdf.open('w') as df:
            vdf.dump(compat_tool_vdf, df, pretty=True)

        with compat_tool_ext_commit_file.open('w') as fp:
            fp.write(compat_tool_ext_commit_hash)
Exemple #24
0
# Setup DB Configs
with open(DB_CONFIG_FILE) as file:
    db_config = vdf.load(file)

db_info = urlparse(secrets['tf2m_site_connection_str'])
db_config['Databases']['xenforo'] = {
    "driver": "default",
    "host": db_info.hostname,
    "user": db_info.username,
    "pass": db_info.password,
    "port": db_info.port,
    "database": db_info.path.replace("/", "")
}
db_info = urlparse(secrets['tf2m_bot_connection_str'])
db_config['Databases']['bot'] = {
    "driver": "default",
    "host": db_info.hostname,
    "user": db_info.username,
    "pass": db_info.password,
    "port": db_info.port,
    "database": db_info.path.replace("/", "")
}

with open(DB_CONFIG_FILE, "w") as file:
    vdf.dump(db_config, file, pretty=True)

# Set instance hostname
subprocess.run(["/usr/bin/hostnamectl", "set-hostname", f"{tags['Name']}"],
               check=True)
Exemple #25
0
username = args.username
password = args.password

sguard = args.steamguard or ""

file = args.vdf

with open(file, "r") as f:
    d = vdf.load(f)

wsitem = d["workshopitem"]


args = vars(args)
for i in optional_args:
    if args[i]:
        v = wsitem[i].format(args[i])
        wsitem[i] = v
        print("Setting {} to {}".format(i, v))

with open("./tmp_vdf.vdf", "w") as f:
    vdf.dump(d, f, pretty=True)


subprocess.call(
    "steamcmd +login {} {} {} +workshop_build_item {} +quit".format(
        username, password, sguard, os.path.realpath("./tmp_vdf.vdf")
    ),
    shell=True,
)
Exemple #26
0
def main(argv):
    usage = "Usage: ProtonDB-to-Steam-Library.py \n" \
          + "        -s <absolute path to sharedconfig.vdf> \n" \
          + "        -n (disables saving)"
    sharedconfig_path = ""
    skip_save = False

    ### From here until the comment saying otherwise is just parsing the command line arguements
    try:
        opts, _ = getopt.getopt(argv, "hs:n")

    except getopt.GetoptError:
        print(usage)
        sys.exit()

    for opt, arg in opts:
        if opt == "-h":
            print(usage)
            sys.exit()

        elif opt in "-s":
            if os.path.exists(arg):
                try:
                    vdf.load(open(arg))
                    sharedconfig_path = arg
                except:
                    print(arg)
                    print("Invalid path!")
                    sys.exit()

            # With ~ for user home
            elif os.path.exists(os.path.expanduser(arg)):
                try:
                    vdf.load(open(arg))
                    sharedconfig_path = os.path.expanduser(arg)

                except:
                    print(os.path.expanduser(arg))
                    print("Invalid path!")
                    sys.exit()

            else:
                print(arg)
                print("Invalid path!")
                sys.exit()

        elif opt in "-n":
            skip_save = True
    ### Done with command line arguements

    # If sharedconfig_path was not set with a command line arguement, have get_sharedconfig_path() find it
    if not sharedconfig_path:
        sharedconfig_path = get_sharedconfig_path()

    print("Selected: " + sharedconfig_path)
    sharedconfig = vdf.load(open(sharedconfig_path))

    # Get which version of the configstore you have
    configstore = get_configstore_for_vdf(sharedconfig)

    for app_id in sharedconfig[configstore]["Software"]["Valve"]["Steam"][
            "Apps"]:
        try:
            # This has to be here because some Steam AppID's are strings of text, which ProtonDB does not support. Check test01.vdf line 278 for an example.
            app_id = int(app_id)
            tag_num = ""

            # If the app is native, no need to check ProtonDB
            if is_native(str(app_id)):
                print(str(app_id) + " native")
                continue

            try:
                # Have to create a copy to avoid: "RuntimeError: dictionary changed size during iteration"
                tags = sharedconfig[configstore]["Software"]["Valve"]["Steam"][
                    "Apps"][str(app_id)]["tags"].copy()
                for tag in tags:
                    # Search to see if a ProtonDB rank is already a tag, if so just overwrite that tag
                    if sharedconfig[configstore]["Software"]["Valve"]["Steam"][
                            "Apps"][str(app_id)]["tags"][tag].startswith(
                                "ProtonDB Ranking:", 0, 17):
                        if not tag_num:
                            tag_num = tag
                        else:
                            # Delete dupe tags caused by error of previous versions, may remove this check in the future once its no longer an issue
                            del sharedconfig[configstore]["Software"]["Valve"][
                                "Steam"]["Apps"][str(app_id)]["tags"][tag]
                if not tag_num:
                    # If no ProtonDB tags were found, use the next available number
                    tag_num = str(
                        len(sharedconfig[configstore]["Software"]["Valve"]
                            ["Steam"]["Apps"][str(app_id)]["tags"]))
            # If the tags key wasn't found, that means there are no tags for the game
            except KeyError:
                tag_num = "0"
                sharedconfig[configstore]["Software"]["Valve"]["Steam"][
                    "Apps"][str(app_id)]["tags"] = vdf.VDFDict()

            protondb_rating = get_protondb_rating(app_id)
            print(str(app_id) + " " + protondb_rating)

            # The 1,2,etc. force the better ranks to be at the top, as Steam sorts these alphabetically
            possible_ranks = {
                "platinum": "ProtonDB Ranking: 1 Platinum",
                "gold": "ProtonDB Ranking: 2 Gold",
                "silver": "ProtonDB Ranking: 3 Silver",
                "bronze": "ProtonDB Ranking: 4 Bronze",
                "pending": "ProtonDB Ranking: 5 Pending",
                "unrated": "ProtonDB Ranking: 6 Unrated",
                "borked": "ProtonDB Ranking: 7 Borked",
            }

            # Try to inject the tag into the vdfDict, if the returned rating from ProtonDB isn't a key above it will error out
            try:
                sharedconfig[configstore]["Software"]["Valve"]["Steam"][
                    "Apps"][str(app_id)]["tags"][tag_num] = possible_ranks[
                        protondb_rating]
            except KeyError:
                print("Unknown ProtonDB rating: " + protondb_rating +
                      "\n Please report this on GitHub!")

        except urllib.error.HTTPError:
            continue
        except ValueError:
            continue

    # skip_save will be True if -n is passed
    if not skip_save:
        print("WARNING: This may clear your current tags on Steam!")
        check = input("Would you like to save sharedconfig.vdf? (y/N)")
        if check.lower() in ("yes", "y"):
            # Output the edited vdfDict back to the origional location
            vdf.dump(sharedconfig, open(sharedconfig_path, 'w'), pretty=True)
def main(args):
    sharedconfig_path = ""
    no_save = args.no_save
    check_native = args.check_native

    if args.sharedconfig_path:
        # With ~ for user home
        if os.path.exists(os.path.expanduser(args.sharedconfig_path)):
            try:
                with open(args.sharedconfig_path) as sharedconfig_vdf:
                    vdf.load(sharedconfig_vdf)
                sharedconfig_path = os.path.expanduser(args.sharedconfig_path)

            except:
                print("Invalid sharedconfig path: '{}'".format(args.sharedconfig_path))
                sys.exit()
        else:
            print("Shared config path '{}' does not exist. Using default path.".format(args.sharedconfig_path))

    # If sharedconfig_path was not set with a command line argument, have get_sharedconfig_path() find it
    if not sharedconfig_path:
        sharedconfig_path = find_sharedconfig()

    print("Selected: {}".format(sharedconfig_path))
    with open(sharedconfig_path) as sharedconfig_vdf:
        sharedconfig = vdf.load(sharedconfig_vdf)

    # Get which version of the configstore you have
    configstore = get_configstore_for_vdf(sharedconfig)

    # This makes the code slightly cleaner
    apps = sharedconfig[configstore]["Software"]["Valve"]["Steam"][get_apps_key(sharedconfig, configstore)]

    appCount = len(apps)
    print("Found {} Steam games".format(appCount))

    for count, app_id in enumerate(apps, 1):
        # This has to be here because some Steam AppID's are strings of text, which ProtonDB does not support. Check test01.vdf line 278 for an example.
        try:
            int(app_id)
        except ValueError:
            continue

        protondb_rating = ""
        # If the app is native, no need to check ProtonDB
        if check_native and is_native(app_id):
            protondb_rating = "native"
        else:
            # Get the ProtonDB rating for the app, if ProtonDB 404's it means no rating is available for the game and likely native
            try:
                protondb_rating = get_protondb_rating(app_id)
            except ProtonDBError:
                continue

        tag_num = get_tag_number(apps[app_id])

        # The 1,2,etc. force the better ranks to be at the top, as Steam sorts these alphanumerically
        possible_ranks = {
            "native":   "ProtonDB Ranking: 0 Native",
            "platinum": "ProtonDB Ranking: 1 Platinum",
            "gold":     "ProtonDB Ranking: 2 Gold",
            "silver":   "ProtonDB Ranking: 3 Silver",
            "bronze":   "ProtonDB Ranking: 4 Bronze",
            "pending":  "ProtonDB Ranking: 5 Pending",
            "unrated":  "ProtonDB Ranking: 6 Unrated",
            "borked":   "ProtonDB Ranking: 7 Borked",
        }


        new_rank = True
        try:
            old_tag = apps[app_id]["tags"][tag_num]
            old_key = ""

            # Get the old key (protondb ranking)
            for key, value in possible_ranks.items():
                if value == old_tag:
                    old_key = key
                    break

            # No change since last run, we don't need to output or save it
            if old_key == protondb_rating:
                new_rank = False
            else:
                print("{} {} => {} ({} of {})".format(app_id, old_key, protondb_rating, count, appCount))
        # If it throws a key error it is a new game to rank
        except KeyError:
            print("{} {}".format(app_id, protondb_rating))

        if new_rank:
            # Try to inject the tag into the vdfDict, if the returned rating from ProtonDB isn't a key above it will error out
            if protondb_rating in possible_ranks:
                apps[app_id]["tags"][tag_num] = possible_ranks[protondb_rating]
            else:
                print("Unknown ProtonDB rating: {}\n Please report this on GitHub!".format(protondb_rating))


    # no_save will be True if -n is passed
    if not no_save:
        print("WARNING: This may clear your current tags on Steam!")
        check = input("Would you like to save sharedconfig.vdf? (y/N)")
        if check.lower() in ("yes", "y"):
            # Output the edited vdfDict back to the original location
            with open(sharedconfig_path, 'w') as sharedconfig_vdf:
                vdf.dump(sharedconfig, sharedconfig_vdf, pretty=True)

            # Workaround provided by Valve for the new library
            url = "steam://resetcollections"
            if sys.platform == "win32":
                command = "start "
            else:
                command = "xdg-open "
            input("Please launch Steam, then press Enter to continue...")
            os.system(command + url) #Reset Collections
Exemple #28
0
 def save_content(self, handle):
     vdf.dump(self.store, handle, pretty=True)
 def save_file(self, data, path=None):
     if path == None:
         path = self.config_name
     vdf.dump(data, open(path, "w"), pretty=True)
Exemple #30
0
print 'This program converts form and to the .txt format used by Source Engine to / from .json, ready to be used by POEditor. It is also capable of converting from the exported' \
      ' .json to an usable .txt by Source. It first asks for a language. You must enter the lowercase, english name of the language, so it will search for that language file.' \
      ' If you want to go from .json to .txt, you must name your .json with the language\'s name it contains. Encoding a file will also create a "_ref_exp" file.'

lang = raw_input("Language?\n")
option = raw_input("DECODE (D) (.txt to .json) or ENCODE (E) (.json to .txt)?\n")

if option == "DECODE" or option == "D":
    print "Decoding..."
    d = vdf.load(open("momentum_" + lang + '.txt'), mapper=vdf.VDFDict)
    tokens = []
    for key, value in d['lang']['Tokens'].items():
        tokens.append({'term': key, 'definition': value})
    json.dump(tokens, open("momentum_" + lang + '.json', 'w'), indent=4, sort_keys=True)
    print 'Tokens dumped to .json'

elif option == "ENCODE" or option == "E":
    print "Encoding..."
    with open(lang + '.json') as filez:
        jos = json.load(filez)
        mom = vdf.VDFDict([('lang', vdf.VDFDict([('Language', lang.title()), ('Tokens', vdf.VDFDict())]))])
        for key in jos:
            mom['lang']['Tokens'][key['term']] = key['definition']
        vdf.dump(mom, open('momentum_' + lang + '.txt', 'w', encoding='utf_16_le'), pretty=True)
        print 'momentum_%s exported.' % lang
        if lang == 'english':
            vdf.dump(mom, open('momentum_english_ref_exp.txt', 'w', encoding='utf-8'), pretty=True)
            print 'momentum_english_ref_exp exported.'

else:
    print "Unknown command. DECODE/D or ENCODE/E"
    def writeLibraryInfo(self):
        # Make sure directories all exist
        for key in self.new_config['libraryfolders']:
            if self._isint(key):
                folder = os.path.join(
                    self.new_config['libraryfolders'][key]['path'],
                    'steamapps')
                if not os.path.exists(folder):
                    if messagebox.askyesno(
                            "Create folders?",
                            "Do you want to create the directory \"{}\"?".
                            format(folder)):
                        try:
                            os.makedirs(folder, exist_ok=True)
                        except:
                            messagebox.showerror(
                                "Error", "Error when creating directories")
                            raise

        # Create backups
        try:
            for f_path in [
                    self.config_library_vdf, self.steamapps_library_vdf
            ]:
                if not os.path.exists(f_path):
                    continue

                with open(f_path, 'r') as f_in:
                    with open(f_path + '.bak', 'w') as f_out:
                        f_out.write(f_in.read())
        except:
            if not messagebox.askyesno(
                    "Warning", "Failed to create a backup. Proceed anyways?"):
                raise

        # Write the new files
        restore_backup = False
        try:
            vdf.dump(self.new_config,
                     open(self.config_library_vdf, 'w'),
                     pretty=True)
            vdf.dump(self.new_config,
                     open(self.steamapps_library_vdf, 'w'),
                     pretty=True)
        except:
            restore_backup = True

        # Restore the backup if needed
        if restore_backup:
            messagebox.showerror(
                "Error",
                "Failed to write libraryfolders.vdf. Restoring backup...")
            try:
                for f_path in [
                        self.config_library_vdf, self.steamapps_library_vdf
                ]:
                    with open(f_path + '.bak', 'r') as f_in:
                        with open(f_path, 'w') as f_out:
                            f_out.write(f_in.read())
            except:
                messagebox.showerror(
                    "Error", "Failed to restore backup! Sorry about that.")
                raise

        # Tell the user stuff is done
        messagebox.showinfo("Complete",
                            "Steam Library Setup is done. Closing program...")
        self.quit()
def main(args):
    sharedconfig_path = ""
    no_save = args.no_save
    check_native = args.check_native

    if args.sharedconfig_path:
        # With ~ for user home
        if os.path.exists(os.path.expanduser(args.sharedconfig_path)):
            try:
                with open(args.sharedconfig_path) as sharedconfig_vdf:
                    vdf.load(sharedconfig_vdf)
                sharedconfig_path = os.path.expanduser(args.sharedconfig_path)

            except:
                print("Invalid sharedconfig path: '{}'".format(
                    args.sharedconfig_path))
                sys.exit()
        else:
            print(
                "Shared config path '{}' does not exist. Using default path.".
                format(args.sharedconfig_path))

    # If sharedconfig_path was not set with a command line argument, have get_sharedconfig_path() find it
    if not sharedconfig_path:
        sharedconfig_path = find_sharedconfig()

    print("Selected: {}".format(sharedconfig_path))
    with open(sharedconfig_path) as sharedconfig_vdf:
        sharedconfig = vdf.load(sharedconfig_vdf)

    # Get which version of the configstore you have
    configstore = get_configstore_for_vdf(sharedconfig)

    # This makes the code slightly cleaner
    apps = sharedconfig[configstore]["Software"]["Valve"]["Steam"][
        get_apps_key(sharedconfig, configstore)]

    for app_id in apps:
        # This has to be here because some Steam AppID's are strings of text, which ProtonDB does not support. Check test01.vdf line 278 for an example.
        try:
            int(app_id)
        except ValueError:
            continue

        protondb_rating = ""
        # If the app is native, no need to check ProtonDB
        if check_native and is_native(app_id):
            protondb_rating = "native"
            print("{} native".format(app_id))
        else:
            # Get the ProtonDB rating for the app, if ProtonDB 404's it means no rating is available for the game and likely native
            try:
                protondb_rating = get_protondb_rating(app_id)
                print("{} {}".format(app_id, protondb_rating))
            except ProtonDBError:
                continue

        tag_num = get_tag_number(apps[app_id])

        # The 1,2,etc. force the better ranks to be at the top, as Steam sorts these alphanumerically
        possible_ranks = {
            "native":
            "ProtonDB Ranking: 0 Native",  # This should probably be changed eventually, but this is to allow us to scan the tags for an existing one.
            "platinum": "ProtonDB Ranking: 1 Platinum",
            "gold": "ProtonDB Ranking: 2 Gold",
            "silver": "ProtonDB Ranking: 3 Silver",
            "bronze": "ProtonDB Ranking: 4 Bronze",
            "pending": "ProtonDB Ranking: 5 Pending",
            "unrated": "ProtonDB Ranking: 6 Unrated",
            "borked": "ProtonDB Ranking: 7 Borked",
        }

        # Try to inject the tag into the vdfDict, if the returned rating from ProtonDB isn't a key above it will error out
        if protondb_rating in possible_ranks:
            apps[app_id]["tags"][tag_num] = possible_ranks[protondb_rating]
        else:
            print(
                "Unknown ProtonDB rating: {}\n Please report this on GitHub!".
                format(protondb_rating))

    # no_save will be True if -n is passed
    if not no_save:
        print("WARNING: This may clear your current tags on Steam!")
        check = input("Would you like to save sharedconfig.vdf? (y/N)")
        if check.lower() in ("yes", "y"):
            # Output the edited vdfDict back to the original location
            with open(sharedconfig_path, 'w') as sharedconfig_vdf:
                vdf.dump(sharedconfig, sharedconfig_vdf, pretty=True)
Exemple #33
0
        print "Decoding..."
        for loclfile in files:
            d = vdf.load(open(loclfile + lang + '.txt'), mapper=vdf.VDFDict)
            tokens = []
            for key, value in d['lang']['Tokens'].items():
                if loclfile is 'gameui_':
                    tokens.append({'term': key, 'definition': value, 'context':'gameui'})
                else:
                    tokens.append({'term': key, 'definition': value})
            json.dump(tokens, open(loclfile+lang + '.json', 'w'), indent=4, sort_keys=True)
            print 'Tokens dumped to .json'
            
    elif option is "ENCODE" or option is "E":
        print "Encoding..."
        with open(lang + '.json') as filez:
            jos = json.load(filez)
            gui = vdf.VDFDict([('lang', vdf.VDFDict([('Language', lang.title()), ('Tokens', vdf.VDFDict())]))])
            mom = vdf.VDFDict([('lang', vdf.VDFDict([('Language', lang.title()), ('Tokens', vdf.VDFDict())]))])
            for key in jos:
                if key['context'] == 'gameui':
                    gui['lang']['Tokens'][key['term']] = key['definition']
                else:
                    mom['lang']['Tokens'][key['term']] = key['definition']
            if gam is "Y" or gam is "y":
            	vdf.dump(gui, open('gameui_' + lang + '.txt', 'w'), pretty=True)
            	print 'gameui_' + lang + ' exported.'
            vdf.dump(mom, open('momentum_' + lang + '.txt', 'w'), pretty=True)
            print 'momentum_' + lang + ' exported.'

    else:
        print "Unknown command. DECODE/D or ENCODE/E"