fix(steam): better data management and setup

This commit is contained in:
arcnmx 2024-02-16 10:49:55 -08:00
parent 81bd1a1a15
commit 475273692d
5 changed files with 822 additions and 284 deletions

View file

@ -5,12 +5,25 @@
pkgs, pkgs,
... ...
}: let }: let
inherit (inputs.self.lib.lib) userIs; inherit (inputs.self.lib.lib) mkWinPath userIs;
inherit (lib.options) mkOption mkEnableOption; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault; inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
inherit (lib.attrsets) filterAttrs mapAttrsToList listToAttrs nameValuePair; inherit (lib.attrsets) filterAttrs mapAttrsToList listToAttrs nameValuePair;
inherit (lib.lists) singleton; inherit (lib.lists) singleton;
inherit (lib.strings) removePrefix;
cfg = config.services.steam.accountSwitch; cfg = config.services.steam.accountSwitch;
machineModule = { config, name, ... }: {
options = with lib.types; {
name = mkOption {
type = str;
default = name;
};
owner = mkOption {
type = str;
default = "admin";
};
};
};
in { in {
options.services.steam.accountSwitch = with lib.types; { options.services.steam.accountSwitch = with lib.types; {
enable = mkEnableOption "steam-account-switch"; enable = mkEnableOption "steam-account-switch";
@ -52,6 +65,10 @@ in {
users = mkOption { users = mkOption {
type = listOf str; type = listOf str;
}; };
machines = mkOption {
type = attrsOf (submodule machineModule);
default = { };
};
}; };
config = let config = let
@ -76,35 +93,34 @@ in {
inherit owner; inherit owner;
inherit (shared) group mode; inherit (shared) group mode;
}; };
setupFiles = setupFiles = singleton {
singleton { ${cfg.rootDir} = toplevel;
${cfg.rootDir} = toplevel; ${cfg.binDir} = toplevel;
${cfg.binDir} = toplevel; ${cfg.binDir + "/users"} = shared;
${cfg.binDir + "/users"} = shared; ${cfg.dataDir} = toplevel;
${cfg.dataDir} = toplevel; ${cfg.sharedDataDir} = shared;
${cfg.sharedDataDir} = shared; ${cfg.workingDir} = toplevel;
${cfg.workingDir} = toplevel; ${cfg.sharedWorkingDir} = shared;
${cfg.sharedWorkingDir} = shared; } ++ map (owner: {
} ${cfg.dataDir + "/${owner}"} = personal owner;
++ map (owner: { ${cfg.workingDir + "/${owner}"} = personal owner;
${cfg.dataDir + "/${owner}"} = personal owner; }) cfg.users
${cfg.workingDir + "/${owner}"} = personal owner; ++ mapAttrsToList (_: machine: {
}) ${cfg.dataDir + "/${machine.name}"} = personal machine.owner;
cfg.users; ${cfg.workingDir + "/${machine.name}"} = personal machine.owner;
userBinFiles = listToAttrs (map (user: }) cfg.machines;
nameValuePair "${cfg.binDir}/users/${user}.bat" { userBinFiles = listToAttrs (map (user: nameValuePair "${cfg.binDir}/users/${user}.bat" {
inherit (toplevel) owner group; inherit (toplevel) owner group;
mode = "0755"; mode = "0755";
type = "copy"; type = "copy";
src = pkgs.writeTextFile { src = pkgs.writeTextFile {
name = "steam-${user}.bat"; name = "steam-${user}.bat";
executable = true; executable = true;
text = '' text = ''
setx GENSO_STEAM_USER ${user} setx GENSO_STEAM_USER ${user}
''; '';
}; };
}) }) cfg.users);
cfg.users);
in { in {
enable = mkIf (cfg.enable || cfg.setup) true; enable = mkIf (cfg.enable || cfg.setup) true;
files = mkMerge [ files = mkMerge [
@ -112,5 +128,18 @@ in {
(mkIf cfg.enable userBinFiles) (mkIf cfg.enable userBinFiles)
]; ];
}; };
lib.steam = {
mkSharePathWith = {
path,
winRoot ? "%GENSO_SMB_SHARED_MOUNT%",
}: mkWinPath (
winRoot
+ "/${cfg.sharePath}"
+ "/${removePrefix (cfg.rootDir + "/") path}"
);
mkSharePath = path: config.lib.steam.mkSharePathWith {
inherit path;
};
};
}; };
} }

File diff suppressed because it is too large Load diff

View file

@ -1,83 +0,0 @@
#!/usr/bin/env bash
set -eu
ARG_GAME_SRC=$1
ARG_GAME_VERSION=$2
ARG_SHARED_DATA=$3
ARG_USER_DATA=$4
shift 4
if ! [[ -e "$ARG_GAME_SRC/$ARG_GAME_VERSION/Beat Saber.exe" ]]; then
echo unexpected game src >&2
exit 1
fi
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/"*.{exe,dll} ./
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/"{MonoBleedingEdge,Plugins} ./
rm "Beat Saber.exe"
cp "$ARG_GAME_SRC/$ARG_GAME_VERSION/Beat Saber.exe" ./
chmod 0775 "Beat Saber.exe"
BSDATA="Beat Saber_Data"
mkdir -pm2775 "$BSDATA"
ln -srf "$ARG_GAME_SRC/$ARG_GAME_VERSION/$BSDATA/"* "$BSDATA/" || true
ln -srf "$ARG_SHARED_DATA/CustomLevels" "$BSDATA/"
rm -f "$BSDATA/Managed"
mkdir -pm2775 UserData
ln -srf "$ARG_SHARED_DATA/"{CustomAvatars,CustomNotes,CustomPlatforms,CustomSabers,CustomWalls,Playlists} ./
for shareddir in DynamicOpenVR IPA Libs Logs Plugins "$BSDATA/Managed" UserData/SongCore; do
shareddirsrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/$shareddir"
if [[ ! -e $shareddirsrc ]]; then
mkdir -pm2775 "$shareddirsrc"
if [[ $shareddir = */Managed ]]; then
cp "$ARG_GAME_SRC/$ARG_GAME_VERSION/$BSDATA/Managed/"* "$shareddirsrc/" || true
chmod 0775 "$shareddirsrc/"*.dll || true
fi
fi
ln -srf "$shareddirsrc" "./$(dirname "$shareddir")"
done
for sharedfile in IPA.exe IPA.exe.config IPA.runtimeconfig.json winhttp.dll; do
sharedfilesrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/$sharedfile"
if [[ ! -e "$sharedfilesrc" ]]; then
mkdir -pm2775 "$(dirname "$sharedfilesrc")"
if [[ $sharedfile = *.json ]]; then
echo '{}' > "$sharedfilesrc"
else
touch "$sharedfilesrc"
fi
chmod 0775 "$sharedfilesrc" || true
fi
ln -f "$sharedfilesrc" ./
done
for sharedfile in "Beat Saber IPA.json"; do
sharedfilesrc="$ARG_SHARED_DATA/$ARG_GAME_VERSION/UserData/$sharedfile"
if [[ ! -e "$sharedfilesrc" ]]; then
mkdir -pm2775 "$(dirname "$sharedfilesrc")"
if [[ $sharedfile = *.json ]]; then
echo '{}' > "$sharedfilesrc"
else
touch "$sharedfilesrc"
fi
fi
ln -f "$sharedfilesrc" "UserData/$(dirname "$sharedfile")"
done
ln -f "$ARG_SHARED_DATA/UserData/"*.{json,ini,proto,etag} UserData/
ln -srf "$ARG_SHARED_DATA/UserData/"{ScoreSaber,Chroma,Nya,SongRankedBadge,HitScoreVisualizer}/ UserData/
SFDATA="UserData/Saber Factory"
mkdir -pm2775 "$SFDATA"
ln -srf "$ARG_SHARED_DATA/$SFDATA/"*/ "$SFDATA/"
ln -srf "$ARG_USER_DATA/$SFDATA/"*/ "$SFDATA/"
ln -f "$ARG_USER_DATA/$SFDATA/"*.json "$SFDATA/"
for userdir in Camera2 DrinkWater Enhancements; do
userdirsrc="$ARG_USER_DATA/UserData/$userdir"
if [[ ! -e $userdirsrc ]]; then
mkdir -pm3775 "$userdirsrc"
fi
ln -srf "$userdirsrc" UserData/
done
ln -f "$ARG_USER_DATA/UserData/"*.{json,ini,dat} UserData/

View file

@ -7,7 +7,7 @@
inherit (lib.modules) mkIf mkMerge mkDefault; inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.strings) removePrefix; inherit (lib.strings) removePrefix;
inherit (lib.attrsets) listToAttrs nameValuePair; inherit (lib.attrsets) listToAttrs nameValuePair;
inherit (config.services.steam) accountSwitch; inherit (config.services.steam) accountSwitch beatsaber;
cfg = config.kyuuto; cfg = config.kyuuto;
in { in {
options.kyuuto = with lib.types; { options.kyuuto = with lib.types; {
@ -106,11 +106,15 @@ in {
enable = mkIf cfg.setup true; enable = mkIf cfg.setup true;
files = mkMerge [ files = mkMerge [
(mkIf cfg.setup (mkMerge setupFiles)) (mkIf cfg.setup (mkMerge setupFiles))
(mkIf accountSwitch.enable { (mkIf (accountSwitch.enable || beatsaber.setup) {
${accountSwitch.gamesDir} = { ${accountSwitch.gamesDir} = {
type = "bind"; type = "bind";
bindReadOnly = true; bindReadOnly = true;
src = cfg.gameLibraryDir + "/PC"; src = cfg.gameLibraryDir + "/PC";
systemd.mountSettings = rec {
wantedBy = mkIf beatsaber.setup beatsaber.setupServiceNames;
before = wantedBy;
};
}; };
}) })
]; ];

View file

@ -3,5 +3,9 @@
in { in {
services.steam.accountSwitch = { services.steam.accountSwitch = {
enable = mkDefault true; enable = mkDefault true;
machines = {
hourai.owner = "arc";
chen.owner = "kat";
};
}; };
} }