From cea6bc803a0f1b5ab4c13552f09c26211a23bcbb Mon Sep 17 00:00:00 2001 From: Emily Frost Date: Fri, 8 Mar 2019 11:49:18 -0600 Subject: [PATCH] Added ps2-sync and sdv-manager. --- ps2-sync | 82 ++++++++++++++++++++++++++++++++++++++++++ sdv-manager | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100755 ps2-sync create mode 100755 sdv-manager diff --git a/ps2-sync b/ps2-sync new file mode 100755 index 0000000..6cd70b0 --- /dev/null +++ b/ps2-sync @@ -0,0 +1,82 @@ +#!/usr/bin/python3 +""" +### ps2-sync +This tool makes links to ISO files in the way that Open PS2 Loader expects. It should work for both +Samba and USB loading, but has only been tested with Samba. + +This depends on hdl-dump. +""" + +import os +import subprocess + +# TODO: Replace these with user input and/or config files. +ROOT_PATH = '.' + +def get_disc_info(disc_image_path): + this_disc_info = { + 'gameid': None, + 'disc_type': None, + 'filename': None + } + + # TODO: Figure out how to do hdl-dump's work in this script. + # I tried this with isoparser, but the parsing took far too long. + hdl_dump_args = ['hdl-dump', 'cdvd_info2', disc_image_path] + # hdl-dump has a weird output format, quoting items inconsistently. Fortunately, it isn't + # likely to change anytime soon. + hdl_dump_result = subprocess.run(hdl_dump_args, capture_output=True) + if hdl_dump_result.returncode == 0: + hdl_dump_output = hdl_dump_result.stdout.decode('utf-8').split(' ') + + # hdl-dump prepends "dual-layer" to the disc type field instead of using DVD5/DVD9. + if hdl_dump_output[0] == 'dual-layer': + this_disc_info['gameid'] = hdl_dump_output[4][1:-1] + this_disc_info['disc_type'] = hdl_dump_output[1] + + else: + this_disc_info['gameid'] = hdl_dump_output[3][1:-1] + this_disc_info['disc_type'] = hdl_dump_output[0] + + this_disc_info['filename'] = os.path.basename(disc_image_path) + else: + print('File %s is not a Playstation 2 disc image.' % os.path.basename(disc_image_path)) + + return this_disc_info + +def remove_dead_links(directory): + for link_name in os.listdir(directory): + link_path = os.path.abspath(os.path.join(directory, link_name)) + if os.path.islink(link_path): + link_target = os.path.join(directory, os.readlink(link_path)) + if not os.path.exists(link_target): + print('Removing dead link %s.' % link_path) + os.remove(link_path) + +root_path = os.path.abspath(ROOT_PATH) +source_path = os.path.join(root_path, 'iso') +disc_repo = os.path.join(root_path, '.opl-srv') + +os.makedirs(os.path.join(disc_repo, 'DVD'), exist_ok=True) +os.makedirs(os.path.join(disc_repo, 'CD'), exist_ok=True) +remove_dead_links(os.path.join(disc_repo, 'DVD')) +remove_dead_links(os.path.join(disc_repo, 'CD')) + +for filename in os.listdir(source_path): + disc_path = os.path.join(source_path, filename) + disc_info = get_disc_info(disc_path) + + if not disc_info['disc_type'] or not disc_info['gameid']: + print("Disc type could not be determined for %s" % disc_info['filename']) + + else: + disc_link_filename = '%s.%s' % (disc_info['gameid'], disc_info['filename']) + disc_link_path = os.path.join(disc_repo, disc_info['disc_type'], disc_link_filename) + disc_rel_path = os.path.relpath(disc_path, start=os.path.dirname(disc_link_path)) + + if not os.path.exists(disc_link_path): + print('Adding disc %s.' % disc_info['filename']) + print('Linking to %s.' % disc_rel_path) + os.symlink(disc_rel_path, disc_link_path) + else: + print('Disc %s already linked.' % disc_info['filename']) diff --git a/sdv-manager b/sdv-manager new file mode 100755 index 0000000..929ec2a --- /dev/null +++ b/sdv-manager @@ -0,0 +1,101 @@ +#!/bin/bash + +### Manage Stardew Valley mods + +# Use nginx-style mods-available and mods-enabled folders. + +# game_dir="${HOME}/.local/share/Steam/steamapps/common/Stardew Valley" +game_dir="${HOME}/sdv-manager-test" +mods_available_dir="${game_dir}/mods-available" +mods_enabled_dir="${game_dir}/mods-enabled" +declare -A mod_state + +function get_mod_state { + for available_mod_dir in "$mods_available_dir"/*; do + available_mod_name="$(basename "$available_mod_dir")" + mod_state[$available_mod_name]='disabled' + done + + # TODO: Probably remove broken links and untracked files. + for enabled_mod_dir in "$mods_enabled_dir"/*; do + enabled_mod_name="$(basename "$enabled_mod_dir")" + # xargs sometimes gets a broken pipe signal here. It's harmless but annoying. + if echo "${!mod_state[@]}" | xargs -n1 2>/dev/null | grep -q "$enabled_mod_name"; then + mod_state[$enabled_mod_name]='enabled' + fi + done +} + +function mod_is_available { + mod_name="$1" + get_mod_state + if [[ $mod_name == '' ]]; then + echo "Mod name not given." + elif echo "${!mod_state[@]}" | xargs -n1 2>/dev/null | grep -q "$mod_name"; then + return 0 + else + return 1 + fi +} + +case "$1" in + 'list') + # TODO: Make this printing prettier. + echo 'Listing available mods.' + get_mod_state + for mod in "${!mod_state[@]}"; do + echo "$mod --- ${mod_state[$mod]}" + done + ;; + 'install') + echo 'Implement install.' + # Check if $2 is an existing directory + # If it is, check if a mod with the same name is already installed. + # If not, copy the directory to mods-available + ;; + 'enable') + mod_name="$2" + if mod_is_available "$mod_name"; then + if [[ ${mod_state[$mod_name]} == 'disabled' ]]; then + echo "Enabling $mod_name." + ln -s "${mods_available_dir}/${mod_name}" "${mods_enabled_dir}/${mod_name}" + else + echo "Mod $mod_name is already enabled." + fi + fi + ;; + 'disable') + mod_name="$2" + if mod_is_available "$mod_name"; then + if [[ ${mod_state[$mod_name]} == 'enabled' ]]; then + echo "Disabling $mod_name." + rm "${mods_enabled_dir}/${mod_name}" + else + echo "Mod $mod_name is already disabled." + fi + fi + ;; + 'init') + # TODO: This needs to be a lot more careful. Cases to handle: + # sdv-manager is already set up + echo "Initializing sdv-manager at ${game_dir}." + SMAPI_mods_dir="${game_dir}/Mods" + + mkdir -p "$mods_available_dir" "$mods_enabled_dir" + + for mod_dir in "${SMAPI_mods_dir}"/*; do + mod_name="$(basename "$mod_dir")" + echo "$mod_dir" + echo "$mod_name" + mv "${mod_dir}" "$mods_available_dir" + ln -s "${mods_available_dir}/${mod_name}" "${mods_enabled_dir}" + done + + rmdir "${SMAPI_mods_dir}" + ln -s "${game_dir}/mods-enabled" "${SMAPI_mods_dir}" + ;; + *) + echo "$1 is not a recognized command." + echo "Available commands are enable, disable, install, and init." + ;; +esac