Skip to content

nonsteam get returns Field key can't be determined #7

@marchaase

Description

@marchaase

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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions