steamworks-ffi-node 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +53 -20
  2. package/dist/index.d.ts +4 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +24 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/SteamAPICore.d.ts +32 -9
  7. package/dist/internal/SteamAPICore.d.ts.map +1 -1
  8. package/dist/internal/SteamAPICore.js +46 -15
  9. package/dist/internal/SteamAPICore.js.map +1 -1
  10. package/dist/internal/SteamAchievementManager.d.ts +25 -25
  11. package/dist/internal/SteamAchievementManager.js +26 -26
  12. package/dist/internal/SteamAchievementManager.js.map +1 -1
  13. package/dist/internal/SteamCallbackPoller.d.ts +68 -0
  14. package/dist/internal/SteamCallbackPoller.d.ts.map +1 -0
  15. package/dist/internal/SteamCallbackPoller.js +134 -0
  16. package/dist/internal/SteamCallbackPoller.js.map +1 -0
  17. package/dist/internal/SteamLeaderboardManager.d.ts +338 -0
  18. package/dist/internal/SteamLeaderboardManager.d.ts.map +1 -0
  19. package/dist/internal/SteamLeaderboardManager.js +734 -0
  20. package/dist/internal/SteamLeaderboardManager.js.map +1 -0
  21. package/dist/internal/SteamLibraryLoader.d.ts +15 -0
  22. package/dist/internal/SteamLibraryLoader.d.ts.map +1 -1
  23. package/dist/internal/SteamLibraryLoader.js +26 -0
  24. package/dist/internal/SteamLibraryLoader.js.map +1 -1
  25. package/dist/internal/SteamStatsManager.d.ts +57 -45
  26. package/dist/internal/SteamStatsManager.d.ts.map +1 -1
  27. package/dist/internal/SteamStatsManager.js +146 -101
  28. package/dist/internal/SteamStatsManager.js.map +1 -1
  29. package/dist/steam.d.ts +115 -172
  30. package/dist/steam.d.ts.map +1 -1
  31. package/dist/steam.js +24 -241
  32. package/dist/steam.js.map +1 -1
  33. package/dist/{types.d.ts → types/achievements.d.ts} +19 -30
  34. package/dist/types/achievements.d.ts.map +1 -0
  35. package/dist/types/achievements.js +6 -0
  36. package/dist/types/achievements.js.map +1 -0
  37. package/dist/types/core.d.ts +18 -0
  38. package/dist/types/core.d.ts.map +1 -0
  39. package/dist/types/core.js +6 -0
  40. package/dist/types/core.js.map +1 -0
  41. package/dist/types/index.d.ts +14 -0
  42. package/dist/types/index.d.ts.map +1 -0
  43. package/dist/types/index.js +34 -0
  44. package/dist/types/index.js.map +1 -0
  45. package/dist/types/leaderboards.d.ts +121 -0
  46. package/dist/types/leaderboards.d.ts.map +1 -0
  47. package/dist/types/leaderboards.js +45 -0
  48. package/dist/types/leaderboards.js.map +1 -0
  49. package/dist/types/stats.d.ts +37 -0
  50. package/dist/types/stats.d.ts.map +1 -0
  51. package/dist/types/stats.js +6 -0
  52. package/dist/types/stats.js.map +1 -0
  53. package/package.json +4 -3
  54. package/dist/types.d.ts.map +0 -1
  55. package/dist/types.js +0 -3
  56. package/dist/types.js.map +0 -1
  57. package/steamworks_sdk/README.md +0 -82
@@ -0,0 +1,338 @@
1
+ import { SteamLibraryLoader } from './SteamLibraryLoader';
2
+ import { SteamAPICore } from './SteamAPICore';
3
+ import { LeaderboardEntry, LeaderboardInfo, LeaderboardScoreUploadResult, LeaderboardSortMethod, LeaderboardDisplayType, LeaderboardDataRequest, LeaderboardUploadScoreMethod } from '../types';
4
+ /**
5
+ * SteamLeaderboardManager
6
+ *
7
+ * Manages all Steam leaderboard operations including:
8
+ * - Finding and creating leaderboards
9
+ * - Uploading scores with optional details
10
+ * - Downloading leaderboard entries (global, friends, around user)
11
+ * - Retrieving leaderboard metadata
12
+ *
13
+ * Leaderboards are persistent scoreboards stored on Steam servers that allow
14
+ * players to compete globally or with friends. Each entry can include a score
15
+ * and up to 64 int32 detail values for additional game-specific data.
16
+ *
17
+ * ✅ IMPLEMENTATION NOTE:
18
+ * This implementation uses ISteamUtils polling to retrieve callback results
19
+ * synchronously after async operations complete. This provides full access to
20
+ * Steam callback data without requiring a C++ addon:
21
+ *
22
+ * 1. Initiates the async operation (returns SteamAPICall_t handle)
23
+ * 2. Polls ISteamUtils::IsAPICallCompleted() to check completion
24
+ * 3. Calls ISteamUtils::GetAPICallResult() to retrieve result struct
25
+ * 4. Returns complete callback data (handles, ranks, scores, etc.)
26
+ *
27
+ * All async operations now return actual results:
28
+ * - findOrCreateLeaderboard/findLeaderboard: Returns LeaderboardInfo with handle
29
+ * - uploadScore: Returns upload result with ranks and success status
30
+ * - downloadLeaderboardEntries: Returns array of LeaderboardEntry objects
31
+ * - attachLeaderboardUGC: Returns true/false based on actual result
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const leaderboardManager = new SteamLeaderboardManager(libraryLoader, apiCore);
36
+ *
37
+ * // Find or create a leaderboard
38
+ * const leaderboard = await leaderboardManager.findOrCreateLeaderboard(
39
+ * 'HighScores',
40
+ * LeaderboardSortMethod.Descending,
41
+ * LeaderboardDisplayType.Numeric
42
+ * );
43
+ *
44
+ * // Upload a score and get rank information
45
+ * const result = await leaderboardManager.uploadScore(
46
+ * leaderboard.handle,
47
+ * 1000,
48
+ * LeaderboardUploadScoreMethod.KeepBest
49
+ * );
50
+ * console.log(`New rank: ${result.globalRankNew}`);
51
+ *
52
+ * // Download top 10 entries
53
+ * const entries = await leaderboardManager.downloadLeaderboardEntries(
54
+ * leaderboard.handle,
55
+ * LeaderboardDataRequest.Global,
56
+ * 1,
57
+ * 10
58
+ * );
59
+ * entries.forEach(entry => {
60
+ * console.log(`${entry.globalRank}. Score: ${entry.score}`);
61
+ * });
62
+ * ```
63
+ */
64
+ export declare class SteamLeaderboardManager {
65
+ /** Steam library loader for FFI function calls */
66
+ private libraryLoader;
67
+ /** Steam API core for initialization and callback management */
68
+ private apiCore;
69
+ /** Callback poller for retrieving async operation results */
70
+ private callbackPoller;
71
+ /**
72
+ * Creates a new SteamLeaderboardManager instance
73
+ *
74
+ * @param libraryLoader - The Steam library loader for FFI calls
75
+ * @param apiCore - The Steam API core for lifecycle management
76
+ */
77
+ constructor(libraryLoader: SteamLibraryLoader, apiCore: SteamAPICore);
78
+ /**
79
+ * Find or create a leaderboard
80
+ *
81
+ * Searches for a leaderboard by name, and creates it if it doesn't exist.
82
+ * This is an asynchronous operation that communicates with Steam servers.
83
+ *
84
+ * @param name - Name of the leaderboard (max 128 UTF-8 bytes)
85
+ * @param sortMethod - How entries should be sorted
86
+ * @param displayType - How scores should be displayed
87
+ * @returns Promise resolving to leaderboard info, or null on error
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * // Create a high score leaderboard
92
+ * const leaderboard = await leaderboardManager.findOrCreateLeaderboard(
93
+ * 'HighScores',
94
+ * LeaderboardSortMethod.Descending, // Highest is best
95
+ * LeaderboardDisplayType.Numeric
96
+ * );
97
+ *
98
+ * // Create a speedrun leaderboard
99
+ * const speedrun = await leaderboardManager.findOrCreateLeaderboard(
100
+ * 'FastestTime',
101
+ * LeaderboardSortMethod.Ascending, // Lowest is best
102
+ * LeaderboardDisplayType.TimeMilliseconds
103
+ * );
104
+ * ```
105
+ *
106
+ * @remarks
107
+ * - Leaderboard names must be unique per game
108
+ * - Maximum name length is 128 UTF-8 bytes
109
+ * - Waits up to 5 seconds for Steam server response
110
+ *
111
+ * Steamworks SDK Functions:
112
+ * - `SteamAPI_ISteamUserStats_FindOrCreateLeaderboard()` - Find/create leaderboard
113
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardName()` - Get leaderboard name
114
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardEntryCount()` - Get entry count
115
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardSortMethod()` - Get sort method
116
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardDisplayType()` - Get display type
117
+ */
118
+ findOrCreateLeaderboard(name: string, sortMethod: LeaderboardSortMethod, displayType: LeaderboardDisplayType): Promise<LeaderboardInfo | null>;
119
+ /**
120
+ * Find an existing leaderboard
121
+ *
122
+ * Searches for a leaderboard by name. Unlike findOrCreateLeaderboard(),
123
+ * this will not create the leaderboard if it doesn't exist.
124
+ *
125
+ * @param name - Name of the leaderboard to find
126
+ * @returns Promise resolving to leaderboard info, or null if not found
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const leaderboard = await leaderboardManager.findLeaderboard('HighScores');
131
+ * if (leaderboard) {
132
+ * console.log(`[Steamworks] Found leaderboard with ${leaderboard.entryCount} entries`);
133
+ * } else {
134
+ * console.log('[Steamworks] Leaderboard does not exist');
135
+ * }
136
+ * ```
137
+ *
138
+ * @remarks
139
+ * - Returns null if leaderboard doesn't exist
140
+ * - Waits up to 5 seconds for Steam server response
141
+ *
142
+ * Steamworks SDK Functions:
143
+ * - `SteamAPI_ISteamUserStats_FindLeaderboard()` - Find existing leaderboard
144
+ */
145
+ findLeaderboard(name: string): Promise<LeaderboardInfo | null>;
146
+ /**
147
+ * Get information about a leaderboard
148
+ *
149
+ * Retrieves metadata for a leaderboard using its handle.
150
+ *
151
+ * @param handle - Leaderboard handle
152
+ * @returns Leaderboard information, or null on error
153
+ *
154
+ * @remarks
155
+ * - Synchronous operation, no Steam server communication needed
156
+ * - Handle must be from a previous find/create operation
157
+ *
158
+ * Steamworks SDK Functions:
159
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardName()` - Get leaderboard name
160
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardEntryCount()` - Get entry count
161
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardSortMethod()` - Get sort method
162
+ * - `SteamAPI_ISteamUserStats_GetLeaderboardDisplayType()` - Get display type
163
+ */
164
+ getLeaderboardInfo(handle: bigint): LeaderboardInfo | null;
165
+ /**
166
+ * Upload a score to a leaderboard
167
+ *
168
+ * Submits a score for the current user to the specified leaderboard.
169
+ * Can optionally include up to 64 int32 detail values.
170
+ *
171
+ * @param leaderboardHandle - Handle to the leaderboard
172
+ * @param score - Score value to upload
173
+ * @param uploadMethod - How to handle the score (keep best or force update)
174
+ * @param details - Optional array of detail values (max 64)
175
+ * @returns Promise resolving to upload result, or null on error
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * // Upload simple score (keep best)
180
+ * await leaderboardManager.uploadScore(
181
+ * leaderboard.handle,
182
+ * 1000,
183
+ * LeaderboardUploadScoreMethod.KeepBest
184
+ * );
185
+ *
186
+ * // Upload score with details (e.g., level, time, difficulty)
187
+ * await leaderboardManager.uploadScore(
188
+ * leaderboard.handle,
189
+ * 5000,
190
+ * LeaderboardUploadScoreMethod.KeepBest,
191
+ * [10, 300, 2] // level 10, 300 seconds, difficulty 2
192
+ * );
193
+ *
194
+ * // Force update score (even if worse)
195
+ * await leaderboardManager.uploadScore(
196
+ * leaderboard.handle,
197
+ * 750,
198
+ * LeaderboardUploadScoreMethod.ForceUpdate
199
+ * );
200
+ * ```
201
+ *
202
+ * @remarks
203
+ * - KeepBest: Only updates if new score is better
204
+ * - ForceUpdate: Always updates to new score
205
+ * - Details array is limited to 64 int32 values
206
+ * - Waits up to 3 seconds for Steam server response
207
+ *
208
+ * Steamworks SDK Functions:
209
+ * - `SteamAPI_ISteamUserStats_UploadLeaderboardScore()` - Upload score to leaderboard
210
+ */
211
+ uploadScore(leaderboardHandle: bigint, score: number, uploadMethod: LeaderboardUploadScoreMethod, details?: number[]): Promise<LeaderboardScoreUploadResult | null>;
212
+ /**
213
+ * Download leaderboard entries
214
+ *
215
+ * Retrieves a range of entries from a leaderboard. Can fetch global top scores,
216
+ * entries around the current user, or friend entries.
217
+ *
218
+ * @param leaderboardHandle - Handle to the leaderboard
219
+ * @param dataRequest - Type of data to request
220
+ * @param rangeStart - Start of range (1-based for global, offset for around user)
221
+ * @param rangeEnd - End of range (1-based for global, offset for around user)
222
+ * @returns Promise resolving to array of entries, or empty array on error
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * // Get top 10 global entries
227
+ * const top10 = await leaderboardManager.downloadLeaderboardEntries(
228
+ * leaderboard.handle,
229
+ * LeaderboardDataRequest.Global,
230
+ * 1, // Start at rank 1
231
+ * 10 // End at rank 10
232
+ * );
233
+ *
234
+ * // Get entries around current user (3 above, 3 below)
235
+ * const aroundMe = await leaderboardManager.downloadLeaderboardEntries(
236
+ * leaderboard.handle,
237
+ * LeaderboardDataRequest.GlobalAroundUser,
238
+ * -3, // 3 entries above
239
+ * 3 // 3 entries below
240
+ * );
241
+ *
242
+ * // Get friend entries
243
+ * const friends = await leaderboardManager.downloadLeaderboardEntries(
244
+ * leaderboard.handle,
245
+ * LeaderboardDataRequest.Friends,
246
+ * 0, // Ignored for friends
247
+ * 0 // Ignored for friends
248
+ * );
249
+ * ```
250
+ *
251
+ * @remarks
252
+ * - Global: rangeStart and rangeEnd are 1-based ranks [1, N]
253
+ * - GlobalAroundUser: rangeStart is negative offset, rangeEnd is positive offset
254
+ * - Friends: range parameters are ignored
255
+ * - Returns up to requested number of entries, or fewer if not available
256
+ * - Waits up to 3 seconds for Steam server response
257
+ *
258
+ * Steamworks SDK Functions:
259
+ * - `SteamAPI_ISteamUserStats_DownloadLeaderboardEntries()` - Download leaderboard entries
260
+ * - `SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry()` - Get individual entry data
261
+ */
262
+ downloadLeaderboardEntries(leaderboardHandle: bigint, dataRequest: LeaderboardDataRequest, rangeStart: number, rangeEnd: number): Promise<LeaderboardEntry[]>;
263
+ /**
264
+ * Download leaderboard entries for specific users
265
+ *
266
+ * Retrieves leaderboard entries for an arbitrary set of Steam users.
267
+ * Useful for comparing scores with specific players.
268
+ *
269
+ * @param leaderboardHandle - Handle to the leaderboard
270
+ * @param steamIds - Array of Steam IDs to retrieve (max 100)
271
+ * @returns Promise resolving to array of entries, or empty array on error
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * // Compare scores with specific players
276
+ * const playerIds = ['76561198012345678', '76561198087654321'];
277
+ * const entries = await leaderboardManager.downloadLeaderboardEntriesForUsers(
278
+ * leaderboard.handle,
279
+ * playerIds
280
+ * );
281
+ *
282
+ * entries.forEach(entry => {
283
+ * console.log(`[Steamworks] ${entry.steamId}: ${entry.score} (rank ${entry.globalRank})`);
284
+ * });
285
+ * ```
286
+ *
287
+ * @remarks
288
+ * - Maximum 100 users per request
289
+ * - Only returns entries for users who have scores
290
+ * - Only one outstanding request at a time
291
+ * - Waits up to 3 seconds for Steam server response
292
+ *
293
+ * Steamworks SDK Functions:
294
+ * - `SteamAPI_ISteamUserStats_DownloadLeaderboardEntriesForUsers()` - Download entries for users
295
+ * - `SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry()` - Get individual entry data
296
+ */
297
+ downloadLeaderboardEntriesForUsers(leaderboardHandle: bigint, steamIds: string[]): Promise<LeaderboardEntry[]>;
298
+ /**
299
+ * Attach user-generated content to a leaderboard entry
300
+ *
301
+ * Associates a piece of UGC (like a replay file, screenshot, or level)
302
+ * with the current user's leaderboard entry. The UGC must first be shared
303
+ * using ISteamRemoteStorage::FileShare().
304
+ *
305
+ * @param leaderboardHandle - Handle to the leaderboard
306
+ * @param ugcHandle - Handle to the shared UGC content
307
+ * @returns Promise resolving to true if successful, false otherwise
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * // First, share a file to get UGC handle
312
+ * // const ugcHandle = await steamRemoteStorage.fileShare('replay.dat');
313
+ *
314
+ * // Then attach it to leaderboard entry
315
+ * const ugcHandle = BigInt('123456789'); // From FileShare
316
+ * const success = await leaderboardManager.attachLeaderboardUGC(
317
+ * leaderboard.handle,
318
+ * ugcHandle
319
+ * );
320
+ *
321
+ * if (success) {
322
+ * console.log('[Steamworks] UGC attached to leaderboard entry');
323
+ * }
324
+ * ```
325
+ *
326
+ * @remarks
327
+ * - UGC must be created with ISteamRemoteStorage::FileShare() first
328
+ * - Only one UGC item can be attached per leaderboard entry
329
+ * - Attaching new UGC replaces any previously attached UGC
330
+ * - Common use cases: replays, screenshots, custom levels
331
+ * - Waits up to 3 seconds for Steam server response
332
+ *
333
+ * Steamworks SDK Functions:
334
+ * - `SteamAPI_ISteamUserStats_AttachLeaderboardUGC()` - Attach UGC to leaderboard entry
335
+ */
336
+ attachLeaderboardUGC(leaderboardHandle: bigint, ugcHandle: bigint): Promise<boolean>;
337
+ }
338
+ //# sourceMappingURL=SteamLeaderboardManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SteamLeaderboardManager.d.ts","sourceRoot":"","sources":["../../src/internal/SteamLeaderboardManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,4BAA4B,EAK7B,MAAM,UAAU,CAAC;AA6DlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,qBAAa,uBAAuB;IAClC,kDAAkD;IAClD,OAAO,CAAC,aAAa,CAAqB;IAE1C,gEAAgE;IAChE,OAAO,CAAC,OAAO,CAAe;IAE9B,6DAA6D;IAC7D,OAAO,CAAC,cAAc,CAAsB;IAE5C;;;;;OAKG;gBACS,aAAa,EAAE,kBAAkB,EAAE,OAAO,EAAE,YAAY;IAUpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,uBAAuB,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAqDlC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAmDpE;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAgD1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACG,WAAW,CACf,iBAAiB,EAAE,MAAM,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,4BAA4B,EAC1C,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;IA8E/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDG;IACG,0BAA0B,CAC9B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,sBAAsB,EACnC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAwF9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACG,kCAAkC,CACtC,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAkG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACG,oBAAoB,CACxB,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;CAmDpB"}