{"id":15888209,"url":"https://github.com/corecii/steam-binary-vdf-ts","last_synced_at":"2025-03-20T10:30:36.736Z","repository":{"id":42806037,"uuid":"270453635","full_name":"Corecii/steam-binary-vdf-ts","owner":"Corecii","description":"A module to read and write the binary vdf file format used by steam. For example: shortcuts.vdf.","archived":false,"fork":false,"pushed_at":"2022-03-26T20:59:03.000Z","size":91,"stargazers_count":26,"open_issues_count":6,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T05:55:04.873Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Corecii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-07T22:47:28.000Z","updated_at":"2025-01-22T17:19:31.000Z","dependencies_parsed_at":"2022-08-22T06:50:17.014Z","dependency_job_id":null,"html_url":"https://github.com/Corecii/steam-binary-vdf-ts","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corecii%2Fsteam-binary-vdf-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corecii%2Fsteam-binary-vdf-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corecii%2Fsteam-binary-vdf-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corecii%2Fsteam-binary-vdf-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Corecii","download_url":"https://codeload.github.com/Corecii/steam-binary-vdf-ts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244066184,"owners_count":20392406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-06T06:06:41.174Z","updated_at":"2025-03-20T10:30:36.496Z","avatar_url":"https://github.com/Corecii.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"`npm i --save steam-binary-vdf`\r\n\r\n# Steam Binary VDF\r\n\r\n`steam-binary-vdf` is a module for reading and writing the binary vdf file format used in files like `shortcuts.vdf`. This module also provides a utility function for calculating the `steam://rungameid/` url for a shortcut.\r\n\r\n## Exports\r\n\r\n```ts\r\nreadVdf(buffer: Buffer, offset?: number): Object\r\n```\r\nReads a vdf file from a buffer and returns an object with its contents.\r\nThis returns a \"plain\" object of `[key: string]: value` with the values from the vdf file.\r\n\r\n```ts\r\nwriteVdf(map: Object): Buffer\r\n```\r\nWrites an object to a new buffer then returns the buffer.\r\n\r\nVDF files values only accept:\r\n* **unsigned 32-bit numbers**: `writeVdf` will error if a number is outside of the range `0 \u003c= value \u003c= 4294967295`.\r\n* **strings without null chars `\\0`**: `writeVdf` will error if a string contains null chars. Remove, replace, or truncate your strings first. VDF files use null-terminated strings internally.\r\n* **Objects with string keys and accepted values**: `writeVdf` will error if a value does not match an accepted type.\r\n\r\n```ts\r\ngetShortcutHash(input: string): string\r\n```\r\nReturns the \"hash\" used by steam to represent non-steam shortcuts\r\nin the `steam://rungameid/` format. This uses code adapted from [Scott Rice's ICE program](https://github.com/scottrice/Ice).\r\n\r\n```ts\r\ngetShortcutUrl(appName: string, exe: string): string\r\n```\r\nReturns the shortcut url for a shortcut with the given name and target. The name is the `AppName` field and the target is the `exe` field from the shortcut entry in the shortcuts file.\r\n\r\nThis just returns `\"steam://rungameid/\" + getShortcutHash(exe + appName)`\r\n\r\n## Shortcuts.vdf example\r\n\r\n```ts\r\nimport { readVdf, writeVdf } from \"steam-binary-vdf\";\r\nimport fs from \"fs-extra\";\r\n\r\n// read the vdf\r\nconst inBuffer = await fs.readFile(\"C:\\\\Program Files (x86)\\\\Steam\\\\userdata\\\\USER_ID\\\\config\\\\shortcuts.vdf\")\r\n\r\nconst shortcuts = readVdf(inBuffer);\r\nconsole.log(shortcuts); // output below;\r\n\r\n// add to the vdf\r\nshortcuts.shortcuts['2'] = {\r\n  AppName: 'Game 3',\r\n  exe: 'D:\\\\Games\\\\Game.exe'\r\n};\r\n\r\nconst outBuffer = writeVdf(shortcuts);\r\n\r\nawait fs.writeFile(\"C:\\\\Program Files (x86)\\\\Steam\\\\userdata\\\\USER_ID\\\\config\\\\shortcuts.vdf\", outBuffer);\r\n```\r\n\r\nThis will produce something like...\r\n\r\n```js\r\n{\r\n  shortcuts: {\r\n    '0': {\r\n      AppName: 'Game 1',\r\n      exe: '\"C:\\\\Program Files\\\\Game 1\\\\Game.exe\"',\r\n      StartDir: '\"C:\\\\Program Files\\\\Game 1\"',\r\n      icon: '',\r\n      ShortcutPath: '',\r\n      LaunchOptions: '',\r\n      IsHidden: 0,\r\n      AllowDesktopConfig: 1,\r\n      AllowOverlay: 1,\r\n      openvr: 0,\r\n      Devkit: 0,\r\n      DevkitGameID: '',\r\n      LastPlayTime: 1527542942,\r\n      tags: {'0': 'some tag', '1': 'another tag'}\r\n    },\r\n    '1': {\r\n      AppName: 'Another Game',\r\n      exe: '\"C:\\\\Program Files\\\\Some Game 2\\\\AnyExe.exe\"',\r\n      StartDir: '\"C:\\\\Any Location\"',\r\n      icon: '',\r\n      ShortcutPath: '',\r\n      LaunchOptions: '',\r\n      IsHidden: 0,\r\n      AllowDesktopConfig: 1,\r\n      AllowOverlay: 1,\r\n      openvr: 0,\r\n      Devkit: 0,\r\n      DevkitGameID: '',\r\n      LastPlayTime: 1525830068,\r\n      tags: {}\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nNotable things about `shortcuts.vdf`:\r\n\r\n* The root of VDF files are maps of string keys to values. `shortcuts.vdf` puts all of the shortcuts in the `shortcuts` value under the root. The vdf file *can* include more values under the root but typically does not. You can set and save other values under the root and Steam will treat the file like normal after a restart, but won't necessarily keep the extra data.\r\n* `shortcuts` is a *map* with numbers as *string keys*. Using a proper key here doesn't actually matter: steam will fix all keys to a number-as-a-string on startup.\r\n* `tags` is map-as-a-list like `shortcuts`, but I couldn't get steam to use it so I couldn't test its behavior.\r\n* When steam starts, it reads and sanitizes `shortcuts.vdf`. This means:\r\n  * Any non-object values under `shortcuts` get discarded\r\n  * Any object values under `shortcuts` get converted into shortcut definitions. Unknown keys in the object are removed and any non-existent shortcut definition keys are added with their default values.\r\n  * Keys under `shortcuts` get converted to numbers-as-strings. For example, setting `shortcuts.a = {AppName: 'Test'}` in the above example would become `shortcuts['2']` or `['3']` depending on the contents.\r\n* `LastPlayTime` is a timestamp\r\n* Booleans are represented as numbers where 0 is false and 1 is true.\r\n* If `shortcuts.vdf` does not follow the binary vdf format, it is cleared and reset to an empty shortcuts vdf.\r\n\r\nThe default values for a shortcut definition are:\r\n```js\r\n{\r\n  AppName: '',\r\n  exe: '',\r\n  StartDir: '',\r\n  icon: '',\r\n  ShortcutPath: '',\r\n  LaunchOptions: '',\r\n  IsHidden: 0,\r\n  AllowDesktopConfig: 1,\r\n  AllowOverlay: 1,\r\n  openvr: 0,\r\n  Devkit: 0,\r\n  DevkitGameID: '',\r\n  LastPlayTime: 0,\r\n  tags: {}\r\n}\r\n```\r\n\r\n# Binary VDF Format\r\n\r\nThe binary vdf format is built around a few structures:\r\n* Null-terminated strings (here on called `String`)\r\n* 32-bit little-endian integers (here on called `Integer`)\r\n* Map (here on called `Map`)\r\n* 1-byte object type (here on called `MapItemType`)\r\n  * `0x00` represents a Map\r\n  * `0x01` represents a String\r\n  * `0x02` represents a Number\r\n  * `0x08` represents the end of a map\r\n\r\n`Map` is structured as reptitions of any of the following:\r\n* `MapItemType(0x01)` `String(name)` `String(value)`\r\n* `MapItemType(0x02)` `String(name)` `Integer(value)`\r\n* `MapItemType(0x00)` `String(name)` `Map(value)`\r\n* `MapItemType(0x08)`\r\n\r\nWhen a type of `0x08` is encountered, map reading stops.\r\n\r\nThe root of a binary vdf file is a `Map`.\r\n\r\n`steam-binary-vdf` reads `Integers` as unsigned integers. I haven't seen enough user-editable integers in vdf files to test if this is a correct representation of the data.\r\n\r\n`steam-binary-vdf` reads `Strings` as utf-8. The vdf format likely accepts any sequence of bytes for a string as long as it doesn't contain a null character `\\0`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorecii%2Fsteam-binary-vdf-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcorecii%2Fsteam-binary-vdf-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorecii%2Fsteam-binary-vdf-ts/lists"}