diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 939490a2..e788bee0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,7 @@ on: push: branches: [main] pull_request: + workflow_dispatch: env: DEBUG: "napi:*" diff --git a/client.d.ts b/client.d.ts index d27c7334..a861e161 100644 --- a/client.d.ts +++ b/client.d.ts @@ -262,8 +262,26 @@ export declare namespace overlay { export function activateToStore(appId: number, flag: StoreFlag): void } export declare namespace screenshots { - /** Triggers the Steam overlay to take a screenshot. */ + /** + * Triggers the Steam overlay to take a screenshot. + * + * {@link https://partner.steamgames.com/doc/api/ISteamScreenshots#TriggerScreenshot} + */ export function triggerScreenshot(): void + /** + * Adds a screenshot to the user's Steam screenshot library from disk. + * + * @param filename - The absolute path to the screenshot image file + * @param thumbnail_filename - Optional path to a thumbnail image (can be null/undefined) + * @param width - Width of the screenshot in pixels + * @param height - Height of the screenshot in pixels + * @returns The screenshot handle, or throws an error if the operation fails + * + * This call is asynchronous. The screenshot will be processed and added to the library. + * + * {@link https://partner.steamgames.com/doc/api/ISteamScreenshots#AddScreenshotToLibrary} + */ + export function addScreenshotToLibrary(filename: string, thumbnailFilename: string | undefined | null, width: number, height: number): number } export declare namespace stats { export function getInt(name: string): number | null diff --git a/src/api/screenshots.rs b/src/api/screenshots.rs index ebd723d8..a32490b9 100644 --- a/src/api/screenshots.rs +++ b/src/api/screenshots.rs @@ -2,11 +2,46 @@ use napi_derive::napi; #[napi] pub mod screenshots { + use napi::bindgen_prelude::Error; + use std::path::Path; + /// Triggers the Steam overlay to take a screenshot. + /// + /// {@link https://partner.steamgames.com/doc/api/ISteamScreenshots#TriggerScreenshot} #[napi] pub fn trigger_screenshot() { let client = crate::client::get_client(); let screenshots = client.screenshots(); screenshots.trigger_screenshot(); } + + /// Adds a screenshot to the user's Steam screenshot library from disk. + /// + /// @param filename - The absolute path to the screenshot image file + /// @param thumbnail_filename - Optional path to a thumbnail image (can be null/undefined) + /// @param width - Width of the screenshot in pixels + /// @param height - Height of the screenshot in pixels + /// @returns The screenshot handle, or throws an error if the operation fails + /// + /// This call is asynchronous. The screenshot will be processed and added to the library. + /// + /// {@link https://partner.steamgames.com/doc/api/ISteamScreenshots#AddScreenshotToLibrary} + #[napi] + pub fn add_screenshot_to_library( + filename: String, + thumbnail_filename: Option, + width: i32, + height: i32, + ) -> Result { + let client = crate::client::get_client(); + let screenshots = client.screenshots(); + + let path = Path::new(&filename); + let thumbnail_path = thumbnail_filename.as_ref().map(|s| Path::new(s.as_str())); + + match screenshots.add_screenshot_to_library(path, thumbnail_path, width, height) { + Ok(handle) => Ok(handle), + Err(e) => Err(Error::from_reason(e.to_string())), + } + } } diff --git a/src/api/workshop.rs b/src/api/workshop.rs index 3c80a010..b7e9108f 100644 --- a/src/api/workshop.rs +++ b/src/api/workshop.rs @@ -423,4 +423,122 @@ pub mod workshop { Err(e) => Err(Error::from_reason(e.to_string())), } } + + // TODO: Uncomment these methods once the steamworks-rs PR is merged + // PR: https://github.com/Noxime/steamworks-rs/pull/297 + // These methods require start_playtime_tracking, stop_playtime_tracking, and + // stop_playtime_tracking_for_all_items to be added to the steamworks-rs UGC API + + // /// Start tracking playtime on a set of workshop items. + // /// + // /// When your app shuts down, playtime tracking will automatically stop. + // /// + // /// @param itemIds - The array of workshop items you want to start tracking. (Maximum of 100 items.) + // /// @returns Promise that resolves when the operation completes + // /// + // /// {@link https://partner.steamgames.com/doc/api/ISteamUGC#StartPlaytimeTracking} + // #[napi] + // pub async fn start_playtime_tracking(item_ids: Vec) -> Result<(), Error> { + // if item_ids.is_empty() { + // return Err(Error::from_reason( + // "item_ids must contain at least 1 item".to_string(), + // )); + // } + // + // if item_ids.len() > 100 { + // return Err(Error::from_reason( + // "item_ids must not contain more than 100 items".to_string(), + // )); + // } + // + // let client = crate::client::get_client(); + // let (tx, rx) = oneshot::channel(); + // + // let published_file_ids: Vec = item_ids + // .iter() + // .map(|id| PublishedFileId(id.get_u64().1)) + // .collect(); + // + // client + // .ugc() + // .start_playtime_tracking(&published_file_ids, |result| { + // tx.send(result).unwrap(); + // }); + // + // let result = rx.await.unwrap(); + // match result { + // Ok(()) => Ok(()), + // Err(e) => Err(Error::from_reason(e.to_string())), + // } + // } + + // /// Stop tracking playtime on a set of workshop items. + // /// + // /// This will increment the number of "playtime" sessions for those items by one. + // /// When your app shuts down, playtime tracking will automatically stop. + // /// + // /// @param itemIds - The array of workshop items you want to stop tracking. (Maximum of 100 items.) + // /// @returns Promise that resolves when the operation completes + // /// + // /// {@link https://partner.steamgames.com/doc/api/ISteamUGC#StopPlaytimeTracking} + // #[napi] + // pub async fn stop_playtime_tracking(item_ids: Vec) -> Result<(), Error> { + // if item_ids.is_empty() { + // return Err(Error::from_reason( + // "item_ids must contain at least 1 item".to_string(), + // )); + // } + // + // if item_ids.len() > 100 { + // return Err(Error::from_reason( + // "item_ids must not contain more than 100 items".to_string(), + // )); + // } + // + // let client = crate::client::get_client(); + // let (tx, rx) = oneshot::channel(); + // + // let published_file_ids: Vec = item_ids + // .iter() + // .map(|id| PublishedFileId(id.get_u64().1)) + // .collect(); + // + // client + // .ugc() + // .stop_playtime_tracking(&published_file_ids, |result| { + // tx.send(result).unwrap(); + // }); + // + // let result = rx.await.unwrap(); + // match result { + // Ok(()) => Ok(()), + // Err(e) => Err(Error::from_reason(e.to_string())), + // } + // } + + // /// Stop tracking playtime of all workshop items. + // /// + // /// When your app shuts down, playtime tracking will automatically stop. + // /// This will increment the number of "playtime" sessions for all items that were being tracked by one. + // /// + // /// @returns Promise that resolves when the operation completes + // /// + // /// {@link https://partner.steamgames.com/doc/api/ISteamUGC#StopPlaytimeTrackingForAllItems} + // #[napi] + // pub async fn stop_playtime_tracking_for_all_items() -> Result<(), Error> { + // let client = crate::client::get_client(); + // let (tx, rx) = oneshot::channel(); + // + // client + // .ugc() + // .stop_playtime_tracking_for_all_items(|result| { + // tx.send(result).unwrap(); + // }); + // + // let result = rx.await.unwrap(); + // match result { + // Ok(()) => Ok(()), + // Err(e) => Err(Error::from_reason(e.to_string())), + // } + // } }