-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Running:
(1)(deck@magik-steamdeck ~)$ nonsteam -V
0.7.0
(deck@magik-steamdeck ~)$ nonsteam -v get
ERR: Field key can't be determined
Not clear to me what or where the error is without digging into the code itself, but I can't quickly skimming seem to find what the root of the error might, maybe my shortcuts vdf file is in a format that this can't parse?
A bit of iteration with gemini produced me this script that seemed to work, not sure what the delta is to your code here:
import vdf
import json
import argparse
import subprocess
import sys
import zlib
import struct
import shutil
from pathlib import Path
def find_shortcuts_file():
search_path = "/home/deck/.local/share/Steam/userdata/"
cmd = ["find", search_path, "-type", "f", "-name", "shortcuts.vdf"]
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
files = [f for f in result.stdout.strip().split('\n') if f]
# Prioritize the file in a directory with a long number (your user ID)
valid_files = [f for f in files if Path(f).stat().st_size > 100]
return valid_files[0] if valid_files else None
except: return None
def calculate_appid(exe, name):
unique_id = f'"{exe}"{name}'
return (zlib.crc32(unique_id.encode()) | 0x80000000) & 0xFFFFFFFF
def to_signed_32(n):
return struct.unpack('i', struct.pack('I', n))[0]
def main():
parser = argparse.ArgumentParser(description="Steam Deck Shortcut Manager")
parser.add_argument("--find-only", action="store_true")
subparsers = parser.add_subparsers(dest="command")
subparsers.add_parser("list")
subparsers.add_parser("dump")
add_parser = subparsers.add_parser("add")
add_parser.add_argument("--name", required=True)
add_parser.add_argument("--path", required=True)
add_parser.add_argument("--overwrite", action="store_true")
args = parser.parse_args()
vdf_path = find_shortcuts_file()
if not vdf_path:
print("Error: Could not find shortcuts.vdf"); sys.exit(1)
print(f"[*] Targeting: {vdf_path}")
if args.find_only: sys.exit(0)
# 1. Load the data using a more resilient buffer read
try:
with open(vdf_path, 'rb') as f:
raw_data = f.read()
if not raw_data:
data = {"shortcuts": {}}
else:
# Use the library but catch internal alignment errors
data = vdf.binary_loads(raw_data)
except Exception as e:
print(f"Error: The VDF file structure is inconsistent. ({e})")
print("Try closing Steam and running the script again.")
sys.exit(1)
shortcuts = data.get("shortcuts", {})
if args.command == "list":
print(f"{'AppID':<12} | {'Name'}")
for s in shortcuts.values():
print(f"{(s.get('appid', 0) & 0xFFFFFFFF):<12} | {s.get('appname')}")
elif args.command == "dump":
print(json.dumps(data, indent=4))
elif args.command == "add":
u_id = calculate_appid(args.path, args.name)
if any((s.get('appid', 0) & 0xFFFFFFFF) == u_id for s in shortcuts.values()) and not args.overwrite:
print(f"Error: AppID {u_id} already exists."); sys.exit(1)
# Build entry
new_entry = {
"appid": to_signed_32(u_id),
"appname": args.name,
"exe": f'"{args.path}"',
"StartDir": f'"{Path(args.path).parent}/"',
"icon": "", "ShortcutPath": "", "LaunchOptions": "",
"IsHidden": 0, "AllowDesktopConfig": 1, "AllowOverlay": 1,
"OpenVR": 0, "Devkit": 0, "DevkitGameID": "",
"DevkitOverrideAppID": 0, "LastPlayTime": 0, "FlatpakAppID": "", "tags": {}
}
# Backup & Save
shutil.copy2(vdf_path, vdf_path + ".bak")
next_idx = str(max([int(k) for k in shortcuts.keys()] + [-1]) + 1)
shortcuts[next_idx] = new_entry
with open(vdf_path, 'wb') as f:
f.write(vdf.binary_dumps(data))
print(f"Added {args.name} ({u_id}). Please RESTART Steam.")
if __name__ == "__main__":
main()
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels