Files
obsidian-vault/family/how-to/htpc-steam-nonsteam-shortcuts.md
T

167 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Non-Steam Shortcuts через VDF
## Главное правило
**Steam должен быть выключен** перед записью shortcuts.vdf. Если Steam работает — он перезапишет файл из памяти при следующем запуске.
## Остановка Steam (Bazzite game session)
```bash
systemctl --user stop gamescope-session-plus@steam.service
sleep 2
systemctl --user is-active gamescope-session-plus@steam.service # должен вернуть "inactive"
# правишь VDF
systemctl --user start gamescope-session-plus@steam.service
```
Если после stop Steam всё ещё активен — повторить.
## Единственный правильный способ — vdf.binary_load
**Процедура (один py-скрипт, с бэкапом):**
1. Остановить Steam
2. Сделать бэкап shortcuts.vdf
3. Отредактировать VDF
4. Запустить Steam
Использовать модуль `vdf` (установлен на HTPC через pip). **Никогда** не редактировать бинарный VDF через ручную сборку байтов или замену строк — это ломает файл.
```python
import os, vdf, shutil, binascii, struct
vdf_path = os.path.expanduser('~/.steam/steam/userdata/147839491/config/shortcuts.vdf')
# 1. Бэкап
shutil.copy2(vdf_path, vdf_path + '.bak')
# 2. Загрузить существующий
with open(vdf_path, 'rb') as f:
data = vdf.binary_load(f)
shortcuts = data.get('shortcuts', {})
# 3. Вычислить appid (алгоритм Steam)
def compute_appid(name, exe):
key = exe + name
top = binascii.crc32(key.encode('utf-8')) | 0x80000000
return struct.unpack('i', struct.pack('I', top))[0]
# 4. Создать entry
next_idx = str(len(shortcuts))
shortcuts[next_idx] = {
'AppName': 'Game Name',
'Exe': '/home/bazzite/Emulation/tools/launchers/ryujinx.sh',
'StartDir': '/home/bazzite/Emulation/tools/launchers',
'LaunchOptions': '/home/bazzite/Emulation/roms/switch/animal_crossing.nsp',
'appid': compute_appid('Game Name', '/home/bazzite/Emulation/tools/launchers/ryujinx.sh'),
'IsHidden': 0,
'AllowDesktopConfig': 1,
'AllowOverlay': 1,
'OpenVR': 0,
'Devkit': 0,
'DevkitGameID': '',
'DevkitOverrideAppID': 0,
'LastPlayTime': 0,
'FlatpakAppID': '',
'sortas': '',
'tags': {},
}
# 5. Записать
data['shortcuts'] = shortcuts
with open(vdf_path, 'wb') as f:
vdf.binary_dump(data, f)
```
## CompatToolMapping (Proton) в config.vdf
После добавления shortcut нужно прописать Proton в текстовом `config.vdf`:
```python
import vdf
CONFIG_PATH = os.path.expanduser('~/.local/share/Steam/config/config.vdf')
with open(CONFIG_PATH, 'r') as f:
config = vdf.load(f)
compat_map = config['InstallConfigStore']['Software']['Valve']['Steam'].setdefault('CompatToolMapping', {})
compat_map[str(appid_signed)] = {
'name': 'GE-Proton10-34', # или 'proton_experimental'
'config': '',
'Priority': '250',
}
with open(CONFIG_PATH, 'w') as f:
vdf.dump(config, f)
```
## Полный скилл
Вся процедура (shortcuts + Proton + artwork) описана в скилле `steam-emulator-shortcuts`. Смотреть там.
## Бэкап
```bash
cp ~/.steam/steam/userdata/*/config/shortcuts.vdf{,.bak}
```
Автоматический бэкап `shortcuts.vdf` делается ежедневно скриптом `backup-saves.sh` на HTPC, версии хранятся в `/run/media/bazzite/Data/backups/saves/shortcuts/` (последние 30 копий).
## Перезагрузка Steam
После записи VDF — перезапустить Steam, чтобы он подхватил изменения.
## Wide Steam Grid Posters — Порядок действий
**Перед остановкой Steam** — сначала скачать все постеры. Так как Steam не нужен для скачивания.
### Постеры для всех форматов
При добавлении новой не-Steam игры — сразу скачивай все 4 формата:
| Размер | Формат файла | Назначение |
|--------|-------------|------------|
| 920×430 | `{unsigned_appid}.png` | Wide — основная карточка в библиотеке |
| 600×900 | `{unsigned_appid}p.png` | Poster — вертикальный, при наведении |
| 1920×620 | `{unsigned_appid}_hero.png` | Hero — фон на странице игры |
| 1200×351 | `{unsigned_appid}_logo.png` | Логотип на hero |
**Unsigned appid** = `signed_appid & 0xFFFFFFFF`. Пример: `-1321720074``2973247222`.
→ Подробно: [[htpc-steam-nonsteam-shortcuts]]
### Процедура (как делал Whale)
1. **Найти постеры на SteamGridDB** — зайти на `https://www.steamgriddb.com/game/<ID>`, отфильтровать по 920×430.
- Для новых игр: поискать `<игра> site:steamgriddb.com`
- Wide grids часто меньше по количеству чем posters (600×900), их ищем в секции Grids → фильтр `Dimensions: 920×430`
2. **Получить прямую ссылку CDN** — thumbnails на странице grid'a ведут на `cdn2.steamgriddb.com/thumb/<hash>.jpg`, а полный файл лежит по `cdn2.steamgriddb.com/grid/<hash>.png`.
3. **Скачать локально:**
```bash
curl -s -o /tmp/<appid>.png "https://cdn2.steamgriddb.com/grid/<hash>.png"
```
4. **Закинуть на HTPC** через scp в `/tmp/`:
```bash
scp /tmp/<appid>.png bazzite@192.168.1.86:/tmp/<appid>.png
```
5. **Скопировать в grid-директорию Steam:**
```bash
ssh bazzite@192.168.1.86
cp /tmp/<appid>.png ~/.steam/steam/userdata/147839491/config/grid/<appid>.png
```
6. **Перезапустить Steam** (Steam перечитывает grid-файлы свежими при старте, но часто подхватывает и без перезапуска):
```bash
systemctl --user stop gamescope-session-plus@steam.service
systemctl --user start gamescope-session-plus@steam.service
```
### SteamGridDB ключ API
`5f0a7cb3366dede2c10860a95795ce60` — для программного доступа.