Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches: [main]
pull_request:
workflow_dispatch:

env:
DEBUG: "napi:*"
Expand Down
20 changes: 19 additions & 1 deletion client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions src/api/screenshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
width: i32,
height: i32,
) -> Result<u32, Error> {
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())),
}
}
}
118 changes: 118 additions & 0 deletions src/api/workshop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<BigInt>) -> 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<PublishedFileId> = 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<BigInt>) -> 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<PublishedFileId> = 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())),
// }
// }
}