From 2978e464e810100824f596dd2b77c86993fa29d6 Mon Sep 17 00:00:00 2001 From: TheLazySquid <76746384+TheLazySquid@users.noreply.github.com> Date: Tue, 30 Dec 2025 15:50:46 -0500 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#74283=20[Gimlo?= =?UTF-8?q?ader]=20Update=20rewriter=20types=20by=20@TheLazySquid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- types/gimloader/gimloader-tests.ts | 29 +++++++++++++++++ types/gimloader/index.d.ts | 52 ++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/types/gimloader/gimloader-tests.ts b/types/gimloader/gimloader-tests.ts index 9529121f53dc0c..75a90278aaf592 100644 --- a/types/gimloader/gimloader-tests.ts +++ b/types/gimloader/gimloader-tests.ts @@ -1,3 +1,21 @@ +interface TestPlugin { + one: number; +} + +interface TestLib { + two: string; +} + +declare namespace Gimloader { + interface Plugins { + testPlugin: TestPlugin; + } + + interface Libraries { + testLib: TestLib; + } +} + GL; // $ExpectType typeof Api api; // $ExpectType Api @@ -25,6 +43,10 @@ GL.rewriter; // $ExpectType Readonly GL.storage; // $ExpectType Readonly GL.commands; // $ExpectType Readonly +api.plugin("testPlugin").one; // $ExpectType number +api.lib("testLib").two; // $ExpectType string +api.plugin("somethingElse"); // $ExpectType any + // @ts-expect-error GL.onStop; // @ts-expect-error @@ -49,6 +71,13 @@ api.net.onLoad((type, gamemode) => {}); api.net.modifyFetchRequest("/path/*/thing", (options) => null); api.net.modifyFetchRequest("/path/*/thing", (options) => options); api.net.modifyFetchResponse("/path/*/thing", (response) => response); +api.rewriter.runInScope("App", (code, evalCode) => evalCode("something")); +api.rewriter.exposeVar("App", { + check: "someString", + find: /,(.+)=>{/, + callback: (theVar) => {}, + multiple: false, +}); api.commands.addCommand({ text: "test", diff --git a/types/gimloader/index.d.ts b/types/gimloader/index.d.ts index ef11cdf4493855..009d2cf8955859 100644 --- a/types/gimloader/index.d.ts +++ b/types/gimloader/index.d.ts @@ -2305,7 +2305,7 @@ declare global { /** Gets the headers of a plugin, such as version, author, and description */ getHeaders(name: string): ScriptHeaders; /** Gets the exported values of a plugin, if it has been enabled */ - get(name: string): any; + get(name: T): Gimloader.Plugins[T]; /** * @deprecated Use {@link get} instead * @hidden @@ -2342,7 +2342,7 @@ declare global { /** Gets the headers of a library, such as version, author, and description */ getHeaders(name: string): ScriptHeaders; /** Gets the exported values of a library */ - get(name: string): any; + get(name: T): Gimloader.Libraries[T]; } class ScopedCommandsApi { @@ -2415,6 +2415,23 @@ declare global { createShared(id: string, value: any): string; /** Removes the shared value with a certain id created by {@link createShared} */ removeSharedById(id: string): void; + /** + * Runs code in the scope of modules when they are loaded, or when runInScope is called with them already loaded. + * Returning true from the callback will remove the hook. + */ + runInScope(prefix: string | boolean, callback: RunInScopeCallback): () => void; + /** A utility function that exposes a variable based on regex to get its name. */ + exposeVar(prefix: string | boolean, exposer: Exposer): () => void; + } + + // eslint-disable-next-line @typescript-eslint/no-invalid-void-type + type RunInScopeCallback = (code: string, run: (evalCode: string) => void) => true | void; + + interface Exposer { + check?: string; + find: RegExp; + callback: (val: any) => void; + multiple?: boolean; } class RewriterApi { @@ -2425,10 +2442,10 @@ declare global { * @param pluginName The name of the plugin creating the hook. * @param prefix Limits the hook to only running on scripts beginning with this prefix. * Passing `true` will only run on the index script, and passing `false` will run on all scripts. - * @param callback The function that will modify the code. Should return the modified code. Cannot have side effects. + * @param callback A function that will modify the code, which should return the modified code. */ - addParseHook(pluginName: string, prefix: string | boolean, callback: (code: string) => string): () => void; - /** Removes all hooks created by a certain plugin */ + addParseHook(pluginName: string, prefix: string | boolean, modifier: (code: string) => string): () => void; + /** Removes all parse hooks created by a certain plugin */ removeParseHooks(pluginName: string): void; /** * Creates a shared value that can be accessed from any script. @@ -2442,6 +2459,15 @@ declare global { removeShared(pluginName: string): void; /** Removes the shared value with a certain id created by {@link createShared} */ removeSharedById(pluginName: string, id: string): void; + /** + * Runs code in the scope of modules when they are loaded, or when runInScope is called with them already loaded. + * Returning true from the callback will remove the hook. + */ + runInScope(pluginName: string, prefix: string | boolean, callback: RunInScopeCallback): () => void; + /** Stops all hooks created by {@link runInScope} */ + removeRunInScope(pluginName: string): void; + /** A utility function that exposes a variable based on regex to get its name. */ + exposeVar(pluginName: string, prefix: string | boolean, exposer: Exposer): () => void; } class ScopedPatcherApi { @@ -2836,11 +2862,11 @@ declare global { /** Methods for getting info on libraries */ static libs: Readonly; /** Gets the exported values of a library */ - static lib: (name: string) => any; + static lib: (name: T) => Gimloader.Libraries[T]; /** Methods for getting info on plugins */ static plugins: Readonly; /** Gets the exported values of a plugin, if it has been enabled */ - static plugin: (name: string) => any; + static plugin: (name: T) => Gimloader.Plugins[T]; /** Gimkit's internal react instance */ static get React(): typeof import("react"); /** Gimkit's internal reactDom instance */ @@ -2909,11 +2935,11 @@ declare global { /** Methods for getting info on libraries */ libs: Readonly; /** Gets the exported values of a library */ - lib: (name: string) => any; + lib: (name: T) => Gimloader.Libraries[T]; /** Methods for getting info on plugins */ plugins: Readonly; /** Gets the exported values of a plugin, if it has been enabled */ - plugin: (name: string) => any; + plugin: (name: T) => Gimloader.Plugins[T]; /** Gimkit's internal react instance */ get React(): typeof import("react"); /** Gimkit's internal reactDom instance */ @@ -2935,6 +2961,14 @@ declare global { */ openSettingsMenu: (callback: () => void) => void; } + + interface Plugins { + [name: string]: any; + } + + interface Libraries { + [name: string]: any; + } } const api: Gimloader.Api; const GL: typeof Gimloader.Api; From 38486ef2d056059818ffef61b020063a7ebb98b3 Mon Sep 17 00:00:00 2001 From: Artur Klesun Date: Tue, 30 Dec 2025 23:10:26 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#74196=20[@type?= =?UTF-8?q?s/steam-user]=20Replace=20`any`=20type=20with=20actual=20object?= =?UTF-8?q?=20description=20in=20`AppInfo.appinfo`=20by=20@klesun-st?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Artur Klesun --- types/steam-user/index.d.ts | 518 ++++++++++++++++++++++- types/steam-user/steam-user-tests.ts | 610 ++++++++++++++++++++++++++- 2 files changed, 1126 insertions(+), 2 deletions(-) diff --git a/types/steam-user/index.d.ts b/types/steam-user/index.d.ts index 3073e6b4da8855..25fa553e36886f 100644 --- a/types/steam-user/index.d.ts +++ b/types/steam-user/index.d.ts @@ -1158,7 +1158,7 @@ declare namespace SteamUser { export interface AppInfo { changenumber: number; missingToken: boolean; - appinfo: any; // too complex to describe + appinfo: AppInfoContent; } export interface PackageInfo { @@ -1461,6 +1461,522 @@ declare namespace SteamUser { phone_number_hint?: string; [key: string]: any; } + + interface SteamDeckCompatibilityTest { + display: "4" | "1" | `${number}`; + token: "#SteamDeckVerified_TestResult_DefaultControllerConfigFullyFunctional" | string; + } + + interface SteamDeckCompatibilityConfiguration { + supported_input: "gamepad" | string; + requires_manual_keyboard_invoke: "0" | `${number}`; + requires_non_controller_launcher_nav: "0" | `${number}`; + primary_player_is_controller_slot_0: "1" | `${number}`; + non_deck_display_glyphs: "0" | `${number}`; + small_text: "0" | `${number}`; + requires_internet_for_setup: "0" | `${number}`; + requires_internet_for_singleplayer: "0" | `${number}`; + recommended_runtime: "native" | string; + requires_h264: "0" | `${number}`; + requires_voice_files: "0" | `${number}`; + gamescope_frame_limiter_not_supported: "0" | `${number}`; + hdr_support: "0" | `${number}`; + } + + interface SteamDeckCompatibility { + category: "3" | `${number}`; + steamos_compatibility: "2" | `${number}`; + test_timestamp: "1700265600" | `${number}`; + tested_build_id: "12705647" | `${number}`; + tests: Record<`${number}`, SteamDeckCompatibilityTest>; + steamos_tests: Record<`${number}`, SteamDeckCompatibilityTest>; + configuration: SteamDeckCompatibilityConfiguration; + } + + interface SupportedLanguageData { + supported: "true" | string; + full_audio?: "true" | string; + subtitles?: "true" | string; + } + + interface LibraryAssets { + library_capsule: "en" | string; + library_hero: "en" | string; + library_logo: "en" | string; + library_hero_blur?: "en" | string; + library_header?: "en" | string; + logo_position: { + pinned_position: "BottomCenter" | string; + width_pct: "77.01516064953753" | `${number}`; + height_pct: "43.685387882494695" | `${number}`; + }; + } + + interface LibraryAssetImage { + image: Record<"schinese" | "english" | string, "library_hero.jpg" | string>; + image2x: Record<"schinese" | "english" | string, "library_hero.jpg" | string>; + } + + interface LibraryAssetsFull { + library_capsule: LibraryAssetImage; + library_hero: LibraryAssetImage; + library_hero_blur?: { + image: { + english: "ac24a584893d024ab1b0fcf40d0a0b82a90cdb7e/library_hero_blur.jpg" | string; + }; + }; + library_logo: LibraryAssetImage & { + logo_position: { + pinned_position: "BottomCenter" | string; + width_pct: "77.01516064953753" | `${number}`; + height_pct: "43.685387882494695" | `${number}`; + }; + }; + library_header?: LibraryAssetImage; + } + + type Associations = Record< + `${number}`, + { + type: "developer" | "publisher" | "franchise"; + /** note: "Anonymous" can be repeated multiple times, likely a special keyword */ + name: "Anonymous" | "Valve" | "Half-Life" | string; + } + >; + + interface AppInfoCommonBase { + name: "Source Dedicated Server" | "Half-Life" | string; + type: string; + gameid: "210" | "70" | `${number}`; + clienttga?: "cf1ac7ec6ac21d099a2fe81bf269bfd50a550a0c" | "b3f33e2fd5e6eee2f2f27fe5b10b1c78683a3363" | string; + clienticon?: "4f3ee44d3e136ee3c56d30318b4ae386e64b1b40" | string; + icon?: "7600c38504523ef3f10d6fe50d20b065bdef192f" | string; + logo?: "c2ea07874fb1a776e4c5bfc659e5f296d656777d"; + small_capsule?: Record< + "english" | string, + "25bee0c9572a4f0dc4de6c773c54d067a4204760/capsule_231x87.jpg" | string + >; + header_image?: Record<"english" | string, "header.jpg" | string>; + community_hub_visible?: "1" | `${number}`; + releasestate?: "prerelease" | string; + aicontenttype?: "1" | `${number}`; + osarch?: "" | string; + osextended?: "" | string; + exfgls?: "8" | `${number}`; + oslist?: "windows" | string; + associations?: Associations; + store_tags?: Record<`${number}`, `${number}`>; + } + + type AppInfoCommonGame = AppInfoCommonBase & { + type: "game" | "Game"; + logo_small: "698efe72e4316c1cde3c4ce2d6ce229be50e698c" | string; + metacritic_url: "pc/halflife" | string; + linuxclienticon: "87bda297bfca8fa26490f4a35d634d978c7da319" | string; + clienticns: "34953436dec82b4e45699ac618cf4c2015a12005" | string; + content_descriptors: Record<`${number}`, `${number}`>; + steam_deck_compatibility: SteamDeckCompatibility; + metacritic_name: "Half-Life" | string; + controllertagwizard: "1" | `${number}`; + controller_support: "full" | string; + library_assets: LibraryAssets; + library_assets_full: LibraryAssetsFull; + store_asset_mtime: "1745368459" | `${number}`; + associations: Associations; + primary_genre: "1" | `${number}`; + genres: Record<`${number}`, `${number}`>; + category: Record<`category_${number}`, `${number}`>; + supported_languages: Record<"english" | "french" | "schinese" | string, SupportedLanguageData>; + steam_release_date: "911462400" | `${number}`; + metacritic_score: "96" | `${number}`; + metacritic_fullurl: "https://www.metacritic.com/game/pc/half-life?ftag=MCD-06-10aaa1f" | string; + content_descriptors_including_dlc: Record<`${number}`, `${number}`>; + review_score: `${number}`; + review_percentage: `${number}`; + }; + + interface DepotManifest { + gid: "724247850320422500" | `${number}`; + size: "49814373" | `${number}`; + download: "19297632" | `${number}`; + } + + interface AppInfoDepot { + config?: { + oslist?: "windows" | string; + language?: "" | "french" | string; + }; + systemdefined?: "1"; + manifests?: { + public: DepotManifest; + steam_legacy?: DepotManifest; + beta?: DepotManifest; + }; + } + + interface SaveFile { + root: "gameinstall" | string; + path: "valve/SAVE" | "valve" | string; + pattern: "*.*" | "*.cfg" | string; + recursive?: "1"; + platforms: Record<`${number}`, "all" | string>; + } + + interface Launch { + executable: "hl.exe" | "hl.sh" | string; + type?: "default" | string; + arguments?: "-steam" | string; + description?: string; + vacmodulefilename?: "resource\\sourceinit.dat" | "resource\\sourceinit_macos.dat" | string; + workingdir?: ".\\"; + config?: { + oslist: "windows" | "macos" | "linux" | string; + osarch?: "64"; + }; + } + + interface AppInfoExtendedBase { + developer: "Valve" | "" | string; + gamedir: "valve" | "ValveTestApp90" | string; + homepage: "http://www.half-life.com/" | "" | string; + icon: "steam/games/icon_hl" | "" | string; + } + + type AppInfoExtendedTool = AppInfoExtendedBase & { + checkpkgstate: "1"; + noservers: "0"; + sourcegame: "1"; + state: "eStateComingSoonNoPreload"; + visibleonlywhensubscribed: "1"; + }; + + type AppInfoExtendedGame = AppInfoExtendedBase & { + icon2: "steam/games/icon_hl_dull" | string; + minclientversion: "1000000" | `${number}`; + order: "15" | `${number}`; + primarycache: "1" | `${number}`; + serverbrowsername: "Half-Life" | string; + vacmacmodulecache: "160" | `${number}`; + vacmodulecache: "202" | `${number}`; + vacmodulefilename: "sourceinit.dat" | string; + developer_url: "http://www.valvesoftware.com" | string; + publisher: "Valve" | string; + aliases: "hl1" | string; + listofdlc: "632440" | `${number}`; + gamemanualurl?: "https://store.steampowered.com/manual/2521400/" | string; + }; + + interface AppInfoExtendedGameAnon { + "developer": "Anonymous"; + "publisher": "Anonymous"; + "gamemanualurl": "https://store.steampowered.com/manual/2521400/" | string; + } + + interface AppInfoConfigBase { + contenttype?: "3" | `${number}`; + installdir: "Half-Life" | string; + shortname?: "5004Media" | string; + launch?: Record<`${number}` | "main" | string, Launch>; + installscriptsignature?: + | "072d84fde2ef0ae5baf2e9dc1178cfcf141cba641b98854cb3ebe850f01729917320c9220d55f15f72f92a2a9d6f16a181050b8a3a4be357fdb238c7da4e35bb840c4a16b3e95a39e0115aff6d833a959ad1228d72fe2307a4ea49579e53c9fca6fbcc2162524f17602c60fef0b3b2a0a3884fecab217320d74083530c2cc01c" + | string; + installscriptoverride?: "1" | `${number}`; + externalregistrationurl?: Record<"english" | string, "http://www.arma2.com" | string>; + steamdecktouchscreen?: "1" | `${number}`; + } + + type AppInfoConfig = AppInfoConfigBase & { + systemprofile: "1" | `${number}`; + convertgcfs: "1" | `${number}`; + steamcontrollertouchtemplateindex: "1" | `${number}`; + steamcontrollertouchconfigdetails: Record< + "2063295774" | `${number}`, + { + controller_type: "controller_mobile_touch" | string; + enabled_branches: "default" | string; + use_action_block: "false" | string; + } + >; + steamcontrollertemplateindex: "13" | `${number}`; + uselaunchcommandline: "1" | `${number}`; + steaminputmanifestpath: "valve\\controller_configs\\hl1_manifest.vdf" | string; + steamconfigurator3rdpartynative: "65531" | `${number}`; + }; + + interface AppInfoContentUnpublished { + appid: `${number}`; + public_only: "1"; + common?: never; + } + + /** + * this type definition was based on a specific data sample - there may, possibly, + * be other fields in this structure, and some of the fields may, possibly, be optional + */ + export interface AppInfoContentGame { + appid: `${number}`; + public_only?: "1" | `${number}`; + common: + | AppInfoCommonGame + | (AppInfoCommonBase & { + type: "game" | "Game"; + }); + extended?: AppInfoExtendedGame | AppInfoExtendedGameAnon; + config?: AppInfoConfig | AppInfoConfigBase; + depots?: Record<`${number}`, AppInfoDepot> & { + branches?: Branches; + }; + ufs?: { + quota: "104857600" | `${number}`; + maxnumfiles: "500" | `${number}`; + savefiles: Record<`${number}`, SaveFile>; + }; + } + + interface AppInfoContentConfig { + appid: "8" | `${number}`; + common: AppInfoCommonBase & { + type: "Config" | "config"; + }; + config?: AppInfoConfigBase; + } + + interface AppInfoContentTool { + appid: "90" | `${number}`; + common: AppInfoCommonBase & { + type: "Tool"; + }; + extended: AppInfoExtendedTool; + config: AppInfoConfigBase; + depots: Record<`${number}`, AppInfoDepot> & { + overridescddb: "1" | `${number}`; + branches: { + public: DepotManifest; + steam_legacy: DepotManifest; + beta: DepotManifest; + }; + privatebranches: "1" | `${number}`; + }; + } + + interface AppInfoContentDlc { + appid: "4079770" | `${number}`; + common: AppInfoCommonBase & { + type: "DLC" | "dlc"; + parent: "2853730" | `${number}`; + }; + extended?: { + dlcforappid: "2853730" | string; + mustownapptopurchase: "2853730" | string; + legacykeyproofofpurchaseticket: "1" | `${number}`; + legacykeylinkedexternally: "1" | `${number}`; + legacykeyregistrationmethod: "api" | string; + proofofpurchaseticketrevision: "2" | `${number}`; + }; + } + + interface MusicTrack { + discnumber: "1" | `${number}`; + tracknumber: "1" | `${number}`; + originalname: "白の語り部" | string; + m: "1" | `${number}`; + s: "32" | `${number}`; + internationalname: "Storyteller in White" | string; + languagecode: "jp" | string; + isrc: "JPA232500241" | string; + } + + interface Branches { + public: BuildBranch & { + timeupdated: "1761703865" | `${number}`; + }; + } + + interface Depots { + [k: "3592811" | `${number}`]: AppInfoDepot; + baselanguages?: "english" | string; + branches: Branches; + } + + interface AppInfoContentMusic { + appid: "4044730" | `${number}`; + common: AppInfoCommonBase & { + type: "Music"; + parent: "3837380" | `${number}`; + name_localized: { + japanese: "魔女ガミ 音楽集 ー ディレクターズ セレクション ー" | string; + }; + }; + extended: { + musicalbumforappid: "3837380" | `${number}`; + activationonlydlc: "1" | `${number}`; + }; + config: AppInfoConfigBase; + depots: Depots; + albummetadata: { + metadata: { + artist: Record<"english" | "french" | string, "III" | "" | string>; + composer: Record<"english" | "french" | string, "山田 一法、武田 葵、佐藤 巧、酒井 祐輔" | "" | string>; + label: Record<"english" | "french" | string, "インティ・クリエイツ" | "" | string>; + othercredits: Record< + "english" | "french" | string, + | "編曲、演奏: 梅垣 ルナ\r\nミックス: 栗原 務\r\n\r\nプロデュース、監修: 山田 一法\r\nマスタリング: 川上 領" + | "" + | string + >; + }; + tracks: Record<`${number}`, MusicTrack>; + cdn_assets: { + album_cover: "d847c0f58c835c719746938fdebda327a7e1a854" | string; + }; + }; + } + + interface AppInfoContentDemo { + appid: "3592810" | `${number}`; + common: AppInfoCommonBase & { + type: "Demo"; + parent: "2492990" | `${number}`; + }; + config: AppInfoConfigBase; + depots: Depots; + } + + interface BuildBranch { + buildid: "250795" | `${number}`; + } + + interface AppInfoContentMedia { + appid: "5004" | `${number}`; + common: AppInfoCommonBase & { + type: "media"; + freeondemand: "1" | `${number}`; + }; + extended: AppInfoExtendedBase & { + ismediafile: "1" | `${number}`; + mediafiletype: "Movie" | string; + order: "1" | `${number}`; + primarycache: "5004" | `${number}`; + }; + config: AppInfoConfigBase; + depots: { + [k: `${number}`]: AppInfoDepot; + overridescddb: "1"; + branches: { + public: BuildBranch; + }; + }; + } + + interface AppInfoContentGuide { + appid: "22800" | `${number}`; + common: AppInfoCommonBase & { + type: "guide"; + }; + extended: AppInfoExtendedBase & { + guideurl: "http://steam.primagames.com/?CDKey=%cdkey%" | string; + legacykeyregistrationmethod: "registry" | string; + legacykeyregistrylocation: "HKEY_CURRENT_USER\\Software\\Valve\\TestApp22800\\SteamKey" | string; + noservers: "1" | `${number}`; + order: "1" | `${number}`; + primarycache: "7" | `${number}`; + serverbrowsername: "" | string; + state: "eStateAvailable" | string; + visibleonlywhensubscribed: "1" | `${number}`; + }; + } + + interface AppInfoContentBeta { + appid: "219540" | `${number}`; + common: AppInfoCommonBase & { + type: "Beta"; + logo_small: "c2ea07874fb1a776e4c5bfc659e5f296d656777d_thumb" | string; + parent: "33930" | `${number}`; + }; + extended: AppInfoExtendedBase & { + noservers: "0" | `${number}`; + sourcegame: "1" | `${number}`; + state: "eStateAvailable" | string; + thirdpartycdkey: "1" | `${number}`; + visibleonlywhensubscribed: "1" | `${number}`; + no_revenue_accumulation: "1" | `${number}`; + }; + config: AppInfoConfigBase; + install: Record; + depots: { + [k: "219541" | `${number}`]: { + systemdefined: "1"; + manifests: { + public: DepotManifest; + beta108074: DepotManifest; + beta112555: DepotManifest; + test: DepotManifest; + }; + }; + preloadonly: "1" | `${number}`; + overridescddb: "1" | `${number}`; + branches: { + public: BuildBranch; + beta108074: BuildBranch; + beta112555: BuildBranch; + test: BuildBranch; + }; + }; + } + + interface AppInfoContentApplication { + appid: "227980" | `${number}`; + common: AppInfoCommonBase & { + type: "Application"; + }; + extended: AppInfoExtendedBase & { + checkpkgstate: "1" | `${number}`; + disableoverlay: "1" | `${number}`; + noservers: "0" | `${number}`; + sourcegame: "1" | `${number}`; + state: "eStateComingSoonNoPreload"; + visibleonlywhensubscribed: "1" | `${number}`; + }; + config: AppInfoConfigBase; + depots: { + [k: "227241" | `${number}`]: { + systemdefined: "1" | `${number}`; + config: { + language: "english"; + oslist: "windows"; + }; + depotfromapp: "227240" | `${number}`; + sharedinstall: "2" | `${number}`; + }; + overridescddb: "1" | `${number}`; + }; + } + + interface AppInfoContentVideo { + appid: "373022" | `${number}`; + common: AppInfoCommonBase & { + type: "Video"; + parent: "373020" | `${number}`; + }; + config: { + videoid: "7527155574822378568" | string; + }; + } + + export type AppInfoContent = + | AppInfoContentUnpublished + | AppInfoContentGame + | AppInfoContentConfig + | AppInfoContentTool + | AppInfoContentApplication + | AppInfoContentGuide + | AppInfoContentDlc + | AppInfoContentBeta + | AppInfoContentDemo + | AppInfoContentMedia + | AppInfoContentVideo + | AppInfoContentMusic; + // #endregion "Response Interfaces" // #region "ENUMS" diff --git a/types/steam-user/steam-user-tests.ts b/types/steam-user/steam-user-tests.ts index 6c2c6745e9cd88..b4e71721906919 100644 --- a/types/steam-user/steam-user-tests.ts +++ b/types/steam-user/steam-user-tests.ts @@ -1,5 +1,6 @@ import SteamUser = require("steam-user"); import SteamID = require("steamid"); +import { AppInfoContent } from "steam-user"; console.log(SteamUser.formatCurrency(12.34, SteamUser.ECurrencyCode.USD)); console.log(SteamUser.formatCurrency(12345, SteamUser.ECurrencyCode.JPY)); @@ -94,7 +95,29 @@ user.getProductChanges(2) user.getProductInfo([730], [420]) .then((response: SteamUser.ProductInfo) => { - // do something with response + // $ExpectType AppInfoContent + response.apps[0].appinfo; + const appinfo: AppInfoContent = response.apps[0].appinfo; + if (!appinfo.common) { + return; + } + if (appinfo.common.associations) { + void appinfo.common.associations["0"].name; + } + if ( + "extended" in appinfo + && appinfo.extended + && "developer" in appinfo.extended + ) { + void appinfo.extended.developer; + } + if ( + "config" in appinfo + && appinfo.config + && "installdir" in appinfo.config + ) { + void appinfo.config.installdir; + } }) .catch(err => console.error(err)); @@ -352,3 +375,588 @@ user.on("packageUpdate", (packageid: number, data: SteamUser.PackageInfo) => { // $ExpectType PackageInfo data; }); + +const DLC_EXAMPLE: AppInfoContent = { + "appid": "4079770", + "common": { + "name": "Skull & Bones - Seasonal Boatload Bundle Y2S3 Ubisoft Activation", + "type": "DLC", + "parent": "2853730", + "releasestate": "released", + "oslist": "windows", + "osarch": "64", + "osextended": "", + "gameid": "4079770", + "exfgls": "9", + }, + "extended": { + "dlcforappid": "2853730", + "mustownapptopurchase": "2853730", + "legacykeyproofofpurchaseticket": "1", + "legacykeylinkedexternally": "1", + "legacykeyregistrationmethod": "api", + "proofofpurchaseticketrevision": "2", + }, +}; + +const GAME_WITHOUT_EXTENSION_EXAMPLE: AppInfoContent = { + "appid": "3822170", + "public_only": "1", + "common": { + "name": "Mythical Haven", + "type": "Game", + "releasestate": "prerelease", + "oslist": "windows,linux", + "osarch": "", + "osextended": "", + "icon": "382426adc9164d18f252372d6e3f1863231128bc", + "clienttga": "068c5e7b9badc6e501553b8a8ca0d50f457c4562", + "clienticon": "5a5f3ca693e70b6f09053cc9d4acfd26177816a4", + "community_hub_visible": "1", + "gameid": "3822170", + "exfgls": "8", + "store_tags": { + "0": "597", + "1": "122", + }, + }, +}; + +const DEMO_EXAMPLE: AppInfoContent = { + "appid": "3592810", + "common": { + "name": "LOCURA Demo", + "type": "Demo", + "parent": "2492990", + "clienttga": "57446c0b1de50d238a53901c7a525d9cee8af7c4", + "clienticon": "4f3ee44d3e136ee3c56d30318b4ae386e64b1b40", + "oslist": "windows", + "osarch": "", + "osextended": "", + "icon": "7600c38504523ef3f10d6fe50d20b065bdef192f", + "releasestate": "released", + "gameid": "3592810", + "exfgls": "6", + }, + "config": { + "installdir": "LOCURA Demo", + "launch": { + "0": { + "executable": "Locura_demo.exe", + "type": "default", + "config": { + "oslist": "windows", + }, + }, + }, + }, + "depots": { + "3592811": { + "config": { + "oslist": "windows", + }, + "manifests": { + "public": { + "gid": "228799882111373695", + "size": "11798240078", + "download": "10862096800", + }, + }, + }, + "baselanguages": "english", + "branches": { + "public": { + "buildid": "20162272", + "timeupdated": "1759341545", + }, + }, + }, +}; + +const MEDIA_EXAMPLE: AppInfoContent = { + "appid": "5004", + "common": { + "clienttga": "e9722032ee5aa7bccb26cfdda0bb1b263cf8854d", + "name": "Alpha Prime Trailer 2", + "type": "media", + "freeondemand": "1", + "gameid": "5004", + }, + "extended": { + "developer": "Black Element Software", + "gamedir": "seet", + "homepage": "http://www.alpha-prime.com/", + "icon": "steam/games/icon_movie", + "ismediafile": "1", + "mediafiletype": "Movie", + "order": "1", + "primarycache": "5004", + }, + "config": { + "shortname": "5004Media", + "installdir": "Alpha Prime Trailer 2", + "contenttype": "3", + "launch": { + "main": { + "executable": "smp.exe", + "arguments": "/redirect steam://advertise/2590 ap_trailer.wmv", + "description": "Alpha Prime Trailer 2", + }, + }, + }, + "depots": { + "910": { + "systemdefined": "1", + "manifests": { + "public": { + "gid": "1332084816209327708", + "size": "266240", + "download": "0", + }, + }, + }, + "5004": { + "systemdefined": "1", + "manifests": { + "public": { + "gid": "4121846428408586738", + "size": "94262425", + "download": "0", + }, + }, + }, + "overridescddb": "1", + "branches": { + "public": { + "buildid": "250795", + }, + }, + }, +}; + +const TEST_DLC_EXAMPLE: AppInfoContent = { + "appid": "20004", + "common": { + "type": "dlc", + "parent": "20000", + "name": "ValveTestApp20004", + "gameid": "20004", + }, +}; + +const GUIDE_EXAMPLE: AppInfoContent = { + "appid": "22800", + "common": { + "name": "Far Cry 2: Prima Official eGuide", + "type": "guide", + "gameid": "22800", + }, + "extended": { + "developer": "", + "gamedir": "Far Cry 2 Prima Official Strategy Guide", + "guideurl": "http://steam.primagames.com/?CDKey=%cdkey%", + "homepage": "", + "icon": "", + "legacykeyregistrationmethod": "registry", + "legacykeyregistrylocation": "HKEY_CURRENT_USER\\Software\\Valve\\TestApp22800\\SteamKey", + "noservers": "1", + "order": "1", + "primarycache": "7", + "serverbrowsername": "", + "state": "eStateAvailable", + "visibleonlywhensubscribed": "1", + }, +}; + +const CONFIG_EXAMPLE: AppInfoContent = { + "appid": "203230", + "common": { + "name": "Risen 2 Continued", + "type": "config", + "gameid": "203230", + }, + "config": { + "contenttype": "3", + "installdir": "Risen 2", + }, +}; + +const BETA_EXAMPLE: AppInfoContent = { + "appid": "219540", + "common": { + "name": "Arma 2: Operation Arrowhead Beta (Obsolete)", + "type": "Beta", + "logo": "c2ea07874fb1a776e4c5bfc659e5f296d656777d", + "logo_small": "c2ea07874fb1a776e4c5bfc659e5f296d656777d_thumb", + "clienticon": "46fbb4263cc8ab442cd939c5434d05b49d9d945f", + "clienttga": "66c958a4ce9cb6a72409ab7c8772b40ba3cd24ee", + "icon": "32431d84014bf4652181f45bc7c06f1ca3f34363", + "parent": "33930", + "community_hub_visible": "1", + "gameid": "219540", + "exfgls": "6", + }, + "extended": { + "developer": "", + "gamedir": "ValveTestApp219540", + "homepage": "", + "icon": "", + "noservers": "0", + "sourcegame": "1", + "state": "eStateAvailable", + "thirdpartycdkey": "1", + "visibleonlywhensubscribed": "1", + "no_revenue_accumulation": "1", + }, + "config": { + "contenttype": "3", + "installdir": "arma 2 operation arrowhead", + "launch": { + "0": { + "executable": "Expansion\\beta\\Arma2OA.exe", + "arguments": "-beta=Expansion\\beta;Expansion\\beta\\Expansion", + "description": "Launch Beta", + "workingdir": ".\\", + }, + }, + "installscriptsignature": + "072d84fde2ef0ae5baf2e9dc1178cfcf141cba641b98854cb3ebe850f01729917320c9220d55f15f72f92a2a9d6f16a181050b8a3a4be357fdb238c7da4e35bb840c4a16b3e95a39e0115aff6d833a959ad1228d72fe2307a4ea49579e53c9fca6fbcc2162524f17602c60fef0b3b2a0a3884fecab217320d74083530c2cc01c", + "installscriptoverride": "1", + "externalregistrationurl": { + "english": "http://www.arma2.com", + }, + }, + "install": { + "registry if not present": {}, + "registry": {}, + "run process": { + "battleyeoabeta": { + "hasrunkey": "HKEY_LOCAL_MACHINE\\Software\\Valve\\Steam\\Apps\\219540", + "description": "BattlEye Anti-Cheat software for ARMA 2 OA beta", + "process 1": "%INSTALLDIR%\\expansion\\beta\\setup_BattlEyeARMA2OA.exe", + "ignoreexitcode": "0", + "nocleanup": "0", + "minimumhasrunvalue": "2", + "ascurrentuser": "0", + }, + }, + "arma 2 cd key": { + "registrypath": "HKEY_LOCAL_MACHINE\\SOFTWARE\\Bohemia Interactive Studio\\ArmA 2 OA\\KEY", + }, + "ea oreg": { + "string": { + "english": { + "url": "http://www.arma2.com", + }, + }, + }, + }, + "depots": { + "219541": { + "systemdefined": "1", + "manifests": { + "public": { + "gid": "6550263247666884023", + "size": "52543197", + "download": "0", + }, + "beta108074": { + "gid": "7888478692897229357", + "size": "40378810", + "download": "0", + }, + "beta112555": { + "gid": "3651664637375018602", + "size": "40379023", + "download": "0", + }, + "test": { + "gid": "6550263247666884023", + "size": "52543197", + "download": "0", + }, + }, + }, + "preloadonly": "1", + "overridescddb": "1", + "branches": { + "public": { + "buildid": "238935", + }, + "beta108074": { + "buildid": "93738", + }, + "beta112555": { + "buildid": "145144", + }, + "test": { + "buildid": "238935", + }, + }, + }, +}; + +const APPLICATION_EXAMPLE: AppInfoContent = { + "appid": "227980", + "common": { + "name": "Construct 2 Personal", + "type": "Application", + "icon": "fd7e273e97b6ec0a0102bf5fe6768d58317cfabb", + "clienttga": "74746519eca10cd477396d1ed44aa2475ee09931", + "clienticon": "c142f28be4fd1fae021a7e5233a7b765b56f1fa9", + "oslist": "windows", + "community_hub_visible": "1", + "gameid": "227980", + "exfgls": "6", + }, + "extended": { + "checkpkgstate": "1", + "developer": "", + "disableoverlay": "1", + "gamedir": "ValveTestApp227980", + "homepage": "", + "icon": "", + "noservers": "0", + "sourcegame": "1", + "state": "eStateComingSoonNoPreload", + "visibleonlywhensubscribed": "1", + }, + "config": { + "contenttype": "3", + "installdir": "Construct2", + "launch": { + "0": { + "executable": "Construct2.exe", + "description": "Launch Construct 2", + "config": { + "oslist": "windows", + }, + }, + }, + }, + "depots": { + "227241": { + "systemdefined": "1", + "config": { + "language": "english", + "oslist": "windows", + }, + "depotfromapp": "227240", + "sharedinstall": "2", + }, + "overridescddb": "1", + }, +}; + +const VIDEO_EXAMPLE: AppInfoContent = { + "appid": "373022", + "common": { + "name": "Blender: 1.3 UI Basics - Layout Customization", + "type": "Video", + "parent": "373020", + "oslist": "windows,macos,linux", + "releasestate": "released", + "community_hub_visible": "1", + "gameid": "373022", + "exfgls": "6", + }, + "config": { + "videoid": "7527155574822378568", + }, +}; + +const GAME_WITH_ANON_ASSOC_EXAMPLE: AppInfoContent = { + "appid": "2521400", + "common": { + "name": "愚人船 NARRENSCHIFF", + "type": "Game", + "oslist": "windows", + "osarch": "", + "osextended": "", + "icon": "69484a9048401fa508f1c52da613182bac133b0c", + "clienttga": "78925b4d8a3a0200a1390e9a36b9baf9236b96cd", + "clienticon": "12e37af555d834003b0e966889da9f17914e3c5e", + "releasestate": "released", + "content_descriptors": { + "0": "1", + "1": "5", + }, + "aicontenttype": "1", + "controllertagwizard": "1", + "small_capsule": { + "schinese": "capsule_231x87_schinese.jpg", + "english": "7eec28c94d470fbd1244f016f60d62adf7ebc238/capsule_231x87.jpg", + }, + "header_image": { + "english": "23311545184bc42e54d4317e96d9fa7af885a089/header.jpg", + }, + "library_assets": { + "library_capsule": "zh-cn,en", + "library_hero": "en", + "library_hero_blur": "en", + "library_logo": "zh-cn,en", + "library_header": "en", + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "50", + "height_pct": "50", + }, + }, + "library_assets_full": { + "library_capsule": { + "image": { + "schinese": "library_600x900_schinese.jpg", + "english": "1a41e429f8a9d1ced4d1d694f8be40a644a9035b/library_capsule.jpg", + }, + "image2x": { + "schinese": "library_600x900_schinese_2x.jpg", + "english": "1a41e429f8a9d1ced4d1d694f8be40a644a9035b/library_capsule_2x.jpg", + }, + }, + "library_hero": { + "image": { + "english": "ac24a584893d024ab1b0fcf40d0a0b82a90cdb7e/library_hero.jpg", + }, + "image2x": { + "english": "ac24a584893d024ab1b0fcf40d0a0b82a90cdb7e/library_hero_2x.jpg", + }, + }, + "library_hero_blur": { + "image": { + "english": "ac24a584893d024ab1b0fcf40d0a0b82a90cdb7e/library_hero_blur.jpg", + }, + }, + "library_logo": { + "image": { + "schinese": "logo_schinese.png", + "english": "644a8dfb21c4fdb1524ddfe6af9627e40cfb7eb6/logo.png", + }, + "image2x": { + "schinese": "logo_schinese_2x.png", + "english": "644a8dfb21c4fdb1524ddfe6af9627e40cfb7eb6/logo_2x.png", + }, + "logo_position": { + "pinned_position": "CenterCenter", + "width_pct": "50", + "height_pct": "50", + }, + }, + "library_header": { + "image": { + "english": "23311545184bc42e54d4317e96d9fa7af885a089/library_header.jpg", + }, + "image2x": { + "english": "23311545184bc42e54d4317e96d9fa7af885a089/library_header_2x.jpg", + }, + }, + }, + "store_asset_mtime": "1759495332", + "associations": { + "0": { + "type": "developer", + "name": "Anonymous", + }, + "1": { + "type": "developer", + "name": "Anonymous", + }, + "2": { + "type": "publisher", + "name": "Anonymous", + }, + "3": { + "type": "publisher", + "name": "Anonymous", + }, + }, + "primary_genre": "23", + "genres": { + "0": "25", + "1": "4", + "2": "23", + "3": "3", + "4": "70", + }, + "category": { + "category_2": "1", + "category_62": "1", + }, + "supported_languages": { + "schinese": { + "supported": "true", + "subtitles": "true", + }, + }, + "community_hub_visible": "1", + "gameid": "2521400", + "content_descriptors_including_dlc": { + "0": "1", + "1": "5", + }, + "store_tags": { + "0": "122", + "1": "1664", + "2": "3871", + "3": "44868", + "4": "1721", + "5": "597", + "6": "3964", + "7": "1742", + "8": "11014", + "9": "21", + "10": "3942", + "11": "5984", + "12": "7743", + "13": "4004", + "14": "1673", + "15": "4182", + "16": "31275", + "17": "492", + "18": "493", + }, + "review_score": "8", + "review_percentage": "95", + }, + "extended": { + "developer": "Anonymous", + "publisher": "Anonymous", + "gamemanualurl": "https://store.steampowered.com/manual/2521400/", + }, + "config": { + "installdir": "愚人船 NARRENSCHIFF", + "launch": { + "0": { + "executable": "Game.exe", + "arguments": "--in-process-gpu", + "type": "default", + "config": { + "oslist": "windows", + "osarch": "64", + }, + }, + }, + "steamdecktouchscreen": "1", + }, + "depots": { + "2521401": { + "manifests": { + "public": { + "gid": "6981023562958172906", + "size": "860631256", + "download": "571884368", + }, + }, + }, + "2521402": { + "config": { + "oslist": "linux", + }, + }, + "branches": { + "public": { + "buildid": "20242077", + "timeupdated": "1759507951", + }, + }, + }, +};