8 * TODO: Combine interfaces and stuff here instead of having them in client code
11 #if defined(__linux__) || defined(__APPLE__)
13 * The 32-bit version of gcc has the alignment requirement for u64 and double
14 * set to 4 meaning that even with #pragma pack(8) these types will only be
15 * four-byte aligned. The 64-bit version of gcc has the alignment requirement
16 * for these types set to 8 meaning that unless we use #pragma pack(4) our
17 * structures will get bigger. The 64-bit structure packing has to match the
18 * 32-bit structure packing for each platform.
20 #define VALVE_CALLBACK_PACK_SMALL
22 #pragma pack( push, 4 )
24 #define VALVE_CALLBACK_PACK_LARGE
25 #pragma pack( push, 8 )
28 typedef i32 HSteamPipe
;
29 typedef i32 HSteamUser
;
31 typedef int E_iCallBack_t
;
33 typedef u64 u64_steamid
;
34 typedef u64 SteamAPICall_t
;
37 const AppId_t k_uAppIdInvalid
= 0x0;
39 typedef u32 DepotId_t
;
40 const DepotId_t k_uDepotIdInvalid
= 0x0;
43 typedef u32 AccountID_t
;
45 enum { k_iSteamUserCallbacks
= 100 };
46 enum { k_iSteamGameServerCallbacks
= 200 };
47 enum { k_iSteamFriendsCallbacks
= 300 };
48 enum { k_iSteamBillingCallbacks
= 400 };
49 enum { k_iSteamMatchmakingCallbacks
= 500 };
50 enum { k_iSteamContentServerCallbacks
= 600 };
51 enum { k_iSteamUtilsCallbacks
= 700 };
52 enum { k_iClientFriendsCallbacks
= 800 };
53 enum { k_iClientUserCallbacks
= 900 };
54 enum { k_iSteamAppsCallbacks
= 1000 };
55 enum { k_iSteamUserStatsCallbacks
= 1100 };
56 enum { k_iSteamNetworkingCallbacks
= 1200 };
57 enum { k_iSteamNetworkingSocketsCallbacks
= 1220 };
58 enum { k_iSteamNetworkingMessagesCallbacks
= 1250 };
59 enum { k_iSteamNetworkingUtilsCallbacks
= 1280 };
60 enum { k_iSteamRemoteStorageCallbacks
= 1300 };
61 enum { k_iClientDepotBuilderCallbacks
= 1400 };
62 enum { k_iSteamGameServerItemsCallbacks
= 1500 };
63 enum { k_iClientUtilsCallbacks
= 1600 };
64 enum { k_iSteamGameCoordinatorCallbacks
= 1700 };
65 enum { k_iSteamGameServerStatsCallbacks
= 1800 };
66 enum { k_iSteam2AsyncCallbacks
= 1900 };
67 enum { k_iSteamGameStatsCallbacks
= 2000 };
68 enum { k_iClientHTTPCallbacks
= 2100 };
69 enum { k_iClientScreenshotsCallbacks
= 2200 };
70 enum { k_iSteamScreenshotsCallbacks
= 2300 };
71 enum { k_iClientAudioCallbacks
= 2400 };
72 enum { k_iClientUnifiedMessagesCallbacks
= 2500 };
73 enum { k_iSteamStreamLauncherCallbacks
= 2600 };
74 enum { k_iClientControllerCallbacks
= 2700 };
75 enum { k_iSteamControllerCallbacks
= 2800 };
76 enum { k_iClientParentalSettingsCallbacks
= 2900 };
77 enum { k_iClientDeviceAuthCallbacks
= 3000 };
78 enum { k_iClientNetworkDeviceManagerCallbacks
= 3100 };
79 enum { k_iClientMusicCallbacks
= 3200 };
80 enum { k_iClientRemoteClientManagerCallbacks
= 3300 };
81 enum { k_iClientUGCCallbacks
= 3400 };
82 enum { k_iSteamUGCCallbacks
= 3400 };
83 enum { k_iSteamStreamClientCallbacks
= 3500 };
84 enum { k_IClientProductBuilderCallbacks
= 3600 };
85 enum { k_iClientShortcutsCallbacks
= 3700 };
86 enum { k_iClientRemoteControlManagerCallbacks
= 3800 };
87 enum { k_iSteamAppListCallbacks
= 3900 };
88 enum { k_iSteamMusicCallbacks
= 4000 };
89 enum { k_iSteamMusicRemoteCallbacks
= 4100 };
90 enum { k_iClientVRCallbacks
= 4200 };
91 enum { k_iClientGameNotificationCallbacks
= 4300 };
92 enum { k_iSteamGameNotificationCallbacks
= 4400 };
93 enum { k_iSteamHTMLSurfaceCallbacks
= 4500 };
94 enum { k_iClientVideoCallbacks
= 4600 };
95 enum { k_iClientInventoryCallbacks
= 4700 };
96 enum { k_iClientBluetoothManagerCallbacks
= 4800 };
97 enum { k_iClientSharedConnectionCallbacks
= 4900 };
98 enum { k_ISteamParentalSettingsCallbacks
= 5000 };
99 enum { k_iClientShaderCallbacks
= 5100 };
100 enum { k_iSteamGameSearchCallbacks
= 5200 };
101 enum { k_iSteamPartiesCallbacks
= 5300 };
102 enum { k_iClientPartiesCallbacks
= 5400 };
103 enum { k_iSteamSTARCallbacks
= 5500 };
104 enum { k_iClientSTARCallbacks
= 5600 };
105 enum { k_iSteamRemotePlayCallbacks
= 5700 };
106 enum { k_iClientCompatCallbacks
= 5800 };
107 enum { k_iSteamChatCallbacks
= 5900 };
109 // General result codes
112 k_EResultNone
= 0, // no result
113 k_EResultOK
= 1, // success
114 k_EResultFail
= 2, // generic failure
115 k_EResultNoConnection
= 3, // no/failed network connection
116 // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
117 k_EResultInvalidPassword
= 5, // password/ticket is invalid
118 k_EResultLoggedInElsewhere
= 6, // same user logged in elsewhere
119 k_EResultInvalidProtocolVer
= 7, // protocol version is incorrect
120 k_EResultInvalidParam
= 8, // a parameter is incorrect
121 k_EResultFileNotFound
= 9, // file was not found
122 k_EResultBusy
= 10, // called method busy - action not taken
123 k_EResultInvalidState
= 11, // called object was in an invalid state
124 k_EResultInvalidName
= 12, // name is invalid
125 k_EResultInvalidEmail
= 13, // email is invalid
126 k_EResultDuplicateName
= 14, // name is not unique
127 k_EResultAccessDenied
= 15, // access is denied
128 k_EResultTimeout
= 16, // operation timed out
129 k_EResultBanned
= 17, // VAC2 banned
130 k_EResultAccountNotFound
= 18, // account not found
131 k_EResultInvalidSteamID
= 19, // steamID is invalid
132 k_EResultServiceUnavailable
= 20,// The requested service is currently
134 k_EResultNotLoggedOn
= 21, // The user is not logged on
135 k_EResultPending
= 22, // Request is pending (may be in process, or
136 // waiting on third party)
137 k_EResultEncryptionFailure
= 23, // Encryption or Decryption failed
138 k_EResultInsufficientPrivilege
= 24,// Insufficient privilege
139 k_EResultLimitExceeded
= 25, // Too much of a good thing
140 k_EResultRevoked
= 26, // Access has been revoked (used for revoked
142 k_EResultExpired
= 27, // License/Guest pass the user is trying to
144 k_EResultAlreadyRedeemed
= 28, // Guest pass has already been redeemed by
145 // account, cannot be acked again
146 k_EResultDuplicateRequest
= 29, // The request is a duplicate and the action
147 // has already occurred in the past, ignored
149 k_EResultAlreadyOwned
= 30, // All the games in this guest pass
150 // redemption request are already owned by
152 k_EResultIPNotFound
= 31, // IP address not found
153 k_EResultPersistFailed
= 32, // failed to write change to the data store
154 k_EResultLockingFailed
= 33, // failed to acquire access lock for this
156 k_EResultLogonSessionReplaced
= 34,
157 k_EResultConnectFailed
= 35,
158 k_EResultHandshakeFailed
= 36,
159 k_EResultIOFailure
= 37,
160 k_EResultRemoteDisconnect
= 38,
161 k_EResultShoppingCartNotFound
= 39, // failed to find the shopping cart
163 k_EResultBlocked
= 40, // a user didn't allow it
164 k_EResultIgnored
= 41, // target is ignoring sender
165 k_EResultNoMatch
= 42, // nothing matching the request found
166 k_EResultAccountDisabled
= 43,
167 k_EResultServiceReadOnly
= 44, // this service is not accepting content
169 k_EResultAccountNotFeatured
= 45, // account doesn't have value, so this
170 // feature isn't available
171 k_EResultAdministratorOK
= 46, // allowed to take this action, but only
172 // because requester is admin
173 k_EResultContentVersion
= 47, // A Version mismatch in content
174 // transmitted within the Steam protocol.
175 k_EResultTryAnotherCM
= 48, // The current CM can't service the user
176 // making a request, user should try
178 k_EResultPasswordRequiredToKickSession
= 49, // You are already logged in
179 // elsewhere, this cached credential
181 k_EResultAlreadyLoggedInElsewhere
= 50, // You are already logged in
182 // elsewhere, you must wait
183 k_EResultSuspended
= 51, // Long running operation (content download)
185 k_EResultCancelled
= 52, // Operation canceled (typically by user:
187 k_EResultDataCorruption
= 53, // Operation canceled because data is ill
188 // formed or unrecoverable
189 k_EResultDiskFull
= 54, // Operation canceled - not enough disk space.
190 k_EResultRemoteCallFailed
= 55, // an remote call or IPC call failed
191 k_EResultPasswordUnset
= 56, // Password could not be verified as it's
193 k_EResultExternalAccountUnlinked
= 57, // External account (PSN, Facebook...)
194 // is not linked to a Steam account
195 k_EResultPSNTicketInvalid
= 58, // PSN ticket was invalid
196 k_EResultExternalAccountAlreadyLinked
= 59, // External account (PSN,
197 // Facebook...) is already linked to some other account,
198 // must explicitly request to replace/delete the link first
199 k_EResultRemoteFileConflict
= 60, // The sync cannot resume due to a conflict
200 // between the local and remote files
201 k_EResultIllegalPassword
= 61, // The requested new password is not legal
202 k_EResultSameAsPreviousValue
= 62,// new value is the same as the old one (
203 // secret question and answer )
204 k_EResultAccountLogonDenied
= 63, // account login denied due to 2nd factor
205 // authentication failure
206 k_EResultCannotUseOldPassword
= 64, // The requested new password is not
208 k_EResultInvalidLoginAuthCode
= 65, // account login denied due to auth code
210 k_EResultAccountLogonDeniedNoMail
= 66, // account login denied due to 2nd
211 // factor auth failure - and no mail
213 k_EResultHardwareNotCapableOfIPT
= 67,
214 k_EResultIPTInitError
= 68,
215 k_EResultParentalControlRestricted
= 69,// operation failed due to parental
216 // control restrictions for current
218 k_EResultFacebookQueryError
= 70, // Facebook query returned an error
219 k_EResultExpiredLoginAuthCode
= 71, // account login denied due to auth
221 k_EResultIPLoginRestrictionFailed
= 72,
222 k_EResultAccountLockedDown
= 73,
223 k_EResultAccountLogonDeniedVerifiedEmailRequired
= 74,
224 k_EResultNoMatchingURL
= 75,
225 k_EResultBadResponse
= 76, // parse failure, missing field, etc.
226 k_EResultRequirePasswordReEntry
= 77, // The user cannot complete the action
227 // until they re-enter their password
228 k_EResultValueOutOfRange
= 78, // the value entered is outside the
230 k_EResultUnexpectedError
= 79, // something happened that we didn't expect
232 k_EResultDisabled
= 80, // The requested service has been configured
234 k_EResultInvalidCEGSubmission
= 81, // The set of files submitted to the CEG
235 // server are not valid !
236 k_EResultRestrictedDevice
= 82, // The device being used is not allowed
237 // to perform this action
238 k_EResultRegionLocked
= 83, // The action could not be complete
239 // because it is region restricted
240 k_EResultRateLimitExceeded
= 84, // Temporary rate limit exceeded, try
241 // again later, different from
242 // k_EResultLimitExceeded which may be
244 k_EResultAccountLoginDeniedNeedTwoFactor
= 85, // Need two-factor code to
246 k_EResultItemDeleted
= 86, // The thing we're trying to access has been
248 k_EResultAccountLoginDeniedThrottle
= 87, // login attempt failed, try to
249 // throttle response to possible
251 k_EResultTwoFactorCodeMismatch
= 88, // two factor code mismatch
252 k_EResultTwoFactorActivationCodeMismatch
= 89, // activation code for
253 // two-factor didn't match
254 k_EResultAccountAssociatedToMultiplePartners
= 90, // account has been
255 // associated with multiple partners
256 k_EResultNotModified
= 91, // data not modified
257 k_EResultNoMobileDevice
= 92, // the account does not have a mobile
258 // device associated with it
259 k_EResultTimeNotSynced
= 93, // the time presented is out of range or
261 k_EResultSmsCodeFailed
= 94, // SMS code failure (no match, none pending,
263 k_EResultAccountLimitExceeded
= 95, // Too many accounts access this resource
264 k_EResultAccountActivityLimitExceeded
= 96,// Too many changes to
266 k_EResultPhoneActivityLimitExceeded
= 97, // Too many changes to this phone
267 k_EResultRefundToWallet
= 98, // Cannot refund to payment method, must use
269 k_EResultEmailSendFailure
= 99, // Cannot send an email
270 k_EResultNotSettled
= 100, // Can't perform operation till payment
272 k_EResultNeedCaptcha
= 101,// Needs to provide a valid captcha
273 k_EResultGSLTDenied
= 102, // a game server login token owned by this token's
274 // owner has been banned
275 k_EResultGSOwnerDenied
= 103, // game server owner is denied for other reason
276 // (account lock, community ban, vac ban, missing phone)
277 k_EResultInvalidItemType
= 104,// the type of thing we were requested to act
279 k_EResultIPBanned
= 105,// the ip address has been banned from taking this
281 k_EResultGSLTExpired
= 106,// this token has expired from disuse; can be
283 k_EResultInsufficientFunds
= 107,// user doesn't have enough wallet funds to
284 // complete the action
285 k_EResultTooManyPending
= 108, // There are too many of this thing pending
287 k_EResultNoSiteLicensesFound
= 109, // No site licenses found
288 k_EResultWGNetworkSendExceeded
= 110,// the WG couldn't send a response
289 // because we exceeded max network send size
290 k_EResultAccountNotFriends
= 111, // the user is not mutually friends
291 k_EResultLimitedUserAccount
= 112,// the user is limited
292 k_EResultCantRemoveItem
= 113, // item can't be removed
293 k_EResultAccountDeleted
= 114, // account has been deleted
294 k_EResultExistingUserCancelledLicense
= 115,
295 // A license for this already exists, but cancelled
296 k_EResultCommunityCooldown
= 116, // access is denied because of a
297 // community cooldown (probably from support profile data resets)
298 k_EResultNoLauncherSpecified
= 117, // No launcher was specified, but a
299 // launcher was needed to choose correct realm for operation.
300 k_EResultMustAgreeToSSA
= 118,// User must agree to china SSA or global SSA
302 k_EResultLauncherMigrated
= 119, // The specified launcher type is no longer
303 // supported; the user should be directed elsewhere
304 k_EResultSteamRealmMismatch
= 120, // The user's realm does not match the
305 // realm of the requested resource
306 k_EResultInvalidSignature
= 121, // signature check did not match
307 k_EResultParseFailure
= 122, // Failed to parse input
308 k_EResultNoVerifiedPhone
= 123, // account does not have a verified phone
314 HSteamUser m_hSteamUser
; // Specific user to whom this callback applies.
316 u8
*m_pubParam
; // Points to the callback structure
317 int m_cubParam
; // Size of the data pointed to by m_pubParam
323 SteamAPICall_t m_hAsyncCall
;
327 } SteamAPICallCompleted_t
;
329 enum { k_iSteamAPICallCompleted
= k_iSteamUtilsCallbacks
+ 3 };
331 // Steam universes. Each universe is a self-contained Steam instance.
333 k_EUniverseInvalid
= 0,
334 k_EUniversePublic
= 1,
336 k_EUniverseInternal
= 3,
338 // k_EUniverseRC = 5, // no such universe anymore
342 struct SteamIDComponent_t
344 #ifdef VALVE_BIG_ENDIAN
345 EUniverse_t m_EUniverse
: 8
346 unsigned int m_EAccountType
: 4;
347 unsigned int m_unAccountInstance
: 20;
348 u32 m_unAccountID
: 32;
350 u32 m_unAccountID
: 32;
351 unsigned int m_unAccountInstance
: 20;
352 unsigned int m_EAccountType
: 4;
353 EUniverse_t m_EUniverse
: 8;
362 struct SteamIDComponent_t m_comp
;
368 typedef struct GameID_t
370 #ifdef VALVE_BIG_ENDIAN
371 unsigned int m_nModID
: 32;
372 unsigned int m_nType
: 8;
373 unsigned int m_nAppID
: 24;
375 unsigned int m_nAppID
: 24;
376 unsigned int m_nType
: 8;
377 unsigned int m_nModID
: 32;
385 * =============================================================================
388 int SteamAPI_RestartAppIfNecessary( u32 unOwnAppID
);
389 int SteamAPI_Init(void);
390 void SteamAPI_Shutdown(void);
394 * =============================================================================
397 typedef enum EServerMode EServerMode
;
400 eServerModeInvalid
= 0,
401 eServerModeNoAuthentication
= 1,
402 eServerModeAuthentication
= 2,
403 eServerModeAuthenticationAndSecure
= 3,
406 int SteamInternal_GameServer_Init( u32 unIP
, u16 usLegacySteamPort
,
407 u16 usGamePort
, u16 usQueryPort
,
408 EServerMode eServerMode
,
409 const char *pchVersionString
);
411 /* Initialize SteamGameServer client and interface objects, and set server
412 * properties which may not be changed.
413 * After calling this function, you should set any additional server parameters,
414 * and then call ISteamGameServer::LogOnAnonymous() or ISteamGameServer::LogOn()
416 * - unIP will usually be zero. If you are on a machine with multiple IP
417 * addresses, you can pass a non-zero value here and the relevant sockets will
418 * be bound to that IP. This can be used to ensure that the IP you desire is
419 * the one used in the server browser.
420 * - usGamePort is the port that clients will connect to for gameplay. You will
421 * usually open up your own socket bound to this port.
422 * - usQueryPort is the port that will manage server browser related duties and
423 * info pings from clients. If you pass STEAMGAMESERVER_QUERY_PORT_SHARED for
424 * usQueryPort, then it will use "GameSocketShare" mode, which means that the
425 * game is responsible for sending and receiving UDP packets for the master
426 * server updater. (See ISteamGameServer::HandleIncomingPacket and
427 * ISteamGameServer::GetNextOutgoingPacket.)
428 * - The version string should be in the form x.x.x.x, and is used by the master
429 * server to detect when the server is out of date. (Only servers with the
430 * latest version will be listed.)
432 int SteamGameServer_Init( u32 unIP
, u16 usGamePort
, u16 usQueryPort
,
433 EServerMode eServerMode
,
434 const char *pchVersionString
)
436 return SteamInternal_GameServer_Init( unIP
, 0, usGamePort
, usQueryPort
,
437 eServerMode
, pchVersionString
);
441 void *SteamAPI_SteamGameServer_v014(void);
442 void *SteamAPI_SteamGameServer(void)
444 return SteamAPI_SteamGameServer_v014();
447 void SteamAPI_ISteamGameServer_LogOnAnonymous( void* self
);
449 void SteamGameServer_Shutdown(void);
451 int SteamGameServer_BSecure(void);
452 u64
SteamGameServer_GetSteamID(void);
456 * =============================================================================
459 typedef struct vg_steam_async_call vg_steam_async_call
;
460 typedef struct vg_steam_callback_handler vg_steam_callback_handler
;
463 struct vg_steam_async_call
{
467 void (*p_handler
)( void *result
, void *userdata
);
472 struct vg_steam_callback_handler
{
474 void (*p_handler
)( CallbackMsg_t
*msg
);
476 callback_handlers
[32];
477 u32 callback_handler_count
;
481 vg_steam_async_call
*vg_alloc_async_steam_api_call(void)
483 if( vg_steam
.call_count
== vg_list_size(vg_steam
.calls
) ){
484 vg_fatal_error( "Maximum concurrent API calls exceeded (%u)\n",
485 vg_steam
.call_count
);
488 return &vg_steam
.calls
[ vg_steam
.call_count
++ ];
493 * =============================================================================
496 static void steam_register_callback( u32 id
,
497 void (*p_handler
)( CallbackMsg_t
*msg
) )
499 if( vg_steam
.callback_handler_count
==
500 vg_list_size(vg_steam
.callback_handlers
) )
502 vg_fatal_error( "Too many steam callback handlers registered (%u)\n",
503 vg_steam
.callback_handler_count
);
506 vg_steam_callback_handler
*handler
=
507 &vg_steam
.callback_handlers
[ vg_steam
.callback_handler_count
++ ];
509 handler
->p_handler
= p_handler
;
510 handler
->callback_id
= id
;
515 * =============================================================================
517 HSteamPipe
SteamAPI_GetHSteamPipe(void);
518 HSteamPipe
SteamGameServer_GetHSteamPipe(void);
519 HSteamUser
SteamAPI_GetHSteamUser(void);
520 void SteamAPI_ManualDispatch_Init(void);
521 void SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe
);
522 int SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe
,
523 CallbackMsg_t
*pCallbackMsg
);
524 void SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe
);
525 int SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe
,
526 SteamAPICall_t hSteamAPICall
, void *pCallback
, int cubCallback
,
527 int iCallbackExpected
, int *pbFailed
);
529 void SteamAPI_ReleaseCurrentThreadMemory(void);
531 static void steamworks_process_api_call( HSteamPipe pipe
,
532 CallbackMsg_t
*callback
)
534 SteamAPICallCompleted_t
*pCallCompleted
=
535 (SteamAPICallCompleted_t
*)callback
->m_pubParam
;
538 void *call_data
= alloca( pCallCompleted
->m_cubParam
);
540 if( SteamAPI_ManualDispatch_GetAPICallResult(
542 pCallCompleted
->m_hAsyncCall
,
544 pCallCompleted
->m_cubParam
,
545 pCallCompleted
->m_iCallback
,
550 * Dispatch the call result to the registered handler(s) for the
551 * call identified by pCallCompleted->m_hAsyncCall
554 vg_info( "steamworks_event::api_call_completed( %lu )\n",
555 pCallCompleted
->m_hAsyncCall
);
558 for( int i
=0; i
<vg_steam
.call_count
; i
++ ){
559 if( vg_steam
.calls
[i
].id
!= pCallCompleted
->m_hAsyncCall
){
560 vg_steam
.calls
[j
++] = vg_steam
.calls
[i
];
563 vg_steam_async_call
*call
= &vg_steam
.calls
[i
];
564 call
->p_handler( call_data
, call
->userdata
);
568 if( vg_steam
.call_count
== j
){
569 vg_error( "No tracker was register for API call\n" );
572 vg_steam
.call_count
= j
;
577 typedef enum ESteamAPICallFailure
579 k_ESteamAPICallFailureNone
= -1,
580 k_ESteamAPICallFailureSteamGone
= 0,
581 k_ESteamAPICallFailureNetworkFailure
= 1,
582 k_ESteamAPICallFailureInvalidHandle
= 2,
583 k_ESteamAPICallFailureMismatchedCallback
= 3,
586 ESteamAPICallFailure
;
587 ESteamAPICallFailure fail_why
=
588 SteamAPI_ISteamUtils_GetAPICallFailureReason(
589 steam_api_classes
.utils
, pCallCompleted
->m_hAsyncCall
);
591 vg_error( "steamworks_event: error getting call result on"
593 pCallCompleted
->m_hAsyncCall
, fail_why
);
598 static void steamworks_event_loop( HSteamPipe pipe
)
600 SteamAPI_ManualDispatch_RunFrame( pipe
);
601 CallbackMsg_t callback
;
603 while( SteamAPI_ManualDispatch_GetNextCallback( pipe
, &callback
) ){
604 vg_low( "steamworks_event::callback( %i )\n", callback
.m_iCallback
);
606 /* Check for dispatching API call results */
607 if( callback
.m_iCallback
== k_iSteamAPICallCompleted
){
608 steamworks_process_api_call( pipe
, &callback
);
612 * Look at callback.m_iCallback to see what kind of callback it is,
613 * and dispatch to appropriate handler(s)
614 * void *data = callback.m_pubParam;
617 for( int i
=0; i
<vg_steam
.callback_handler_count
; i
++ ){
618 vg_steam_callback_handler
*handler
= &vg_steam
.callback_handlers
[i
];
619 if( handler
->callback_id
== callback
.m_iCallback
){
620 handler
->p_handler( &callback
);
626 SteamAPI_ManualDispatch_FreeLastCallback( pipe
);
631 * This is required to run the server outside of steamcmd environment.
632 * It can be any appid but idealy the one that is actually your game
634 static void steamworks_ensure_txt( const char *appid_str
)
636 FILE *txt
= fopen("steam_appid.txt", "w");
637 fputs( appid_str
, txt
);
641 #endif /* VG_STEAM_H */