1 #if defined(__linux__) || defined(__APPLE__)
2 // The 32-bit version of gcc has the alignment requirement for u64 and double set to
3 // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
4 // The 64-bit version of gcc has the alignment requirement for these types set to
5 // 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
6 // The 64-bit structure packing has to match the 32-bit structure packing for each platform.
7 #define VALVE_CALLBACK_PACK_SMALL
9 #define VALVE_CALLBACK_PACK_LARGE
12 #if defined( VALVE_CALLBACK_PACK_SMALL )
13 #pragma pack( push, 4 )
14 #elif defined( VALVE_CALLBACK_PACK_LARGE )
15 #pragma pack( push, 8 )
17 #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
21 typedef void ISteamFriends
;
22 typedef void ISteamUserStats
;
23 typedef void ISteamUtils
;
24 typedef void ISteamUser
;
25 typedef void ISteamNetworking
;
27 typedef i32 HSteamPipe
;
28 typedef i32 HSteamUser
;
30 typedef int E_iCallBack_t
;
32 typedef u32 SNetSocket_t
; // CreateP2PConnectionSocket()
33 typedef u32 SNetListenSocket_t
; // CreateListenSocket()
35 typedef u64 u64_steamid
;
36 typedef u64 SteamAPICall_t
;
38 enum { k_iSteamUserCallbacks
= 100 };
39 enum { k_iSteamGameServerCallbacks
= 200 };
40 enum { k_iSteamFriendsCallbacks
= 300 };
41 enum { k_iSteamBillingCallbacks
= 400 };
42 enum { k_iSteamMatchmakingCallbacks
= 500 };
43 enum { k_iSteamContentServerCallbacks
= 600 };
44 enum { k_iSteamUtilsCallbacks
= 700 };
45 enum { k_iClientFriendsCallbacks
= 800 };
46 enum { k_iClientUserCallbacks
= 900 };
47 enum { k_iSteamAppsCallbacks
= 1000 };
48 enum { k_iSteamUserStatsCallbacks
= 1100 };
49 enum { k_iSteamNetworkingCallbacks
= 1200 };
50 enum { k_iSteamNetworkingSocketsCallbacks
= 1220 };
51 enum { k_iSteamNetworkingMessagesCallbacks
= 1250 };
52 enum { k_iSteamNetworkingUtilsCallbacks
= 1280 };
53 enum { k_iClientRemoteStorageCallbacks
= 1300 };
54 enum { k_iClientDepotBuilderCallbacks
= 1400 };
55 enum { k_iSteamGameServerItemsCallbacks
= 1500 };
56 enum { k_iClientUtilsCallbacks
= 1600 };
57 enum { k_iSteamGameCoordinatorCallbacks
= 1700 };
58 enum { k_iSteamGameServerStatsCallbacks
= 1800 };
59 enum { k_iSteam2AsyncCallbacks
= 1900 };
60 enum { k_iSteamGameStatsCallbacks
= 2000 };
61 enum { k_iClientHTTPCallbacks
= 2100 };
62 enum { k_iClientScreenshotsCallbacks
= 2200 };
63 enum { k_iSteamScreenshotsCallbacks
= 2300 };
64 enum { k_iClientAudioCallbacks
= 2400 };
65 enum { k_iClientUnifiedMessagesCallbacks
= 2500 };
66 enum { k_iSteamStreamLauncherCallbacks
= 2600 };
67 enum { k_iClientControllerCallbacks
= 2700 };
68 enum { k_iSteamControllerCallbacks
= 2800 };
69 enum { k_iClientParentalSettingsCallbacks
= 2900 };
70 enum { k_iClientDeviceAuthCallbacks
= 3000 };
71 enum { k_iClientNetworkDeviceManagerCallbacks
= 3100 };
72 enum { k_iClientMusicCallbacks
= 3200 };
73 enum { k_iClientRemoteClientManagerCallbacks
= 3300 };
74 enum { k_iClientUGCCallbacks
= 3400 };
75 enum { k_iSteamStreamClientCallbacks
= 3500 };
76 enum { k_IClientProductBuilderCallbacks
= 3600 };
77 enum { k_iClientShortcutsCallbacks
= 3700 };
78 enum { k_iClientRemoteControlManagerCallbacks
= 3800 };
79 enum { k_iSteamAppListCallbacks
= 3900 };
80 enum { k_iSteamMusicCallbacks
= 4000 };
81 enum { k_iSteamMusicRemoteCallbacks
= 4100 };
82 enum { k_iClientVRCallbacks
= 4200 };
83 enum { k_iClientGameNotificationCallbacks
= 4300 };
84 enum { k_iSteamGameNotificationCallbacks
= 4400 };
85 enum { k_iSteamHTMLSurfaceCallbacks
= 4500 };
86 enum { k_iClientVideoCallbacks
= 4600 };
87 enum { k_iClientInventoryCallbacks
= 4700 };
88 enum { k_iClientBluetoothManagerCallbacks
= 4800 };
89 enum { k_iClientSharedConnectionCallbacks
= 4900 };
90 enum { k_ISteamParentalSettingsCallbacks
= 5000 };
91 enum { k_iClientShaderCallbacks
= 5100 };
92 enum { k_iSteamGameSearchCallbacks
= 5200 };
93 enum { k_iSteamPartiesCallbacks
= 5300 };
94 enum { k_iClientPartiesCallbacks
= 5400 };
95 enum { k_iSteamSTARCallbacks
= 5500 };
96 enum { k_iClientSTARCallbacks
= 5600 };
97 enum { k_iSteamRemotePlayCallbacks
= 5700 };
98 enum { k_iClientCompatCallbacks
= 5800 };
99 enum { k_iSteamChatCallbacks
= 5900 };
101 // General result codes
104 k_EResultNone
= 0, // no result
105 k_EResultOK
= 1, // success
106 k_EResultFail
= 2, // generic failure
107 k_EResultNoConnection
= 3, // no/failed network connection
108 // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
109 k_EResultInvalidPassword
= 5, // password/ticket is invalid
110 k_EResultLoggedInElsewhere
= 6, // same user logged in elsewhere
111 k_EResultInvalidProtocolVer
= 7, // protocol version is incorrect
112 k_EResultInvalidParam
= 8, // a parameter is incorrect
113 k_EResultFileNotFound
= 9, // file was not found
114 k_EResultBusy
= 10, // called method busy - action not taken
115 k_EResultInvalidState
= 11, // called object was in an invalid state
116 k_EResultInvalidName
= 12, // name is invalid
117 k_EResultInvalidEmail
= 13, // email is invalid
118 k_EResultDuplicateName
= 14, // name is not unique
119 k_EResultAccessDenied
= 15, // access is denied
120 k_EResultTimeout
= 16, // operation timed out
121 k_EResultBanned
= 17, // VAC2 banned
122 k_EResultAccountNotFound
= 18, // account not found
123 k_EResultInvalidSteamID
= 19, // steamID is invalid
124 k_EResultServiceUnavailable
= 20, // The requested service is currently unavailable
125 k_EResultNotLoggedOn
= 21, // The user is not logged on
126 k_EResultPending
= 22, // Request is pending (may be in process, or waiting on third party)
127 k_EResultEncryptionFailure
= 23, // Encryption or Decryption failed
128 k_EResultInsufficientPrivilege
= 24, // Insufficient privilege
129 k_EResultLimitExceeded
= 25, // Too much of a good thing
130 k_EResultRevoked
= 26, // Access has been revoked (used for revoked guest passes)
131 k_EResultExpired
= 27, // License/Guest pass the user is trying to access is expired
132 k_EResultAlreadyRedeemed
= 28, // Guest pass has already been redeemed by account, cannot be acked again
133 k_EResultDuplicateRequest
= 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
134 k_EResultAlreadyOwned
= 30, // All the games in this guest pass redemption request are already owned by the user
135 k_EResultIPNotFound
= 31, // IP address not found
136 k_EResultPersistFailed
= 32, // failed to write change to the data store
137 k_EResultLockingFailed
= 33, // failed to acquire access lock for this operation
138 k_EResultLogonSessionReplaced
= 34,
139 k_EResultConnectFailed
= 35,
140 k_EResultHandshakeFailed
= 36,
141 k_EResultIOFailure
= 37,
142 k_EResultRemoteDisconnect
= 38,
143 k_EResultShoppingCartNotFound
= 39, // failed to find the shopping cart requested
144 k_EResultBlocked
= 40, // a user didn't allow it
145 k_EResultIgnored
= 41, // target is ignoring sender
146 k_EResultNoMatch
= 42, // nothing matching the request found
147 k_EResultAccountDisabled
= 43,
148 k_EResultServiceReadOnly
= 44, // this service is not accepting content changes right now
149 k_EResultAccountNotFeatured
= 45, // account doesn't have value, so this feature isn't available
150 k_EResultAdministratorOK
= 46, // allowed to take this action, but only because requester is admin
151 k_EResultContentVersion
= 47, // A Version mismatch in content transmitted within the Steam protocol.
152 k_EResultTryAnotherCM
= 48, // The current CM can't service the user making a request, user should try another.
153 k_EResultPasswordRequiredToKickSession
= 49,// You are already logged in elsewhere, this cached credential login has failed.
154 k_EResultAlreadyLoggedInElsewhere
= 50, // You are already logged in elsewhere, you must wait
155 k_EResultSuspended
= 51, // Long running operation (content download) suspended/paused
156 k_EResultCancelled
= 52, // Operation canceled (typically by user: content download)
157 k_EResultDataCorruption
= 53, // Operation canceled because data is ill formed or unrecoverable
158 k_EResultDiskFull
= 54, // Operation canceled - not enough disk space.
159 k_EResultRemoteCallFailed
= 55, // an remote call or IPC call failed
160 k_EResultPasswordUnset
= 56, // Password could not be verified as it's unset server side
161 k_EResultExternalAccountUnlinked
= 57, // External account (PSN, Facebook...) is not linked to a Steam account
162 k_EResultPSNTicketInvalid
= 58, // PSN ticket was invalid
163 k_EResultExternalAccountAlreadyLinked
= 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
164 k_EResultRemoteFileConflict
= 60, // The sync cannot resume due to a conflict between the local and remote files
165 k_EResultIllegalPassword
= 61, // The requested new password is not legal
166 k_EResultSameAsPreviousValue
= 62, // new value is the same as the old one ( secret question and answer )
167 k_EResultAccountLogonDenied
= 63, // account login denied due to 2nd factor authentication failure
168 k_EResultCannotUseOldPassword
= 64, // The requested new password is not legal
169 k_EResultInvalidLoginAuthCode
= 65, // account login denied due to auth code invalid
170 k_EResultAccountLogonDeniedNoMail
= 66, // account login denied due to 2nd factor auth failure - and no mail has been sent
171 k_EResultHardwareNotCapableOfIPT
= 67, //
172 k_EResultIPTInitError
= 68, //
173 k_EResultParentalControlRestricted
= 69, // operation failed due to parental control restrictions for current user
174 k_EResultFacebookQueryError
= 70, // Facebook query returned an error
175 k_EResultExpiredLoginAuthCode
= 71, // account login denied due to auth code expired
176 k_EResultIPLoginRestrictionFailed
= 72,
177 k_EResultAccountLockedDown
= 73,
178 k_EResultAccountLogonDeniedVerifiedEmailRequired
= 74,
179 k_EResultNoMatchingURL
= 75,
180 k_EResultBadResponse
= 76, // parse failure, missing field, etc.
181 k_EResultRequirePasswordReEntry
= 77, // The user cannot complete the action until they re-enter their password
182 k_EResultValueOutOfRange
= 78, // the value entered is outside the acceptable range
183 k_EResultUnexpectedError
= 79, // something happened that we didn't expect to ever happen
184 k_EResultDisabled
= 80, // The requested service has been configured to be unavailable
185 k_EResultInvalidCEGSubmission
= 81, // The set of files submitted to the CEG server are not valid !
186 k_EResultRestrictedDevice
= 82, // The device being used is not allowed to perform this action
187 k_EResultRegionLocked
= 83, // The action could not be complete because it is region restricted
188 k_EResultRateLimitExceeded
= 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
189 k_EResultAccountLoginDeniedNeedTwoFactor
= 85, // Need two-factor code to login
190 k_EResultItemDeleted
= 86, // The thing we're trying to access has been deleted
191 k_EResultAccountLoginDeniedThrottle
= 87, // login attempt failed, try to throttle response to possible attacker
192 k_EResultTwoFactorCodeMismatch
= 88, // two factor code mismatch
193 k_EResultTwoFactorActivationCodeMismatch
= 89, // activation code for two-factor didn't match
194 k_EResultAccountAssociatedToMultiplePartners
= 90, // account has been associated with multiple partners
195 k_EResultNotModified
= 91, // data not modified
196 k_EResultNoMobileDevice
= 92, // the account does not have a mobile device associated with it
197 k_EResultTimeNotSynced
= 93, // the time presented is out of range or tolerance
198 k_EResultSmsCodeFailed
= 94, // SMS code failure (no match, none pending, etc.)
199 k_EResultAccountLimitExceeded
= 95, // Too many accounts access this resource
200 k_EResultAccountActivityLimitExceeded
= 96, // Too many changes to this account
201 k_EResultPhoneActivityLimitExceeded
= 97, // Too many changes to this phone
202 k_EResultRefundToWallet
= 98, // Cannot refund to payment method, must use wallet
203 k_EResultEmailSendFailure
= 99, // Cannot send an email
204 k_EResultNotSettled
= 100, // Can't perform operation till payment has settled
205 k_EResultNeedCaptcha
= 101, // Needs to provide a valid captcha
206 k_EResultGSLTDenied
= 102, // a game server login token owned by this token's owner has been banned
207 k_EResultGSOwnerDenied
= 103, // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone)
208 k_EResultInvalidItemType
= 104, // the type of thing we were requested to act on is invalid
209 k_EResultIPBanned
= 105, // the ip address has been banned from taking this action
210 k_EResultGSLTExpired
= 106, // this token has expired from disuse; can be reset for use
211 k_EResultInsufficientFunds
= 107, // user doesn't have enough wallet funds to complete the action
212 k_EResultTooManyPending
= 108, // There are too many of this thing pending already
213 k_EResultNoSiteLicensesFound
= 109, // No site licenses found
214 k_EResultWGNetworkSendExceeded
= 110, // the WG couldn't send a response because we exceeded max network send size
215 k_EResultAccountNotFriends
= 111, // the user is not mutually friends
216 k_EResultLimitedUserAccount
= 112, // the user is limited
217 k_EResultCantRemoveItem
= 113, // item can't be removed
218 k_EResultAccountDeleted
= 114, // account has been deleted
219 k_EResultExistingUserCancelledLicense
= 115, // A license for this already exists, but cancelled
220 k_EResultCommunityCooldown
= 116, // access is denied because of a community cooldown (probably from support profile data resets)
221 k_EResultNoLauncherSpecified
= 117, // No launcher was specified, but a launcher was needed to choose correct realm for operation.
222 k_EResultMustAgreeToSSA
= 118, // User must agree to china SSA or global SSA before login
223 k_EResultLauncherMigrated
= 119, // The specified launcher type is no longer supported; the user should be directed elsewhere
224 k_EResultSteamRealmMismatch
= 120, // The user's realm does not match the realm of the requested resource
225 k_EResultInvalidSignature
= 121, // signature check did not match
226 k_EResultParseFailure
= 122, // Failed to parse input
227 k_EResultNoVerifiedPhone
= 123, // account does not have a verified phone number
236 } ValvePackingSentinel_t
;
240 HSteamUser m_hSteamUser
; // Specific user to whom this callback applies.
241 int m_iCallback
; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
242 u8
*m_pubParam
; // Points to the callback structure
243 int m_cubParam
; // Size of the data pointed to by m_pubParam
249 SteamAPICall_t m_hAsyncCall
;
253 } SteamAPICallCompleted_t
;
255 // Steam universes. Each universe is a self-contained Steam instance.
257 k_EUniverseInvalid
= 0,
258 k_EUniversePublic
= 1,
260 k_EUniverseInternal
= 3,
262 // k_EUniverseRC = 5, // no such universe anymore
270 struct SteamIDComponent_t
272 #ifdef VALVE_BIG_ENDIAN
273 EUniverse_t m_EUniverse
: 8; // universe this account belongs to
274 unsigned int m_EAccountType
: 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
275 unsigned int m_unAccountInstance
: 20; // dynamic instance ID
276 u32 m_unAccountID
: 32; // unique account identifier
278 u32 m_unAccountID
: 32; // unique account identifier
279 unsigned int m_unAccountInstance
: 20; // dynamic instance ID
280 unsigned int m_EAccountType
: 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
281 EUniverse_t m_EUniverse
: 8; // universe this account belongs to
289 typedef struct GameID_t
291 #ifdef VALVE_BIG_ENDIAN
292 unsigned int m_nModID
: 32;
293 unsigned int m_nType
: 8;
294 unsigned int m_nAppID
: 24;
296 unsigned int m_nAppID
: 24;
297 unsigned int m_nType
: 8;
298 unsigned int m_nModID
: 32;
302 #define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
304 typedef enum ESteamAPICallFailure
306 k_ESteamAPICallFailureNone
= -1, // no failure
307 k_ESteamAPICallFailureSteamGone
= 0, // the local Steam process has gone away
308 k_ESteamAPICallFailureNetworkFailure
= 1, // the network connection to Steam has been broken, or was already broken
309 // SteamServersDisconnected_t callback will be sent around the same time
310 // SteamServersConnected_t will be sent when the client is able to talk to the Steam servers again
311 k_ESteamAPICallFailureInvalidHandle
= 2, // the SteamAPICall_t handle passed in no longer exists
312 k_ESteamAPICallFailureMismatchedCallback
= 3,// GetAPICallResult() was called with the wrong callback type for this API call
313 } ESteamAPICallFailure
;
315 typedef u64 UGCHandle_t
;
316 typedef u64 PublishedFileUpdateHandle_t
;
317 typedef u64 PublishedFileId_t
;
318 const PublishedFileId_t k_PublishedFileIdInvalid
= 0;
319 const UGCHandle_t k_UGCHandleInvalid
= 0xffffffffffffffffull
;
320 const PublishedFileUpdateHandle_t k_PublishedFileUpdateHandleInvalid
= 0xffffffffffffffffull
;
322 // Handle for writing to Steam Cloud
323 typedef u64 UGCFileWriteStreamHandle_t
;
325 // size limit on stat or achievement name (UTF-8 encoded)
326 enum { k_cchStatNameMax
= 128 };
328 // maximum number of bytes for a leaderboard name (UTF-8 encoded)
329 enum { k_cchLeaderboardNameMax
= 128 };
331 // maximum number of details i32's storable for a single leaderboard entry
332 enum { k_cLeaderboardDetailsMax
= 64 };
334 // handle to a single leaderboard
335 typedef u64 SteamLeaderboard_t
;
337 // handle to a set of downloaded entries in a leaderboard
338 typedef u64 SteamLeaderboardEntries_t
;
340 // type of data request, when downloading leaderboard entries
341 typedef enum ELeaderboardDataRequest
343 k_ELeaderboardDataRequestGlobal
= 0,
344 k_ELeaderboardDataRequestGlobalAroundUser
= 1,
345 k_ELeaderboardDataRequestFriends
= 2,
346 k_ELeaderboardDataRequestUsers
= 3
347 } ELeaderboardDataRequest
;
349 // the sort order of a leaderboard
350 typedef enum ELeaderboardSortMethod
352 k_ELeaderboardSortMethodNone
= 0,
353 k_ELeaderboardSortMethodAscending
= 1, // top-score is lowest number
354 k_ELeaderboardSortMethodDescending
= 2, // top-score is highest number
355 } ELeaderboardSortMethod
;
357 // the display type (used by the Steam Community web site) for a leaderboard
358 typedef enum ELeaderboardDisplayType
360 k_ELeaderboardDisplayTypeNone
= 0,
361 k_ELeaderboardDisplayTypeNumeric
= 1, // simple numerical score
362 k_ELeaderboardDisplayTypeTimeSeconds
= 2, // the score represents a time, in seconds
363 k_ELeaderboardDisplayTypeTimeMilliSeconds
= 3, // the score represents a time, in milliseconds
364 } ELeaderboardDisplayType
;
366 typedef enum ELeaderboardUploadScoreMethod
368 k_ELeaderboardUploadScoreMethodNone
= 0,
369 k_ELeaderboardUploadScoreMethodKeepBest
= 1, // Leaderboard will keep user's best score
370 k_ELeaderboardUploadScoreMethodForceUpdate
= 2, // Leaderboard will always replace score with specified
371 } ELeaderboardUploadScoreMethod
;
373 // a single entry in a leaderboard, as returned by GetDownloadedLeaderboardEntry()
374 typedef struct LeaderboardEntry_t
376 CSteamID m_steamIDUser
; // user with the entry - use SteamFriends()->GetFriendPersonaName() & SteamFriends()->GetFriendAvatar() to get more info
377 i32 m_nGlobalRank
; // [1..N], where N is the number of users with an entry in the leaderboard
378 i32 m_nScore
; // score as set in the leaderboard
379 i32 m_cDetails
; // number of i32 details available for this entry
380 UGCHandle_t m_hUGC
; // handle for UGC attached to the entry
381 } LeaderboardEntry_t
;
383 //-----------------------------------------------------------------------------
384 // Purpose: called when the latests stats and achievements have been received
386 //-----------------------------------------------------------------------------
387 typedef struct UserStatsReceived_t
389 u64 m_nGameID
; // Game these stats are for
390 EResult m_eResult
; // Success / error fetching the stats
391 CSteamID m_steamIDUser
; // The user for whom the stats are retrieved for
392 } UserStatsReceived_t
;
393 #define SW_CBID_UserStatsReceived (k_iSteamUserStatsCallbacks + 1)
395 //-----------------------------------------------------------------------------
396 // Purpose: result of a request to store the user stats for a game
397 //-----------------------------------------------------------------------------
398 typedef struct UserStatsStored_t
400 u64 m_nGameID
; // Game these stats are for
401 EResult m_eResult
; // success / error
403 #define SW_CBID_UserStatsStored (k_iSteamUserStatsCallbacks + 2)
405 //-----------------------------------------------------------------------------
406 // Purpose: result of a request to store the achievements for a game, or an
407 // "indicate progress" call. If both m_nCurProgress and m_nMaxProgress
408 // are zero, that means the achievement has been fully unlocked.
409 //-----------------------------------------------------------------------------
410 typedef struct UserAchievementStored_t
412 u64 m_nGameID
; // Game this is for
413 int m_bGroupAchievement
; // if this is a "group" achievement
414 char m_rgchAchievementName
[k_cchStatNameMax
]; // name of the achievement
415 u32 m_nCurProgress
; // current progress towards the achievement
416 u32 m_nMaxProgress
; // "out of" this many
417 } UserAchievementStored_t
;
418 #define SW_CBID_UserAchievementStored (k_iSteamUserStatsCallbacks + 3)
420 //-----------------------------------------------------------------------------
421 // Purpose: call result for finding a leaderboard, returned as a result of FindOrCreateLeaderboard() or FindLeaderboard()
422 // use CCallResult<> to map this async result to a member function
423 //-----------------------------------------------------------------------------
424 typedef struct LeaderboardFindResult_t
426 SteamLeaderboard_t m_hSteamLeaderboard
; // handle to the leaderboard serarched for, 0 if no leaderboard found
427 u8 m_bLeaderboardFound
; // 0 if no leaderboard found
428 } LeaderboardFindResult_t
;
429 #define SW_CBID_LeaderboardFindResult (k_iSteamUserStatsCallbacks + 4)
431 //-----------------------------------------------------------------------------
432 // Purpose: call result indicating scores for a leaderboard have been downloaded and are ready to be retrieved, returned as a result of DownloadLeaderboardEntries()
433 // use CCallResult<> to map this async result to a member function
434 //-----------------------------------------------------------------------------
435 typedef struct LeaderboardScoresDownloaded_t
437 SteamLeaderboard_t m_hSteamLeaderboard
;
438 SteamLeaderboardEntries_t m_hSteamLeaderboardEntries
; // the handle to pass into GetDownloadedLeaderboardEntries()
439 int m_cEntryCount
; // the number of entries downloaded
440 } LeaderboardScoresDownloaded_t
;
441 #define SW_CBID_LeaderboardScoresDownloaded (k_iSteamUserStatsCallbacks + 5)
443 //-----------------------------------------------------------------------------
444 // Purpose: call result indicating scores has been uploaded, returned as a result of UploadLeaderboardScore()
445 // use CCallResult<> to map this async result to a member function
446 //-----------------------------------------------------------------------------
447 typedef struct LeaderboardScoreUploaded_t
449 u8 m_bSuccess
; // 1 if the call was successful
450 SteamLeaderboard_t m_hSteamLeaderboard
; // the leaderboard handle that was
451 i32 m_nScore
; // the score that was attempted to set
452 u8 m_bScoreChanged
; // true if the score in the leaderboard change, false if the existing score was better
453 int m_nGlobalRankNew
; // the new global rank of the user in this leaderboard
454 int m_nGlobalRankPrevious
; // the previous global rank of the user in this leaderboard; 0 if the user had no existing entry in the leaderboard
455 } LeaderboardScoreUploaded_t
;
456 #define SW_CBID_LeaderboardScoreUploaded (k_iSteamUserStatsCallbacks + 6)
458 typedef struct NumberOfCurrentPlayers_t
460 u8 m_bSuccess
; // 1 if the call was successful
461 i32 m_cPlayers
; // Number of players currently playing
462 } NumberOfCurrentPlayers_t
;
463 #define SW_CBID_NumberOfCurrentPlayers (k_iSteamUserStatsCallbacks + 7)
466 //-----------------------------------------------------------------------------
467 // Purpose: Callback indicating that a user's stats have been unloaded.
468 // Call RequestUserStats again to access stats for this user
469 //-----------------------------------------------------------------------------
470 typedef struct UserStatsUnloaded_t
472 CSteamID m_steamIDUser
; // User whose stats have been unloaded
473 } UserStatsUnloaded_t
;
474 #define SW_CBID_UserStatsUnloaded (k_iSteamUserStatsCallbacks + 8)
477 //-----------------------------------------------------------------------------
478 // Purpose: Callback indicating that an achievement icon has been fetched
479 //-----------------------------------------------------------------------------
480 typedef struct UserAchievementIconFetched_t
482 CGameID m_nGameID
; // Game this is for
483 char m_rgchAchievementName
[k_cchStatNameMax
]; // name of the achievement
484 int m_bAchieved
; // Is the icon for the achieved or not achieved version?
485 int m_nIconHandle
; // Handle to the image, which can be used in SteamUtils()->GetImageRGBA(), 0 means no image is set for the achievement
486 } UserAchievementIconFetched_t
;
487 #define SW_CBID_UserAchievementIconFetched (k_iSteamUserStatsCallbacks + 9)
489 //-----------------------------------------------------------------------------
490 // Purpose: Callback indicating that global achievement percentages are fetched
491 //-----------------------------------------------------------------------------
492 typedef struct GlobalAchievementPercentagesReady_t
494 u64 m_nGameID
; // Game this is for
495 EResult m_eResult
; // Result of the operation
496 } GlobalAchievementPercentagesReady_t
;
497 #define SW_CBID_GlobalAchievementPercentagesReady (k_iSteamUserStatsCallbacks + 10)
499 //-----------------------------------------------------------------------------
500 // Purpose: call result indicating UGC has been uploaded, returned as a result of SetLeaderboardUGC()
501 //-----------------------------------------------------------------------------
502 typedef struct LeaderboardUGCSet_t
504 EResult m_eResult
; // The result of the operation
505 SteamLeaderboard_t m_hSteamLeaderboard
; // the leaderboard handle that was
506 } LeaderboardUGCSet_t
;
507 #define SW_CBID_LeaderboardUGCSet (k_iSteamUserStatsCallbacks + 11)
509 //-----------------------------------------------------------------------------
510 // Purpose: callback indicating that PS3 trophies have been installed
511 //-----------------------------------------------------------------------------
512 typedef struct PS3TrophiesInstalled_t
514 u64 m_nGameID
; // Game these stats are for
515 EResult m_eResult
; // The result of the operation
516 u64 m_ulRequiredDiskSpace
; // If m_eResult is k_EResultDiskFull, will contain the amount of space needed to install trophies
518 } PS3TrophiesInstalled_t
;
519 #define SW_CBID_TrophiesInstalled (k_iSteamUserStatsCallbacks + 12)
521 //-----------------------------------------------------------------------------
522 // Purpose: callback indicating global stats have been received.
523 // Returned as a result of RequestGlobalStats()
524 //-----------------------------------------------------------------------------
525 typedef struct GlobalStatsReceived_t
527 u64 m_nGameID
; // Game global stats were requested for
528 EResult m_eResult
; // The result of the request
529 } GlobalStatsReceived_t
;
530 #define SW_CBID_GlobalStatsReceived (k_iSteamUserStatsCallbacks + 12)
535 void SteamAPI_Shutdown();
537 int SteamAPI_RestartAppIfNecessary( u32 unOwnAppID
);
539 void SteamAPI_ManualDispatch_Init();
540 void SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe
);
541 int SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe
, CallbackMsg_t
*pCallbackMsg
);
542 void SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe
);
543 int SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe
, SteamAPICall_t hSteamAPICall
, void *pCallback
, int cubCallback
, int iCallbackExpected
, int *pbFailed
);
544 void SteamAPI_ReleaseCurrentThreadMemory();
546 int SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats
*self
, const char *pchName
);
548 ESteamAPICallFailure
SteamAPI_ISteamUtils_GetAPICallFailureReason( ISteamUtils
* self
, SteamAPICall_t hSteamAPICall
);
551 char *SteamAPI_ISteamFriends_GetPersonaName( ISteamFriends
*self
);
552 const char *SteamAPI_ISteamFriends_GetFriendPersonaName( ISteamFriends
*self
, u64_steamid steamIDFriend
);
553 u64_steamid
SteamAPI_ISteamUser_GetSteamID( ISteamUser
*self
);
554 int SteamAPI_ISteamFriends_GetSmallFriendAvatar( ISteamFriends
*self
, u64_steamid steamIDFriend
); // 32x32
555 int SteamAPI_ISteamUtils_GetImageSize( ISteamUtils
*self
, int iImage
, u32
*pnWidth
, u32
*pnHeight
);
556 int SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils
*self
, int iImage
, u8
*pubDest
, int nDestBufferSize
);
559 SteamAPICall_t
SteamAPI_ISteamUserStats_FindOrCreateLeaderboard( ISteamUserStats
* self
, const char * pchLeaderboardName
, ELeaderboardSortMethod eLeaderboardSortMethod
, ELeaderboardDisplayType eLeaderboardDisplayType
);
560 SteamAPICall_t
SteamAPI_ISteamUserStats_FindLeaderboard( ISteamUserStats
* self
, const char * pchLeaderboardName
);
561 const char * SteamAPI_ISteamUserStats_GetLeaderboardName( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
);
562 int SteamAPI_ISteamUserStats_GetLeaderboardEntryCount( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
);
563 ELeaderboardSortMethod
SteamAPI_ISteamUserStats_GetLeaderboardSortMethod( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
);
564 ELeaderboardDisplayType
SteamAPI_ISteamUserStats_GetLeaderboardDisplayType( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
);
565 SteamAPICall_t
SteamAPI_ISteamUserStats_DownloadLeaderboardEntries( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
, ELeaderboardDataRequest eLeaderboardDataRequest
, int nRangeStart
, int nRangeEnd
);
566 SteamAPICall_t
SteamAPI_ISteamUserStats_DownloadLeaderboardEntriesForUsers( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
, CSteamID
* prgUsers
, int cUsers
);
567 int SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( ISteamUserStats
* self
, SteamLeaderboardEntries_t hSteamLeaderboardEntries
, int index
, LeaderboardEntry_t
* pLeaderboardEntry
, i32
* pDetails
, int cDetailsMax
);
568 SteamAPICall_t
SteamAPI_ISteamUserStats_UploadLeaderboardScore( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod
, i32 nScore
, const i32
* pScoreDetails
, int cScoreDetailsCount
);
569 SteamAPICall_t
SteamAPI_ISteamUserStats_AttachLeaderboardUGC( ISteamUserStats
* self
, SteamLeaderboard_t hSteamLeaderboard
, UGCHandle_t hUGC
);
571 #define sw_get_image_size(...) SteamAPI_ISteamUtils_GetImageSize( steam_api_classes.utils, __VA_ARGS__ )
572 #define sw_get_image_rgba(...) SteamAPI_ISteamUtils_GetImageRGBA( steam_api_classes.utils, __VA_ARGS__ )
573 #define sw_get_small_friend_avatar(...) SteamAPI_ISteamFriends_GetSmallFriendAvatar( steam_api_classes.friends, __VA_ARGS__ )
574 #define sw_get_steamid() SteamAPI_ISteamUser_GetSteamID( steam_api_classes.friends )
575 #define sw_get_friend_persona_name(...) SteamAPI_ISteamFriends_GetFriendPersonaName( steam_api_classes.friends, __VA_ARGS__ )
576 #define sw_get_persona_name() SteamAPI_ISteamFriends_GetPersonaName( steam_api_classes.friends )
577 #define sw_find_leaderboard(...) SteamAPI_ISteamUserStats_FindLeaderboard( steam_api_classes.stats, __VA_ARGS__ );
578 #define sw_get_leaderboard_name(...) SteamAPI_ISteamUserStats_GetLeaderboardName( steam_api_classes.stats, __VA_ARGS__ )
579 #define sw_download_leaderboard_entries(...) SteamAPI_ISteamUserStats_DownloadLeaderboardEntries( steam_api_classes.stats, __VA_ARGS__ )
580 #define sw_get_downloaded_entry(...) SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( steam_api_classes.stats, __VA_ARGS__ )
581 #define sw_upload_leaderboard_score(...) SteamAPI_ISteamUserStats_UploadLeaderboardScore( steam_api_classes.stats, __VA_ARGS__ )
583 HSteamPipe
SteamAPI_GetHSteamPipe();
584 HSteamUser
SteamAPI_GetHSteamUser();
588 ISteamFriends
*friends
;
590 ISteamUserStats
*stats
;
591 ISteamNetworking
*net
;
599 GLuint avatar_texture
; // tex_unkown.name
601 struct cached_player
*l
, *r
;
605 struct cached_player
*cache_head
, *cache_tail
;
611 static void _sw_cache_push( struct cached_player
*player
)
614 player
->r
= steam_api_classes
.cache_head
;
615 if( steam_api_classes
.cache_head
) steam_api_classes
.cache_head
->l
= player
;
616 if( !steam_api_classes
.cache_tail
) steam_api_classes
.cache_tail
= player
;
617 steam_api_classes
.cache_head
= player
;
618 steam_api_classes
.cache_count
++;
621 static void _sw_cache_evict( struct cached_player
*player
)
623 if( player
== steam_api_classes
.cache_tail
) steam_api_classes
.cache_tail
= player
->l
;
624 if( player
== steam_api_classes
.cache_head
) steam_api_classes
.cache_head
= player
->r
;
625 if( player
->l
) player
->l
->r
= player
->r
;
626 if( player
->r
) player
->r
->l
= player
->l
;
627 steam_api_classes
.cache_count
--;
630 static void _sw_access_cache( struct cached_player
*player
)
632 _sw_cache_evict( player
);
633 _sw_cache_push( player
);
636 static GLuint
sw_get_player_image( u64_steamid usr
)
640 // Look for player in cache
641 for( int i
= 0; i
< steam_api_classes
.cache_count
; i
++ )
643 struct cached_player
*player
= &steam_api_classes
.cached_players
[i
];
645 if( player
->id
== usr
)
647 _sw_access_cache( player
);
648 return player
->avatar_texture
;
652 struct cached_player
*dest
;
654 if( steam_api_classes
.cache_count
== vg_list_size( steam_api_classes
.cached_players
) )
656 dest
= steam_api_classes
.cache_tail
;
657 _sw_access_cache( dest
);
659 // Delete previous before creating a new one
660 glDeleteTextures( 1, &dest
->avatar_texture
);
664 dest
= &steam_api_classes
.cached_players
[ steam_api_classes
.cache_count
];
665 _sw_cache_push( dest
);
669 dest
->avatar_texture
= 0;
675 steam_image
= sw_get_small_friend_avatar( usr
);
679 if( !sw_get_image_size( steam_image
, &x
, &y
) )
682 u8
* img_buf
= (u8
*)malloc( x
* y
* 4 );
684 if( !sw_get_image_rgba(steam_image
, img_buf
, x
* y
* 4) )
690 glGenTextures( 1, &dest
->avatar_texture
);
691 glBindTexture( GL_TEXTURE_2D
, dest
->avatar_texture
);
693 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, x
, y
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, img_buf
);
694 glGenerateMipmap( GL_TEXTURE_2D
);
696 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
697 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
699 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
700 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
704 return dest
->avatar_texture
;
711 ISteamFriends
*SteamAPI_SteamFriends_v017();
712 ISteamUser
*SteamAPI_SteamUser_v021();
713 ISteamUserStats
*SteamAPI_SteamUserStats_v012();
714 ISteamNetworking
*SteamAPI_SteamNetworking_v006();
715 ISteamUtils
*SteamAPI_SteamUtils_v010();
717 static void sw_exit(void)
724 static void sw_free_opengl(void)
726 for( int i
= 0; i
< steam_api_classes
.cache_count
; i
++ )
727 if( steam_api_classes
.cached_players
[i
].avatar_texture
)
728 glDeleteTextures( 1, &steam_api_classes
.cached_players
[i
].avatar_texture
);
731 static int sw_init(void)
734 #if defined(VALVE_CALLBACK_PACK_SMALL)
735 if( sizeof(ValvePackingSentinel_t
) != 24 ){
736 printf( "Struct packing error: ValvePackingSentinel_t expected 24 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t
));
740 if( sizeof(ValvePackingSentinel_t
) != 32 ){
741 printf( "Struct packing error: ValvePackingSentinel_t expected 32 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t
));
746 vg_info( "Intializing steamworks\n" );
748 if( SteamAPI_RestartAppIfNecessary( VG_STEAM_APPID
) == 1 )
750 vg_info( "Restarting app via steam\n" );
754 if( !SteamAPI_Init() )
756 vg_error( "Steamworks connection failed\n" );
760 SteamAPI_ManualDispatch_Init();
762 steam_api_classes
.friends
= SteamAPI_SteamFriends_v017();
763 steam_api_classes
.user
= SteamAPI_SteamUser_v021();
764 steam_api_classes
.stats
= SteamAPI_SteamUserStats_v012();
765 steam_api_classes
.net
= SteamAPI_SteamNetworking_v006();
766 steam_api_classes
.utils
= SteamAPI_SteamUtils_v010();
768 if( !steam_api_classes
.friends
|| !steam_api_classes
.user
|| !steam_api_classes
.stats
|| !steam_api_classes
.net
|| !steam_api_classes
.utils
)
770 vg_error( "Steamworks interface pointers failed. Steamworks DLL may be old\n" );
775 steam_api_classes
.pipe
= SteamAPI_GetHSteamPipe();
776 vg_success( "Steamworks API running\n" );
778 vg_register_exit( &sw_exit
, "SteamAPI" );
786 void (*sw_leaderboard_found
)( LeaderboardFindResult_t
*pCallback
);
787 void (*sw_leaderboard_downloaded
)( LeaderboardScoresDownloaded_t
*pCallback
);
789 static void sw_event_loop(void)
792 SteamAPI_ManualDispatch_RunFrame( steam_api_classes
.pipe
);
793 CallbackMsg_t callback
;
795 while( SteamAPI_ManualDispatch_GetNextCallback( steam_api_classes
.pipe
, &callback
) )
797 vg_info( "steamworks_event::callback( %i )\n", callback
.m_iCallback
);
799 // Check for dispatching API call results
800 if( callback
.m_iCallback
== SW_CBID_SteamAPICallCompleted
){
802 SteamAPICallCompleted_t
*pCallCompleted
= (SteamAPICallCompleted_t
*)callback
.m_pubParam
;
803 void *pTmpCallResult
= malloc( pCallCompleted
->m_cubParam
);
806 if( SteamAPI_ManualDispatch_GetAPICallResult(
807 steam_api_classes
.pipe
,
808 pCallCompleted
->m_hAsyncCall
,
810 pCallCompleted
->m_cubParam
,
811 pCallCompleted
->m_iCallback
,
815 // Dispatch the call result to the registered handler(s) for the
816 // call identified by pCallCompleted->m_hAsyncCall
818 vg_info( "steamworks_event::api_call_completed( %lu )\n", pCallCompleted
->m_hAsyncCall
);
820 switch( pCallCompleted
->m_iCallback
)
822 case SW_CBID_LeaderboardFindResult
:
823 if( sw_leaderboard_found
) sw_leaderboard_found( (LeaderboardFindResult_t
*)pTmpCallResult
);
825 case SW_CBID_LeaderboardScoresDownloaded
:
826 if( sw_leaderboard_downloaded
) sw_leaderboard_downloaded( (LeaderboardScoresDownloaded_t
*)pTmpCallResult
);
833 typedef enum ESteamAPICallFailure
835 k_ESteamAPICallFailureNone
= -1, // no failure
836 k_ESteamAPICallFailureSteamGone
= 0, // the local Steam process has gone away
837 k_ESteamAPICallFailureNetworkFailure
= 1, // the network connection to Steam has been broken, or was already broken
838 // SteamServersDisconnected_t callback will be sent around the same time
839 // SteamServersConnected_t will be sent when the client is able to talk to the Steam servers again
840 k_ESteamAPICallFailureInvalidHandle
= 2, // the SteamAPICall_t handle passed in no longer exists
841 k_ESteamAPICallFailureMismatchedCallback
= 3,// GetAPICallResult() was called with the wrong callback type for this API call
842 } ESteamAPICallFailure
;
844 ESteamAPICallFailure fail_why
=
845 SteamAPI_ISteamUtils_GetAPICallFailureReason( steam_api_classes
.utils
, pCallCompleted
->m_hAsyncCall
);
847 vg_error( "steamworks_event: error getting call result on %lu (code %d)\n", pCallCompleted
->m_hAsyncCall
, fail_why
);
850 free( pTmpCallResult
);
854 // Look at callback.m_iCallback to see what kind of callback it is,
855 // and dispatch to appropriate handler(s)
856 //void *data = callback.m_pubParam;
858 switch( callback
.m_iCallback
)
864 SteamAPI_ManualDispatch_FreeLastCallback( steam_api_classes
.pipe
);
869 static void sw_set_achievement( const char *vg_ach_name
)
871 struct vg_achievement
*ach
= NULL
;
873 for( int i
= 0; i
< vg_list_size( vg_achievements
); i
++ )
874 if( !strcmp( vg_ach_name
, vg_achievements
[i
].name
) )
875 ach
= &vg_achievements
[i
];
880 SteamAPI_ISteamUserStats_SetAchievement( steam_api_classes
.stats
, vg_ach_name
);
883 vg_success( "Achievement set: '%s'\n", vg_ach_name
);