2019-04-14 00:21:56 +08:00
//========= Copyright <20> 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose:
//
//=============================================================================
# ifndef STEAMCLIENTPUBLIC_H
# define STEAMCLIENTPUBLIC_H
# ifdef STEAM_WIN32
# pragma once
# endif
//lint -save -e1931 -e1927 -e1924 -e613 -e726
// This header file defines the interface between the calling application and the code that
// knows how to communicate with the connection manager (CM) from the Steam service
// This header file is intended to be portable; ideally this 1 header file plus a lib or dll
// is all you need to integrate the client library into some other tree. So please avoid
// including or requiring other header files if possible. This header should only describe the
// interface layer, no need to include anything about the implementation.
# include "steamtypes.h"
# include "steamuniverse.h"
// General result codes
enum EResult
{
2019-12-10 01:49:55 +08:00
k_EResultNone = 0 , // no result
2019-04-14 00:21:56 +08:00
k_EResultOK = 1 , // success
k_EResultFail = 2 , // generic failure
k_EResultNoConnection = 3 , // no/failed network connection
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
k_EResultInvalidPassword = 5 , // password/ticket is invalid
k_EResultLoggedInElsewhere = 6 , // same user logged in elsewhere
k_EResultInvalidProtocolVer = 7 , // protocol version is incorrect
k_EResultInvalidParam = 8 , // a parameter is incorrect
k_EResultFileNotFound = 9 , // file was not found
k_EResultBusy = 10 , // called method busy - action not taken
k_EResultInvalidState = 11 , // called object was in an invalid state
k_EResultInvalidName = 12 , // name is invalid
k_EResultInvalidEmail = 13 , // email is invalid
k_EResultDuplicateName = 14 , // name is not unique
k_EResultAccessDenied = 15 , // access is denied
k_EResultTimeout = 16 , // operation timed out
k_EResultBanned = 17 , // VAC2 banned
k_EResultAccountNotFound = 18 , // account not found
k_EResultInvalidSteamID = 19 , // steamID is invalid
k_EResultServiceUnavailable = 20 , // The requested service is currently unavailable
k_EResultNotLoggedOn = 21 , // The user is not logged on
k_EResultPending = 22 , // Request is pending (may be in process, or waiting on third party)
k_EResultEncryptionFailure = 23 , // Encryption or Decryption failed
k_EResultInsufficientPrivilege = 24 , // Insufficient privilege
k_EResultLimitExceeded = 25 , // Too much of a good thing
k_EResultRevoked = 26 , // Access has been revoked (used for revoked guest passes)
k_EResultExpired = 27 , // License/Guest pass the user is trying to access is expired
k_EResultAlreadyRedeemed = 28 , // Guest pass has already been redeemed by account, cannot be acked again
k_EResultDuplicateRequest = 29 , // The request is a duplicate and the action has already occurred in the past, ignored this time
k_EResultAlreadyOwned = 30 , // All the games in this guest pass redemption request are already owned by the user
k_EResultIPNotFound = 31 , // IP address not found
k_EResultPersistFailed = 32 , // failed to write change to the data store
k_EResultLockingFailed = 33 , // failed to acquire access lock for this operation
k_EResultLogonSessionReplaced = 34 ,
k_EResultConnectFailed = 35 ,
k_EResultHandshakeFailed = 36 ,
k_EResultIOFailure = 37 ,
k_EResultRemoteDisconnect = 38 ,
k_EResultShoppingCartNotFound = 39 , // failed to find the shopping cart requested
k_EResultBlocked = 40 , // a user didn't allow it
k_EResultIgnored = 41 , // target is ignoring sender
k_EResultNoMatch = 42 , // nothing matching the request found
k_EResultAccountDisabled = 43 ,
k_EResultServiceReadOnly = 44 , // this service is not accepting content changes right now
k_EResultAccountNotFeatured = 45 , // account doesn't have value, so this feature isn't available
k_EResultAdministratorOK = 46 , // allowed to take this action, but only because requester is admin
k_EResultContentVersion = 47 , // A Version mismatch in content transmitted within the Steam protocol.
k_EResultTryAnotherCM = 48 , // The current CM can't service the user making a request, user should try another.
k_EResultPasswordRequiredToKickSession = 49 , // You are already logged in elsewhere, this cached credential login has failed.
k_EResultAlreadyLoggedInElsewhere = 50 , // You are already logged in elsewhere, you must wait
k_EResultSuspended = 51 , // Long running operation (content download) suspended/paused
k_EResultCancelled = 52 , // Operation canceled (typically by user: content download)
k_EResultDataCorruption = 53 , // Operation canceled because data is ill formed or unrecoverable
k_EResultDiskFull = 54 , // Operation canceled - not enough disk space.
k_EResultRemoteCallFailed = 55 , // an remote call or IPC call failed
k_EResultPasswordUnset = 56 , // Password could not be verified as it's unset server side
k_EResultExternalAccountUnlinked = 57 , // External account (PSN, Facebook...) is not linked to a Steam account
k_EResultPSNTicketInvalid = 58 , // PSN ticket was invalid
k_EResultExternalAccountAlreadyLinked = 59 , // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
k_EResultRemoteFileConflict = 60 , // The sync cannot resume due to a conflict between the local and remote files
k_EResultIllegalPassword = 61 , // The requested new password is not legal
k_EResultSameAsPreviousValue = 62 , // new value is the same as the old one ( secret question and answer )
k_EResultAccountLogonDenied = 63 , // account login denied due to 2nd factor authentication failure
k_EResultCannotUseOldPassword = 64 , // The requested new password is not legal
k_EResultInvalidLoginAuthCode = 65 , // account login denied due to auth code invalid
k_EResultAccountLogonDeniedNoMail = 66 , // account login denied due to 2nd factor auth failure - and no mail has been sent
k_EResultHardwareNotCapableOfIPT = 67 , //
k_EResultIPTInitError = 68 , //
k_EResultParentalControlRestricted = 69 , // operation failed due to parental control restrictions for current user
k_EResultFacebookQueryError = 70 , // Facebook query returned an error
k_EResultExpiredLoginAuthCode = 71 , // account login denied due to auth code expired
k_EResultIPLoginRestrictionFailed = 72 ,
k_EResultAccountLockedDown = 73 ,
k_EResultAccountLogonDeniedVerifiedEmailRequired = 74 ,
k_EResultNoMatchingURL = 75 ,
k_EResultBadResponse = 76 , // parse failure, missing field, etc.
k_EResultRequirePasswordReEntry = 77 , // The user cannot complete the action until they re-enter their password
k_EResultValueOutOfRange = 78 , // the value entered is outside the acceptable range
k_EResultUnexpectedError = 79 , // something happened that we didn't expect to ever happen
k_EResultDisabled = 80 , // The requested service has been configured to be unavailable
k_EResultInvalidCEGSubmission = 81 , // The set of files submitted to the CEG server are not valid !
k_EResultRestrictedDevice = 82 , // The device being used is not allowed to perform this action
k_EResultRegionLocked = 83 , // The action could not be complete because it is region restricted
k_EResultRateLimitExceeded = 84 , // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
k_EResultAccountLoginDeniedNeedTwoFactor = 85 , // Need two-factor code to login
k_EResultItemDeleted = 86 , // The thing we're trying to access has been deleted
k_EResultAccountLoginDeniedThrottle = 87 , // login attempt failed, try to throttle response to possible attacker
k_EResultTwoFactorCodeMismatch = 88 , // two factor code mismatch
k_EResultTwoFactorActivationCodeMismatch = 89 , // activation code for two-factor didn't match
k_EResultAccountAssociatedToMultiplePartners = 90 , // account has been associated with multiple partners
k_EResultNotModified = 91 , // data not modified
k_EResultNoMobileDevice = 92 , // the account does not have a mobile device associated with it
k_EResultTimeNotSynced = 93 , // the time presented is out of range or tolerance
k_EResultSmsCodeFailed = 94 , // SMS code failure (no match, none pending, etc.)
k_EResultAccountLimitExceeded = 95 , // Too many accounts access this resource
k_EResultAccountActivityLimitExceeded = 96 , // Too many changes to this account
k_EResultPhoneActivityLimitExceeded = 97 , // Too many changes to this phone
k_EResultRefundToWallet = 98 , // Cannot refund to payment method, must use wallet
k_EResultEmailSendFailure = 99 , // Cannot send an email
k_EResultNotSettled = 100 , // Can't perform operation till payment has settled
k_EResultNeedCaptcha = 101 , // Needs to provide a valid captcha
k_EResultGSLTDenied = 102 , // a game server login token owned by this token's owner has been banned
k_EResultGSOwnerDenied = 103 , // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone)
k_EResultInvalidItemType = 104 , // the type of thing we were requested to act on is invalid
k_EResultIPBanned = 105 , // the ip address has been banned from taking this action
k_EResultGSLTExpired = 106 , // this token has expired from disuse; can be reset for use
k_EResultInsufficientFunds = 107 , // user doesn't have enough wallet funds to complete the action
k_EResultTooManyPending = 108 , // There are too many of this thing pending already
k_EResultNoSiteLicensesFound = 109 , // No site licenses found
k_EResultWGNetworkSendExceeded = 110 , // the WG couldn't send a response because we exceeded max network send size
k_EResultAccountNotFriends = 111 , // the user is not mutually friends
k_EResultLimitedUserAccount = 112 , // the user is limited
k_EResultCantRemoveItem = 113 , // item can't be removed
2020-03-26 01:43:23 +08:00
k_EResultAccountDeleted = 114 , // account has been deleted
k_EResultExistingUserCancelledLicense = 115 , // A license for this already exists, but cancelled
2020-06-15 04:04:43 +08:00
k_EResultCommunityCooldown = 116 , // access is denied because of a community cooldown (probably from support profile data resets)
2021-01-18 11:46:00 +08:00
k_EResultNoLauncherSpecified = 117 , // No launcher was specified, but a launcher was needed to choose correct realm for operation.
k_EResultMustAgreeToSSA = 118 , // User must agree to china SSA or global SSA before login
k_EResultLauncherMigrated = 119 , // The specified launcher type is no longer supported; the user should be directed elsewhere
2019-04-14 00:21:56 +08:00
} ;
// Error codes for use with the voice functions
enum EVoiceResult
{
k_EVoiceResultOK = 0 ,
k_EVoiceResultNotInitialized = 1 ,
k_EVoiceResultNotRecording = 2 ,
k_EVoiceResultNoData = 3 ,
k_EVoiceResultBufferTooSmall = 4 ,
k_EVoiceResultDataCorrupted = 5 ,
k_EVoiceResultRestricted = 6 ,
k_EVoiceResultUnsupportedCodec = 7 ,
k_EVoiceResultReceiverOutOfDate = 8 ,
k_EVoiceResultReceiverDidNotAnswer = 9 ,
} ;
// Result codes to GSHandleClientDeny/Kick
enum EDenyReason
{
k_EDenyInvalid = 0 ,
k_EDenyInvalidVersion = 1 ,
k_EDenyGeneric = 2 ,
k_EDenyNotLoggedOn = 3 ,
k_EDenyNoLicense = 4 ,
k_EDenyCheater = 5 ,
k_EDenyLoggedInElseWhere = 6 ,
k_EDenyUnknownText = 7 ,
k_EDenyIncompatibleAnticheat = 8 ,
k_EDenyMemoryCorruption = 9 ,
k_EDenyIncompatibleSoftware = 10 ,
k_EDenySteamConnectionLost = 11 ,
k_EDenySteamConnectionError = 12 ,
k_EDenySteamResponseTimedOut = 13 ,
k_EDenySteamValidationStalled = 14 ,
k_EDenySteamOwnerLeftGuestUser = 15 ,
} ;
// return type of GetAuthSessionTicket
typedef uint32 HAuthTicket ;
const HAuthTicket k_HAuthTicketInvalid = 0 ;
// results from BeginAuthSession
enum EBeginAuthSessionResult
{
k_EBeginAuthSessionResultOK = 0 , // Ticket is valid for this game and this steamID.
k_EBeginAuthSessionResultInvalidTicket = 1 , // Ticket is not valid.
k_EBeginAuthSessionResultDuplicateRequest = 2 , // A ticket has already been submitted for this steamID
k_EBeginAuthSessionResultInvalidVersion = 3 , // Ticket is from an incompatible interface version
k_EBeginAuthSessionResultGameMismatch = 4 , // Ticket is not for this game
k_EBeginAuthSessionResultExpiredTicket = 5 , // Ticket has expired
} ;
// Callback values for callback ValidateAuthTicketResponse_t which is a response to BeginAuthSession
enum EAuthSessionResponse
{
k_EAuthSessionResponseOK = 0 , // Steam has verified the user is online, the ticket is valid and ticket has not been reused.
k_EAuthSessionResponseUserNotConnectedToSteam = 1 , // The user in question is not connected to steam
k_EAuthSessionResponseNoLicenseOrExpired = 2 , // The license has expired.
k_EAuthSessionResponseVACBanned = 3 , // The user is VAC banned for this game.
k_EAuthSessionResponseLoggedInElseWhere = 4 , // The user account has logged in elsewhere and the session containing the game instance has been disconnected.
k_EAuthSessionResponseVACCheckTimedOut = 5 , // VAC has been unable to perform anti-cheat checks on this user
k_EAuthSessionResponseAuthTicketCanceled = 6 , // The ticket has been canceled by the issuer
k_EAuthSessionResponseAuthTicketInvalidAlreadyUsed = 7 , // This ticket has already been used, it is not valid.
k_EAuthSessionResponseAuthTicketInvalid = 8 , // This ticket is not from a user instance currently connected to steam.
k_EAuthSessionResponsePublisherIssuedBan = 9 , // The user is banned for this game. The ban came via the web api and not VAC
} ;
// results from UserHasLicenseForApp
enum EUserHasLicenseForAppResult
{
k_EUserHasLicenseResultHasLicense = 0 , // User has a license for specified app
k_EUserHasLicenseResultDoesNotHaveLicense = 1 , // User does not have a license for the specified app
k_EUserHasLicenseResultNoAuth = 2 , // User has not been authenticated
} ;
// Steam account types
enum EAccountType
{
k_EAccountTypeInvalid = 0 ,
k_EAccountTypeIndividual = 1 , // single user account
k_EAccountTypeMultiseat = 2 , // multiseat (e.g. cybercafe) account
k_EAccountTypeGameServer = 3 , // game server account
k_EAccountTypeAnonGameServer = 4 , // anonymous game server account
k_EAccountTypePending = 5 , // pending
k_EAccountTypeContentServer = 6 , // content server
k_EAccountTypeClan = 7 ,
k_EAccountTypeChat = 8 ,
k_EAccountTypeConsoleUser = 9 , // Fake SteamID for local PSN account on PS3 or Live account on 360, etc.
k_EAccountTypeAnonUser = 10 ,
// Max of 16 items in this field
k_EAccountTypeMax
} ;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
enum EAppReleaseState
{
k_EAppReleaseState_Unknown = 0 , // unknown, required appinfo or license info is missing
2020-06-15 04:04:43 +08:00
k_EAppReleaseState_Unavailable = 1 , // even owners can't see game in library yet, no AppInfo released
k_EAppReleaseState_Prerelease = 2 , // app can be purchased and is visible in library, nothing else. Only Common AppInfo section released
k_EAppReleaseState_PreloadOnly = 3 , // owners can preload app, but not play it. All AppInfo sections fully released
2019-04-14 00:21:56 +08:00
k_EAppReleaseState_Released = 4 , // owners can download and play app.
} ;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
enum EAppOwnershipFlags
{
k_EAppOwnershipFlags_None = 0x0000 , // unknown
k_EAppOwnershipFlags_OwnsLicense = 0x0001 , // owns license for this game
k_EAppOwnershipFlags_FreeLicense = 0x0002 , // not paid for game
k_EAppOwnershipFlags_RegionRestricted = 0x0004 , // owns app, but not allowed to play in current region
k_EAppOwnershipFlags_LowViolence = 0x0008 , // only low violence version
k_EAppOwnershipFlags_InvalidPlatform = 0x0010 , // app not supported on current platform
k_EAppOwnershipFlags_SharedLicense = 0x0020 , // license was granted by authorized local device
k_EAppOwnershipFlags_FreeWeekend = 0x0040 , // owned by a free weekend licenses
k_EAppOwnershipFlags_RetailLicense = 0x0080 , // has a retail license for game, (CD-Key etc)
k_EAppOwnershipFlags_LicenseLocked = 0x0100 , // shared license is locked (in use) by other user
k_EAppOwnershipFlags_LicensePending = 0x0200 , // owns app, but transaction is still pending. Can't install or play
k_EAppOwnershipFlags_LicenseExpired = 0x0400 , // doesn't own app anymore since license expired
k_EAppOwnershipFlags_LicensePermanent = 0x0800 , // permanent license, not borrowed, or guest or freeweekend etc
k_EAppOwnershipFlags_LicenseRecurring = 0x1000 , // Recurring license, user is charged periodically
k_EAppOwnershipFlags_LicenseCanceled = 0x2000 , // Mark as canceled, but might be still active if recurring
k_EAppOwnershipFlags_AutoGrant = 0x4000 , // Ownership is based on any kind of autogrant license
k_EAppOwnershipFlags_PendingGift = 0x8000 , // user has pending gift to redeem
k_EAppOwnershipFlags_RentalNotActivated = 0x10000 , // Rental hasn't been activated yet
k_EAppOwnershipFlags_Rental = 0x20000 , // Is a rental
k_EAppOwnershipFlags_SiteLicense = 0x40000 , // Is from a site license
2019-12-10 01:49:55 +08:00
k_EAppOwnershipFlags_LegacyFreeSub = 0x80000 , // App only owned through Steam's legacy free sub
k_EAppOwnershipFlags_InvalidOSType = 0x100000 , // app not supported on current OS version, used to indicate a game is 32-bit on post-catalina. Currently it's own flag so the library will display a notice.
2020-06-15 04:04:43 +08:00
k_EAppOwnershipFlags_TimedTrial = 0x200000 , // App is playable only for limited time
2019-04-14 00:21:56 +08:00
} ;
//-----------------------------------------------------------------------------
// Purpose: designed as flags to allow filters masks
// NOTE: If you add to this, please update PackageAppType (SteamConfig) as well as populatePackageAppType
//-----------------------------------------------------------------------------
enum EAppType
{
k_EAppType_Invalid = 0x000 , // unknown / invalid
k_EAppType_Game = 0x001 , // playable game, default type
k_EAppType_Application = 0x002 , // software application
k_EAppType_Tool = 0x004 , // SDKs, editors & dedicated servers
k_EAppType_Demo = 0x008 , // game demo
k_EAppType_Media_DEPRECATED = 0x010 , // legacy - was used for game trailers, which are now just videos on the web
k_EAppType_DLC = 0x020 , // down loadable content
k_EAppType_Guide = 0x040 , // game guide, PDF etc
k_EAppType_Driver = 0x080 , // hardware driver updater (ATI, Razor etc)
k_EAppType_Config = 0x100 , // hidden app used to config Steam features (backpack, sales, etc)
k_EAppType_Hardware = 0x200 , // a hardware device (Steam Machine, Steam Controller, Steam Link, etc.)
k_EAppType_Franchise = 0x400 , // A hub for collections of multiple apps, eg films, series, games
k_EAppType_Video = 0x800 , // A video component of either a Film or TVSeries (may be the feature, an episode, preview, making-of, etc)
k_EAppType_Plugin = 0x1000 , // Plug-in types for other Apps
2019-12-10 01:49:55 +08:00
k_EAppType_MusicAlbum = 0x2000 , // "Video game soundtrack album"
2019-04-14 00:21:56 +08:00
k_EAppType_Series = 0x4000 , // Container app for video series
2019-12-10 01:49:55 +08:00
k_EAppType_Comic_UNUSED = 0x8000 , // Comic Book
2019-07-28 21:02:09 +08:00
k_EAppType_Beta = 0x10000 , // this is a beta version of a game
2019-04-14 00:21:56 +08:00
k_EAppType_Shortcut = 0x40000000 , // just a shortcut, client side only
2021-01-18 11:46:00 +08:00
k_EAppType_DepotOnly_DEPRECATED = 0x80000000 , // there shouldn't be any appinfo for depots
2019-04-14 00:21:56 +08:00
} ;
//-----------------------------------------------------------------------------
// types of user game stats fields
// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN DATABASE
//-----------------------------------------------------------------------------
enum ESteamUserStatType
{
k_ESteamUserStatTypeINVALID = 0 ,
k_ESteamUserStatTypeINT = 1 ,
k_ESteamUserStatTypeFLOAT = 2 ,
// Read as FLOAT, set with count / session length
k_ESteamUserStatTypeAVGRATE = 3 ,
k_ESteamUserStatTypeACHIEVEMENTS = 4 ,
k_ESteamUserStatTypeGROUPACHIEVEMENTS = 5 ,
// max, for sanity checks
k_ESteamUserStatTypeMAX
} ;
//-----------------------------------------------------------------------------
// Purpose: Chat Entry Types (previously was only friend-to-friend message types)
//-----------------------------------------------------------------------------
enum EChatEntryType
{
k_EChatEntryTypeInvalid = 0 ,
k_EChatEntryTypeChatMsg = 1 , // Normal text message from another user
k_EChatEntryTypeTyping = 2 , // Another user is typing (not used in multi-user chat)
k_EChatEntryTypeInviteGame = 3 , // Invite from other user into that users current game
k_EChatEntryTypeEmote = 4 , // text emote message (deprecated, should be treated as ChatMsg)
//k_EChatEntryTypeLobbyGameStart = 5, // lobby game is starting (dead - listen for LobbyGameCreated_t callback instead)
k_EChatEntryTypeLeftConversation = 6 , // user has left the conversation ( closed chat window )
// Above are previous FriendMsgType entries, now merged into more generic chat entry types
k_EChatEntryTypeEntered = 7 , // user has entered the conversation (used in multi-user chat and group chat)
k_EChatEntryTypeWasKicked = 8 , // user was kicked (data: 64-bit steamid of actor performing the kick)
k_EChatEntryTypeWasBanned = 9 , // user was banned (data: 64-bit steamid of actor performing the ban)
k_EChatEntryTypeDisconnected = 10 , // user disconnected
k_EChatEntryTypeHistoricalChat = 11 , // a chat message from user's chat history or offilne message
//k_EChatEntryTypeReserved1 = 12, // No longer used
//k_EChatEntryTypeReserved2 = 13, // No longer used
k_EChatEntryTypeLinkBlocked = 14 , // a link was removed by the chat filter.
} ;
//-----------------------------------------------------------------------------
// Purpose: Chat Room Enter Responses
//-----------------------------------------------------------------------------
enum EChatRoomEnterResponse
{
k_EChatRoomEnterResponseSuccess = 1 , // Success
k_EChatRoomEnterResponseDoesntExist = 2 , // Chat doesn't exist (probably closed)
k_EChatRoomEnterResponseNotAllowed = 3 , // General Denied - You don't have the permissions needed to join the chat
k_EChatRoomEnterResponseFull = 4 , // Chat room has reached its maximum size
k_EChatRoomEnterResponseError = 5 , // Unexpected Error
k_EChatRoomEnterResponseBanned = 6 , // You are banned from this chat room and may not join
k_EChatRoomEnterResponseLimited = 7 , // Joining this chat is not allowed because you are a limited user (no value on account)
k_EChatRoomEnterResponseClanDisabled = 8 , // Attempt to join a clan chat when the clan is locked or disabled
k_EChatRoomEnterResponseCommunityBan = 9 , // Attempt to join a chat when the user has a community lock on their account
k_EChatRoomEnterResponseMemberBlockedYou = 10 , // Join failed - some member in the chat has blocked you from joining
k_EChatRoomEnterResponseYouBlockedMember = 11 , // Join failed - you have blocked some member already in the chat
// k_EChatRoomEnterResponseNoRankingDataLobby = 12, // No longer used
// k_EChatRoomEnterResponseNoRankingDataUser = 13, // No longer used
// k_EChatRoomEnterResponseRankOutOfRange = 14, // No longer used
k_EChatRoomEnterResponseRatelimitExceeded = 15 , // Join failed - to many join attempts in a very short period of time
} ;
typedef void ( * PFNLegacyKeyRegistration ) ( const char * pchCDKey , const char * pchInstallPath ) ;
typedef bool ( * PFNLegacyKeyInstalled ) ( ) ;
const unsigned int k_unSteamAccountIDMask = 0xFFFFFFFF ;
const unsigned int k_unSteamAccountInstanceMask = 0x000FFFFF ;
2019-12-10 01:49:55 +08:00
const unsigned int k_unSteamUserDefaultInstance = 1 ; // fixed instance for all individual users
2019-04-14 00:21:56 +08:00
// Special flags for Chat accounts - they go in the top 8 bits
// of the steam ID's "instance", leaving 12 for the actual instances
enum EChatSteamIDInstanceFlags
{
k_EChatAccountInstanceMask = 0x00000FFF , // top 8 bits are flags
k_EChatInstanceFlagClan = ( k_unSteamAccountInstanceMask + 1 ) > > 1 , // top bit
k_EChatInstanceFlagLobby = ( k_unSteamAccountInstanceMask + 1 ) > > 2 , // next one down, etc
k_EChatInstanceFlagMMSLobby = ( k_unSteamAccountInstanceMask + 1 ) > > 3 , // next one down, etc
// Max of 8 flags
} ;
//-----------------------------------------------------------------------------
// Purpose: Marketing message flags that change how a client should handle them
//-----------------------------------------------------------------------------
enum EMarketingMessageFlags
{
k_EMarketingMessageFlagsNone = 0 ,
k_EMarketingMessageFlagsHighPriority = 1 < < 0 ,
k_EMarketingMessageFlagsPlatformWindows = 1 < < 1 ,
k_EMarketingMessageFlagsPlatformMac = 1 < < 2 ,
k_EMarketingMessageFlagsPlatformLinux = 1 < < 3 ,
//aggregate flags
k_EMarketingMessageFlagsPlatformRestrictions =
k_EMarketingMessageFlagsPlatformWindows |
2019-12-10 01:49:55 +08:00
k_EMarketingMessageFlagsPlatformMac |
k_EMarketingMessageFlagsPlatformLinux ,
2019-04-14 00:21:56 +08:00
} ;
//-----------------------------------------------------------------------------
// Purpose: Possible positions to tell the overlay to show notifications in
//-----------------------------------------------------------------------------
enum ENotificationPosition
{
k_EPositionTopLeft = 0 ,
k_EPositionTopRight = 1 ,
k_EPositionBottomLeft = 2 ,
k_EPositionBottomRight = 3 ,
} ;
//-----------------------------------------------------------------------------
// Purpose: Broadcast upload result details
//-----------------------------------------------------------------------------
enum EBroadcastUploadResult
{
k_EBroadcastUploadResultNone = 0 , // broadcast state unknown
k_EBroadcastUploadResultOK = 1 , // broadcast was good, no problems
k_EBroadcastUploadResultInitFailed = 2 , // broadcast init failed
k_EBroadcastUploadResultFrameFailed = 3 , // broadcast frame upload failed
k_EBroadcastUploadResultTimeout = 4 , // broadcast upload timed out
k_EBroadcastUploadResultBandwidthExceeded = 5 , // broadcast send too much data
k_EBroadcastUploadResultLowFPS = 6 , // broadcast FPS too low
k_EBroadcastUploadResultMissingKeyFrames = 7 , // broadcast sending not enough key frames
k_EBroadcastUploadResultNoConnection = 8 , // broadcast client failed to connect to relay
k_EBroadcastUploadResultRelayFailed = 9 , // relay dropped the upload
k_EBroadcastUploadResultSettingsChanged = 10 , // the client changed broadcast settings
k_EBroadcastUploadResultMissingAudio = 11 , // client failed to send audio data
k_EBroadcastUploadResultTooFarBehind = 12 , // clients was too slow uploading
k_EBroadcastUploadResultTranscodeBehind = 13 , // server failed to keep up with transcode
k_EBroadcastUploadResultNotAllowedToPlay = 14 , // Broadcast does not have permissions to play game
k_EBroadcastUploadResultBusy = 15 , // RTMP host to busy to take new broadcast stream, choose another
k_EBroadcastUploadResultBanned = 16 , // Account banned from community broadcast
k_EBroadcastUploadResultAlreadyActive = 17 , // We already already have an stream running.
k_EBroadcastUploadResultForcedOff = 18 , // We explicitly shutting down a broadcast
k_EBroadcastUploadResultAudioBehind = 19 , // Audio stream was too far behind video
k_EBroadcastUploadResultShutdown = 20 , // Broadcast Server was shut down
k_EBroadcastUploadResultDisconnect = 21 , // broadcast uploader TCP disconnected
k_EBroadcastUploadResultVideoInitFailed = 22 , // invalid video settings
k_EBroadcastUploadResultAudioInitFailed = 23 , // invalid audio settings
} ;
//-----------------------------------------------------------------------------
// Purpose: codes for well defined launch options
//-----------------------------------------------------------------------------
enum ELaunchOptionType
{
k_ELaunchOptionType_None = 0 , // unknown what launch option does
k_ELaunchOptionType_Default = 1 , // runs the game, app, whatever in default mode
k_ELaunchOptionType_SafeMode = 2 , // runs the game in safe mode
k_ELaunchOptionType_Multiplayer = 3 , // runs the game in multiplayer mode
k_ELaunchOptionType_Config = 4 , // runs config tool for this game
k_ELaunchOptionType_OpenVR = 5 , // runs game in VR mode using OpenVR
k_ELaunchOptionType_Server = 6 , // runs dedicated server for this game
k_ELaunchOptionType_Editor = 7 , // runs game editor
k_ELaunchOptionType_Manual = 8 , // shows game manual
k_ELaunchOptionType_Benchmark = 9 , // runs game benchmark
k_ELaunchOptionType_Option1 = 10 , // generic run option, uses description field for game name
k_ELaunchOptionType_Option2 = 11 , // generic run option, uses description field for game name
k_ELaunchOptionType_Option3 = 12 , // generic run option, uses description field for game name
k_ELaunchOptionType_OculusVR = 13 , // runs game in VR mode using the Oculus SDK
k_ELaunchOptionType_OpenVROverlay = 14 , // runs an OpenVR dashboard overlay
k_ELaunchOptionType_OSVR = 15 , // runs game in VR mode using the OSVR SDK
k_ELaunchOptionType_Dialog = 1000 , // show launch options dialog
} ;
//-----------------------------------------------------------------------------
// Purpose: true if this launch option is any of the vr launching types
//-----------------------------------------------------------------------------
static inline bool BIsVRLaunchOptionType ( const ELaunchOptionType eType )
{
return eType = = k_ELaunchOptionType_OpenVR
| | eType = = k_ELaunchOptionType_OpenVROverlay
| | eType = = k_ELaunchOptionType_OculusVR
| | eType = = k_ELaunchOptionType_OSVR ;
}
2020-06-15 04:04:43 +08:00
//-----------------------------------------------------------------------------
// Purpose: true if this launch option is any of the vr launching types
//-----------------------------------------------------------------------------
static inline bool BIsLaunchOptionTypeExemptFromGameTheater ( const ELaunchOptionType eType )
{
return eType = = k_ELaunchOptionType_Config
| | eType = = k_ELaunchOptionType_Server
| | eType = = k_ELaunchOptionType_Editor
| | eType = = k_ELaunchOptionType_Manual ;
}
2019-04-14 00:21:56 +08:00
//-----------------------------------------------------------------------------
// Purpose: code points for VR HMD vendors and models
// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN A DATABASE
//-----------------------------------------------------------------------------
enum EVRHMDType
{
k_eEVRHMDType_None = - 1 , // unknown vendor and model
k_eEVRHMDType_Unknown = 0 , // unknown vendor and model
k_eEVRHMDType_HTC_Dev = 1 , // original HTC dev kits
k_eEVRHMDType_HTC_VivePre = 2 , // htc vive pre
k_eEVRHMDType_HTC_Vive = 3 , // htc vive consumer release
k_eEVRHMDType_HTC_VivePro = 4 , // htc vive pro release
2019-07-28 21:02:09 +08:00
k_eEVRHMDType_HTC_ViveCosmos = 5 , // HTC Vive Cosmos
2019-04-14 00:21:56 +08:00
k_eEVRHMDType_HTC_Unknown = 20 , // unknown htc hmd
k_eEVRHMDType_Oculus_DK1 = 21 , // Oculus DK1
k_eEVRHMDType_Oculus_DK2 = 22 , // Oculus DK2
2019-07-28 21:02:09 +08:00
k_eEVRHMDType_Oculus_Rift = 23 , // Oculus Rift
k_eEVRHMDType_Oculus_RiftS = 24 , // Oculus Rift S
2020-03-26 01:43:23 +08:00
k_eEVRHMDType_Oculus_Quest = 25 , // Oculus Quest
2019-04-14 00:21:56 +08:00
k_eEVRHMDType_Oculus_Unknown = 40 , // // Oculus unknown HMD
k_eEVRHMDType_Acer_Unknown = 50 , // Acer unknown HMD
k_eEVRHMDType_Acer_WindowsMR = 51 , // Acer QHMD Windows MR headset
k_eEVRHMDType_Dell_Unknown = 60 , // Dell unknown HMD
k_eEVRHMDType_Dell_Visor = 61 , // Dell Visor Windows MR headset
k_eEVRHMDType_Lenovo_Unknown = 70 , // Lenovo unknown HMD
k_eEVRHMDType_Lenovo_Explorer = 71 , // Lenovo Explorer Windows MR headset
k_eEVRHMDType_HP_Unknown = 80 , // HP unknown HMD
k_eEVRHMDType_HP_WindowsMR = 81 , // HP Windows MR headset
2019-12-10 01:49:55 +08:00
k_eEVRHMDType_HP_Reverb = 82 , // HP Reverb Windows MR headset
2021-01-18 11:46:00 +08:00
k_eEVRHMDType_HP_ReverbG2 = 1463 , // HP Reverb G2 Windows MR headset
2019-04-14 00:21:56 +08:00
k_eEVRHMDType_Samsung_Unknown = 90 , // Samsung unknown HMD
k_eEVRHMDType_Samsung_Odyssey = 91 , // Samsung Odyssey Windows MR headset
k_eEVRHMDType_Unannounced_Unknown = 100 , // Unannounced unknown HMD
k_eEVRHMDType_Unannounced_WindowsMR = 101 , // Unannounced Windows MR headset
k_eEVRHMDType_vridge = 110 , // VRIDGE tool
k_eEVRHMDType_Huawei_Unknown = 120 , // Huawei unknown HMD
k_eEVRHMDType_Huawei_VR2 = 121 , // Huawei VR2 3DOF headset
k_eEVRHMDType_Huawei_EndOfRange = 129 , // end of Huawei HMD range
2019-07-28 21:02:09 +08:00
k_eEVRHmdType_Valve_Unknown = 130 , // Valve Unknown HMD
k_eEVRHmdType_Valve_Index = 131 , // Valve Index HMD
2019-04-14 00:21:56 +08:00
} ;
//-----------------------------------------------------------------------------
// Purpose: true if this is from an Oculus HMD
//-----------------------------------------------------------------------------
static inline bool BIsOculusHMD ( EVRHMDType eType )
{
2020-03-26 01:43:23 +08:00
return eType = = k_eEVRHMDType_Oculus_DK1 | | eType = = k_eEVRHMDType_Oculus_DK2 | | eType = = k_eEVRHMDType_Oculus_Rift | | eType = = k_eEVRHMDType_Oculus_RiftS | | eType = = k_eEVRHMDType_Oculus_Quest | | eType = = k_eEVRHMDType_Oculus_Unknown ;
2019-04-14 00:21:56 +08:00
}
//-----------------------------------------------------------------------------
// Purpose: true if this is from a Windows MR HMD
//-----------------------------------------------------------------------------
static inline bool BIsWindowsMRHeadset ( EVRHMDType eType )
{
return eType > = k_eEVRHMDType_Acer_WindowsMR & & eType < = k_eEVRHMDType_Unannounced_WindowsMR ;
}
//-----------------------------------------------------------------------------
// Purpose: true if this is from a Hauwei HMD
//-----------------------------------------------------------------------------
static inline bool BIsHuaweiHeadset ( EVRHMDType eType )
{
return eType > = k_eEVRHMDType_Huawei_Unknown & & eType < = k_eEVRHMDType_Huawei_EndOfRange ;
}
//-----------------------------------------------------------------------------
// Purpose: true if this is from an Vive HMD
//-----------------------------------------------------------------------------
static inline bool BIsViveHMD ( EVRHMDType eType )
{
return eType = = k_eEVRHMDType_HTC_Dev | | eType = = k_eEVRHMDType_HTC_VivePre | | eType = = k_eEVRHMDType_HTC_Vive | | eType = = k_eEVRHMDType_HTC_Unknown | | eType = = k_eEVRHMDType_HTC_VivePro ;
}
//-----------------------------------------------------------------------------
// Purpose: Reasons a user may not use the Community Market.
// Used in MarketEligibilityResponse_t.
//-----------------------------------------------------------------------------
enum EMarketNotAllowedReasonFlags
{
k_EMarketNotAllowedReason_None = 0 ,
// A back-end call failed or something that might work again on retry
k_EMarketNotAllowedReason_TemporaryFailure = ( 1 < < 0 ) ,
// Disabled account
k_EMarketNotAllowedReason_AccountDisabled = ( 1 < < 1 ) ,
// Locked account
k_EMarketNotAllowedReason_AccountLockedDown = ( 1 < < 2 ) ,
// Limited account (no purchases)
k_EMarketNotAllowedReason_AccountLimited = ( 1 < < 3 ) ,
// The account is banned from trading items
k_EMarketNotAllowedReason_TradeBanned = ( 1 < < 4 ) ,
// Wallet funds aren't tradable because the user has had no purchase
// activity in the last year or has had no purchases prior to last month
k_EMarketNotAllowedReason_AccountNotTrusted = ( 1 < < 5 ) ,
// The user doesn't have Steam Guard enabled
k_EMarketNotAllowedReason_SteamGuardNotEnabled = ( 1 < < 6 ) ,
// The user has Steam Guard, but it hasn't been enabled for the required
// number of days
k_EMarketNotAllowedReason_SteamGuardOnlyRecentlyEnabled = ( 1 < < 7 ) ,
// The user has recently forgotten their password and reset it
k_EMarketNotAllowedReason_RecentPasswordReset = ( 1 < < 8 ) ,
// The user has recently funded his or her wallet with a new payment method
k_EMarketNotAllowedReason_NewPaymentMethod = ( 1 < < 9 ) ,
// An invalid cookie was sent by the user
k_EMarketNotAllowedReason_InvalidCookie = ( 1 < < 10 ) ,
// The user has Steam Guard, but is using a new computer or web browser
k_EMarketNotAllowedReason_UsingNewDevice = ( 1 < < 11 ) ,
// The user has recently refunded a store purchase by his or herself
k_EMarketNotAllowedReason_RecentSelfRefund = ( 1 < < 12 ) ,
// The user has recently funded his or her wallet with a new payment method that cannot be verified
k_EMarketNotAllowedReason_NewPaymentMethodCannotBeVerified = ( 1 < < 13 ) ,
// Not only is the account not trusted, but they have no recent purchases at all
k_EMarketNotAllowedReason_NoRecentPurchases = ( 1 < < 14 ) ,
// User accepted a wallet gift that was recently purchased
k_EMarketNotAllowedReason_AcceptedWalletGift = ( 1 < < 15 ) ,
} ;
2019-07-28 21:02:09 +08:00
//
// describes XP / progress restrictions to apply for games with duration control /
// anti-indulgence enabled for minor Steam China users.
//
2019-12-10 01:49:55 +08:00
// WARNING: DO NOT RENUMBER
2019-07-28 21:02:09 +08:00
enum EDurationControlProgress
{
2019-12-10 01:49:55 +08:00
k_EDurationControlProgress_Full = 0 , // Full progress
k_EDurationControlProgress_Half = 1 , // deprecated - XP or persistent rewards should be halved
k_EDurationControlProgress_None = 2 , // deprecated - XP or persistent rewards should be stopped
k_EDurationControl_ExitSoon_3h = 3 , // allowed 3h time since 5h gap/break has elapsed, game should exit - steam will terminate the game soon
k_EDurationControl_ExitSoon_5h = 4 , // allowed 5h time in calendar day has elapsed, game should exit - steam will terminate the game soon
k_EDurationControl_ExitSoon_Night = 5 , // game running after day period, game should exit - steam will terminate the game soon
2019-07-28 21:02:09 +08:00
} ;
//
// describes which notification timer has expired, for steam china duration control feature
//
2019-12-10 01:49:55 +08:00
// WARNING: DO NOT RENUMBER
2019-07-28 21:02:09 +08:00
enum EDurationControlNotification
{
2019-12-10 01:49:55 +08:00
k_EDurationControlNotification_None = 0 , // just informing you about progress, no notification to show
k_EDurationControlNotification_1Hour = 1 , // "you've been playing for N hours"
k_EDurationControlNotification_3Hours = 2 , // deprecated - "you've been playing for 3 hours; take a break"
k_EDurationControlNotification_HalfProgress = 3 , // deprecated - "your XP / progress is half normal"
k_EDurationControlNotification_NoProgress = 4 , // deprecated - "your XP / progress is zero"
k_EDurationControlNotification_ExitSoon_3h = 5 , // allowed 3h time since 5h gap/break has elapsed, game should exit - steam will terminate the game soon
k_EDurationControlNotification_ExitSoon_5h = 6 , // allowed 5h time in calendar day has elapsed, game should exit - steam will terminate the game soon
k_EDurationControlNotification_ExitSoon_Night = 7 , // game running after day period, game should exit - steam will terminate the game soon
2019-07-28 21:02:09 +08:00
} ;
2020-06-15 04:04:43 +08:00
//
// Specifies a game's online state in relation to duration control
//
enum EDurationControlOnlineState
{
k_EDurationControlOnlineState_Invalid = 0 , // nil value
k_EDurationControlOnlineState_Offline = 1 , // currently in offline play - single-player, offline co-op, etc.
k_EDurationControlOnlineState_Online = 2 , // currently in online play
k_EDurationControlOnlineState_OnlineHighPri = 3 , // currently in online play and requests not to be interrupted
} ;
2019-04-14 00:21:56 +08:00
# pragma pack( push, 1 )
# define CSTEAMID_DEFINED
// Steam ID structure (64 bits total)
class CSteamID
{
public :
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSteamID ( )
{
m_steamid . m_comp . m_unAccountID = 0 ;
m_steamid . m_comp . m_EAccountType = k_EAccountTypeInvalid ;
m_steamid . m_comp . m_EUniverse = k_EUniverseInvalid ;
m_steamid . m_comp . m_unAccountInstance = 0 ;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
CSteamID ( uint32 unAccountID , EUniverse eUniverse , EAccountType eAccountType )
{
Set ( unAccountID , eUniverse , eAccountType ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : unAccountID - 32-bit account ID
// unAccountInstance - instance
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
CSteamID ( uint32 unAccountID , unsigned int unAccountInstance , EUniverse eUniverse , EAccountType eAccountType )
{
# if defined(_SERVER) && defined(Assert)
2019-12-10 01:49:55 +08:00
Assert ( ( k_EAccountTypeIndividual ! = eAccountType ) | | ( unAccountInstance = = k_unSteamUserDefaultInstance ) ) ; // enforce that for individual accounts, instance is always 1
2019-04-14 00:21:56 +08:00
# endif // _SERVER
InstancedSet ( unAccountID , unAccountInstance , eUniverse , eAccountType ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : ulSteamID - 64-bit representation of a Steam ID
// Note: Will not accept a uint32 or int32 as input, as that is a probable mistake.
// See the stubbed out overloads in the private: section for more info.
//-----------------------------------------------------------------------------
CSteamID ( uint64 ulSteamID )
{
SetFromUint64 ( ulSteamID ) ;
}
# ifdef INT64_DIFFERENT_FROM_INT64_T
CSteamID ( uint64_t ulSteamID )
{
SetFromUint64 ( ( uint64 ) ulSteamID ) ;
}
# endif
//-----------------------------------------------------------------------------
// Purpose: Sets parameters for steam ID
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
void Set ( uint32 unAccountID , EUniverse eUniverse , EAccountType eAccountType )
{
m_steamid . m_comp . m_unAccountID = unAccountID ;
m_steamid . m_comp . m_EUniverse = eUniverse ;
m_steamid . m_comp . m_EAccountType = eAccountType ;
if ( eAccountType = = k_EAccountTypeClan | | eAccountType = = k_EAccountTypeGameServer )
{
m_steamid . m_comp . m_unAccountInstance = 0 ;
}
else
{
2019-12-10 01:49:55 +08:00
m_steamid . m_comp . m_unAccountInstance = k_unSteamUserDefaultInstance ;
2019-04-14 00:21:56 +08:00
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets parameters for steam ID
// Input : unAccountID - 32-bit account ID
// eUniverse - Universe this account belongs to
// eAccountType - Type of account
//-----------------------------------------------------------------------------
void InstancedSet ( uint32 unAccountID , uint32 unInstance , EUniverse eUniverse , EAccountType eAccountType )
{
m_steamid . m_comp . m_unAccountID = unAccountID ;
m_steamid . m_comp . m_EUniverse = eUniverse ;
m_steamid . m_comp . m_EAccountType = eAccountType ;
m_steamid . m_comp . m_unAccountInstance = unInstance ;
}
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from its 52 bit parts and universe/type
// Input : ulIdentifier - 52 bits of goodness
//-----------------------------------------------------------------------------
void FullSet ( uint64 ulIdentifier , EUniverse eUniverse , EAccountType eAccountType )
{
m_steamid . m_comp . m_unAccountID = ( ulIdentifier & k_unSteamAccountIDMask ) ; // account ID is low 32 bits
m_steamid . m_comp . m_unAccountInstance = ( ( ulIdentifier > > 32 ) & k_unSteamAccountInstanceMask ) ; // account instance is next 20 bits
m_steamid . m_comp . m_EUniverse = eUniverse ;
m_steamid . m_comp . m_EAccountType = eAccountType ;
}
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from its 64-bit representation
// Input : ulSteamID - 64-bit representation of a Steam ID
//-----------------------------------------------------------------------------
void SetFromUint64 ( uint64 ulSteamID )
{
m_steamid . m_unAll64Bits = ulSteamID ;
}
//-----------------------------------------------------------------------------
// Purpose: Clear all fields, leaving an invalid ID.
//-----------------------------------------------------------------------------
void Clear ( )
{
m_steamid . m_comp . m_unAccountID = 0 ;
m_steamid . m_comp . m_EAccountType = k_EAccountTypeInvalid ;
m_steamid . m_comp . m_EUniverse = k_EUniverseInvalid ;
m_steamid . m_comp . m_unAccountInstance = 0 ;
}
# if defined( INCLUDED_STEAM2_USERID_STRUCTS )
//-----------------------------------------------------------------------------
// Purpose: Initializes a steam ID from a Steam2 ID structure
// Input: pTSteamGlobalUserID - Steam2 ID to convert
// eUniverse - universe this ID belongs to
//-----------------------------------------------------------------------------
void SetFromSteam2 ( TSteamGlobalUserID * pTSteamGlobalUserID , EUniverse eUniverse )
{
m_steamid . m_comp . m_unAccountID = pTSteamGlobalUserID - > m_SteamLocalUserID . Split . Low32bits * 2 +
pTSteamGlobalUserID - > m_SteamLocalUserID . Split . High32bits ;
m_steamid . m_comp . m_EUniverse = eUniverse ; // set the universe
m_steamid . m_comp . m_EAccountType = k_EAccountTypeIndividual ; // Steam 2 accounts always map to account type of individual
2019-12-10 01:49:55 +08:00
m_steamid . m_comp . m_unAccountInstance = k_unSteamUserDefaultInstance ; // Steam2 only knew one instance
2019-04-14 00:21:56 +08:00
}
//-----------------------------------------------------------------------------
// Purpose: Fills out a Steam2 ID structure
// Input: pTSteamGlobalUserID - Steam2 ID to write to
//-----------------------------------------------------------------------------
void ConvertToSteam2 ( TSteamGlobalUserID * pTSteamGlobalUserID ) const
{
// only individual accounts have any meaning in Steam 2, only they can be mapped
// Assert( m_steamid.m_comp.m_EAccountType == k_EAccountTypeIndividual );
pTSteamGlobalUserID - > m_SteamInstanceID = 0 ;
pTSteamGlobalUserID - > m_SteamLocalUserID . Split . High32bits = m_steamid . m_comp . m_unAccountID % 2 ;
pTSteamGlobalUserID - > m_SteamLocalUserID . Split . Low32bits = m_steamid . m_comp . m_unAccountID / 2 ;
}
# endif // defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H )
//-----------------------------------------------------------------------------
// Purpose: Converts steam ID to its 64-bit representation
// Output : 64-bit representation of a Steam ID
//-----------------------------------------------------------------------------
uint64 ConvertToUint64 ( ) const
{
return m_steamid . m_unAll64Bits ;
}
//-----------------------------------------------------------------------------
// Purpose: Converts the static parts of a steam ID to a 64-bit representation.
// For multiseat accounts, all instances of that account will have the
// same static account key, so they can be grouped together by the static
// account key.
// Output : 64-bit static account key
//-----------------------------------------------------------------------------
uint64 GetStaticAccountKey ( ) const
{
// note we do NOT include the account instance (which is a dynamic property) in the static account key
return ( uint64 ) ( ( ( ( uint64 ) m_steamid . m_comp . m_EUniverse ) < < 56 ) + ( ( uint64 ) m_steamid . m_comp . m_EAccountType < < 52 ) + m_steamid . m_comp . m_unAccountID ) ;
}
//-----------------------------------------------------------------------------
// Purpose: create an anonymous game server login to be filled in by the AM
//-----------------------------------------------------------------------------
void CreateBlankAnonLogon ( EUniverse eUniverse )
{
m_steamid . m_comp . m_unAccountID = 0 ;
m_steamid . m_comp . m_EAccountType = k_EAccountTypeAnonGameServer ;
m_steamid . m_comp . m_EUniverse = eUniverse ;
m_steamid . m_comp . m_unAccountInstance = 0 ;
}
//-----------------------------------------------------------------------------
// Purpose: create an anonymous game server login to be filled in by the AM
//-----------------------------------------------------------------------------
void CreateBlankAnonUserLogon ( EUniverse eUniverse )
{
m_steamid . m_comp . m_unAccountID = 0 ;
m_steamid . m_comp . m_EAccountType = k_EAccountTypeAnonUser ;
m_steamid . m_comp . m_EUniverse = eUniverse ;
m_steamid . m_comp . m_unAccountInstance = 0 ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an anonymous game server login that will be filled in?
//-----------------------------------------------------------------------------
bool BBlankAnonAccount ( ) const
{
return m_steamid . m_comp . m_unAccountID = = 0 & & BAnonAccount ( ) & & m_steamid . m_comp . m_unAccountInstance = = 0 ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a game server account id? (Either persistent or anonymous)
//-----------------------------------------------------------------------------
bool BGameServerAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeGameServer | | m_steamid . m_comp . m_EAccountType = = k_EAccountTypeAnonGameServer ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a persistent (not anonymous) game server account id?
//-----------------------------------------------------------------------------
bool BPersistentGameServerAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeGameServer ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an anonymous game server account id?
//-----------------------------------------------------------------------------
bool BAnonGameServerAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeAnonGameServer ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a content server account id?
//-----------------------------------------------------------------------------
bool BContentServerAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeContentServer ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a clan account id?
//-----------------------------------------------------------------------------
bool BClanAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeClan ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a chat account id?
//-----------------------------------------------------------------------------
bool BChatAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeChat ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a chat account id?
//-----------------------------------------------------------------------------
bool IsLobby ( ) const
{
return ( m_steamid . m_comp . m_EAccountType = = k_EAccountTypeChat )
& & ( m_steamid . m_comp . m_unAccountInstance & k_EChatInstanceFlagLobby ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an individual user account id?
//-----------------------------------------------------------------------------
bool BIndividualAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeIndividual | | m_steamid . m_comp . m_EAccountType = = k_EAccountTypeConsoleUser ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an anonymous account?
//-----------------------------------------------------------------------------
bool BAnonAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeAnonUser | | m_steamid . m_comp . m_EAccountType = = k_EAccountTypeAnonGameServer ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this an anonymous user account? ( used to create an account or reset a password )
//-----------------------------------------------------------------------------
bool BAnonUserAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeAnonUser ;
}
//-----------------------------------------------------------------------------
// Purpose: Is this a faked up Steam ID for a PSN friend account?
//-----------------------------------------------------------------------------
bool BConsoleUserAccount ( ) const
{
return m_steamid . m_comp . m_EAccountType = = k_EAccountTypeConsoleUser ;
}
// simple accessors
void SetAccountID ( uint32 unAccountID ) { m_steamid . m_comp . m_unAccountID = unAccountID ; }
void SetAccountInstance ( uint32 unInstance ) { m_steamid . m_comp . m_unAccountInstance = unInstance ; }
2019-12-10 01:49:55 +08:00
2019-04-14 00:21:56 +08:00
AccountID_t GetAccountID ( ) const { return m_steamid . m_comp . m_unAccountID ; }
uint32 GetUnAccountInstance ( ) const { return m_steamid . m_comp . m_unAccountInstance ; }
EAccountType GetEAccountType ( ) const { return ( EAccountType ) m_steamid . m_comp . m_EAccountType ; }
EUniverse GetEUniverse ( ) const { return m_steamid . m_comp . m_EUniverse ; }
void SetEUniverse ( EUniverse eUniverse ) { m_steamid . m_comp . m_EUniverse = eUniverse ; }
bool IsValid ( ) const ;
// this set of functions is hidden, will be moved out of class
explicit CSteamID ( const char * pchSteamID , EUniverse eDefaultUniverse = k_EUniverseInvalid ) ;
const char * Render ( ) const ; // renders this steam ID to string
static const char * Render ( uint64 ulSteamID ) ; // static method to render a uint64 representation of a steam ID to a string
void SetFromString ( const char * pchSteamID , EUniverse eDefaultUniverse ) ;
// SetFromString allows many partially-correct strings, constraining how
// we might be able to change things in the future.
// SetFromStringStrict requires the exact string forms that we support
// and is preferred when the caller knows it's safe to be strict.
// Returns whether the string parsed correctly.
bool SetFromStringStrict ( const char * pchSteamID , EUniverse eDefaultUniverse ) ;
bool SetFromSteam2String ( const char * pchSteam2ID , EUniverse eUniverse ) ;
inline bool operator = = ( const CSteamID & val ) const { return m_steamid . m_unAll64Bits = = val . m_steamid . m_unAll64Bits ; }
inline bool operator ! = ( const CSteamID & val ) const { return ! operator = = ( val ) ; }
inline bool operator < ( const CSteamID & val ) const { return m_steamid . m_unAll64Bits < val . m_steamid . m_unAll64Bits ; }
inline bool operator > ( const CSteamID & val ) const { return m_steamid . m_unAll64Bits > val . m_steamid . m_unAll64Bits ; }
// DEBUG function
bool BValidExternalSteamID ( ) const ;
private :
// These are defined here to prevent accidental implicit conversion of a u32AccountID to a CSteamID.
// If you get a compiler error about an ambiguous constructor/function then it may be because you're
// passing a 32-bit int to a function that takes a CSteamID. You should explicitly create the SteamID
// using the correct Universe and account Type/Instance values.
CSteamID ( uint32 ) ;
CSteamID ( int32 ) ;
// 64 bits total
union SteamID_t
{
struct SteamIDComponent_t
{
# ifdef VALVE_BIG_ENDIAN
EUniverse m_EUniverse : 8 ; // universe this account belongs to
unsigned int m_EAccountType : 4 ; // type of account - can't show as EAccountType, due to signed / unsigned difference
unsigned int m_unAccountInstance : 20 ; // dynamic instance ID
uint32 m_unAccountID : 32 ; // unique account identifier
# else
uint32 m_unAccountID : 32 ; // unique account identifier
unsigned int m_unAccountInstance : 20 ; // dynamic instance ID
unsigned int m_EAccountType : 4 ; // type of account - can't show as EAccountType, due to signed / unsigned difference
EUniverse m_EUniverse : 8 ; // universe this account belongs to
# endif
} m_comp ;
uint64 m_unAll64Bits ;
} m_steamid ;
} ;
inline bool CSteamID : : IsValid ( ) const
{
if ( m_steamid . m_comp . m_EAccountType < = k_EAccountTypeInvalid | | m_steamid . m_comp . m_EAccountType > = k_EAccountTypeMax )
return false ;
if ( m_steamid . m_comp . m_EUniverse < = k_EUniverseInvalid | | m_steamid . m_comp . m_EUniverse > = k_EUniverseMax )
return false ;
if ( m_steamid . m_comp . m_EAccountType = = k_EAccountTypeIndividual )
{
2019-12-10 01:49:55 +08:00
if ( m_steamid . m_comp . m_unAccountID = = 0 | | m_steamid . m_comp . m_unAccountInstance ! = k_unSteamUserDefaultInstance )
2019-04-14 00:21:56 +08:00
return false ;
}
if ( m_steamid . m_comp . m_EAccountType = = k_EAccountTypeClan )
{
if ( m_steamid . m_comp . m_unAccountID = = 0 | | m_steamid . m_comp . m_unAccountInstance ! = 0 )
return false ;
}
if ( m_steamid . m_comp . m_EAccountType = = k_EAccountTypeGameServer )
{
if ( m_steamid . m_comp . m_unAccountID = = 0 )
return false ;
// Any limit on instances? We use them for local users and bots
}
return true ;
}
// generic invalid CSteamID
# define k_steamIDNil CSteamID()
// This steamID comes from a user game connection to an out of date GS that hasnt implemented the protocol
// to provide its steamID
# define k_steamIDOutofDateGS CSteamID( 0, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
// This steamID comes from a user game connection to an sv_lan GS
# define k_steamIDLanModeGS CSteamID( 0, 0, k_EUniversePublic, k_EAccountTypeInvalid )
// This steamID can come from a user game connection to a GS that has just booted but hasnt yet even initialized
// its steam3 component and started logging on.
# define k_steamIDNotInitYetGS CSteamID( 1, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
// This steamID can come from a user game connection to a GS that isn't using the steam authentication system but still
// wants to support the "Join Game" option in the friends list
# define k_steamIDNonSteamGS CSteamID( 2, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
# ifdef STEAM
// Returns the matching chat steamID, with the default instance of 0
// If the steamID passed in is already of type k_EAccountTypeChat it will be returned with the same instance
CSteamID ChatIDFromSteamID ( const CSteamID & steamID ) ;
// Returns the matching clan steamID, with the default instance of 0
// If the steamID passed in is already of type k_EAccountTypeClan it will be returned with the same instance
CSteamID ClanIDFromSteamID ( const CSteamID & steamID ) ;
// Asserts steamID type before conversion
CSteamID ChatIDFromClanID ( const CSteamID & steamIDClan ) ;
// Asserts steamID type before conversion
CSteamID ClanIDFromChatID ( const CSteamID & steamIDChat ) ;
# endif // _STEAM
//-----------------------------------------------------------------------------
// Purpose: encapsulates an appID/modID pair
//-----------------------------------------------------------------------------
class CGameID
{
public :
CGameID ( )
{
m_gameID . m_nType = k_EGameIDTypeApp ;
m_gameID . m_nAppID = k_uAppIdInvalid ;
m_gameID . m_nModID = 0 ;
}
explicit CGameID ( uint64 ulGameID )
{
m_ulGameID = ulGameID ;
}
# ifdef INT64_DIFFERENT_FROM_INT64_T
CGameID ( uint64_t ulGameID )
{
m_ulGameID = ( uint64 ) ulGameID ;
}
# endif
explicit CGameID ( int32 nAppID )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = nAppID ;
}
explicit CGameID ( uint32 nAppID )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = nAppID ;
}
CGameID ( uint32 nAppID , uint32 nModID )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = nAppID ;
m_gameID . m_nModID = nModID ;
m_gameID . m_nType = k_EGameIDTypeGameMod ;
}
2019-12-10 01:49:55 +08:00
CGameID ( const CGameID & that )
{
m_ulGameID = that . m_ulGameID ;
}
CGameID & operator = ( const CGameID & that )
{
m_ulGameID = that . m_ulGameID ;
return * this ;
}
2019-04-14 00:21:56 +08:00
// Hidden functions used only by Steam
explicit CGameID ( const char * pchGameID ) ;
const char * Render ( ) const ; // render this Game ID to string
static const char * Render ( uint64 ulGameID ) ; // static method to render a uint64 representation of a Game ID to a string
// must include checksum_crc.h first to get this functionality
# if defined( CHECKSUM_CRC_H )
CGameID ( uint32 nAppID , const char * pchModPath )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = nAppID ;
m_gameID . m_nType = k_EGameIDTypeGameMod ;
char rgchModDir [ MAX_PATH ] ;
V_FileBase ( pchModPath , rgchModDir , sizeof ( rgchModDir ) ) ;
CRC32_t crc32 ;
CRC32_Init ( & crc32 ) ;
CRC32_ProcessBuffer ( & crc32 , rgchModDir , V_strlen ( rgchModDir ) ) ;
CRC32_Final ( & crc32 ) ;
// set the high-bit on the mod-id
// reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique
// replacement for appID's
m_gameID . m_nModID = crc32 | ( 0x80000000 ) ;
}
CGameID ( const char * pchExePath , const char * pchAppName )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = k_uAppIdInvalid ;
m_gameID . m_nType = k_EGameIDTypeShortcut ;
CRC32_t crc32 ;
CRC32_Init ( & crc32 ) ;
if ( pchExePath )
CRC32_ProcessBuffer ( & crc32 , pchExePath , V_strlen ( pchExePath ) ) ;
if ( pchAppName )
CRC32_ProcessBuffer ( & crc32 , pchAppName , V_strlen ( pchAppName ) ) ;
CRC32_Final ( & crc32 ) ;
// set the high-bit on the mod-id
// reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique
// replacement for appID's
m_gameID . m_nModID = crc32 | ( 0x80000000 ) ;
}
# if defined( VSTFILEID_H )
CGameID ( VstFileID vstFileID )
{
m_ulGameID = 0 ;
m_gameID . m_nAppID = k_uAppIdInvalid ;
m_gameID . m_nType = k_EGameIDTypeP2P ;
CRC32_t crc32 ;
CRC32_Init ( & crc32 ) ;
const char * pchFileId = vstFileID . Render ( ) ;
CRC32_ProcessBuffer ( & crc32 , pchFileId , V_strlen ( pchFileId ) ) ;
CRC32_Final ( & crc32 ) ;
// set the high-bit on the mod-id
// reduces crc32 to 31bits, but lets us use the modID as a guaranteed unique
// replacement for appID's
m_gameID . m_nModID = crc32 | ( 0x80000000 ) ;
}
# endif /* VSTFILEID_H */
# endif /* CHECKSUM_CRC_H */
uint64 ToUint64 ( ) const
{
return m_ulGameID ;
}
uint64 * GetUint64Ptr ( )
{
return & m_ulGameID ;
}
void Set ( uint64 ulGameID )
{
m_ulGameID = ulGameID ;
}
bool IsMod ( ) const
{
return ( m_gameID . m_nType = = k_EGameIDTypeGameMod ) ;
}
bool IsShortcut ( ) const
{
return ( m_gameID . m_nType = = k_EGameIDTypeShortcut ) ;
}
bool IsP2PFile ( ) const
{
return ( m_gameID . m_nType = = k_EGameIDTypeP2P ) ;
}
bool IsSteamApp ( ) const
{
return ( m_gameID . m_nType = = k_EGameIDTypeApp ) ;
}
uint32 ModID ( ) const
{
return m_gameID . m_nModID ;
}
uint32 AppID ( ) const
{
return m_gameID . m_nAppID ;
}
bool operator = = ( const CGameID & rhs ) const
{
return m_ulGameID = = rhs . m_ulGameID ;
}
bool operator ! = ( const CGameID & rhs ) const
{
return ! ( * this = = rhs ) ;
}
bool operator < ( const CGameID & rhs ) const
{
return ( m_ulGameID < rhs . m_ulGameID ) ;
}
bool IsValid ( ) const
{
// each type has it's own invalid fixed point:
switch ( m_gameID . m_nType )
{
case k_EGameIDTypeApp :
return m_gameID . m_nAppID ! = k_uAppIdInvalid ;
case k_EGameIDTypeGameMod :
return m_gameID . m_nAppID ! = k_uAppIdInvalid & & m_gameID . m_nModID & 0x80000000 ;
case k_EGameIDTypeShortcut :
return ( m_gameID . m_nModID & 0x80000000 ) ! = 0 ;
case k_EGameIDTypeP2P :
return m_gameID . m_nAppID = = k_uAppIdInvalid & & m_gameID . m_nModID & 0x80000000 ;
default :
return false ;
}
}
void Reset ( )
{
m_ulGameID = 0 ;
}
private :
enum EGameIDType
{
k_EGameIDTypeApp = 0 ,
k_EGameIDTypeGameMod = 1 ,
k_EGameIDTypeShortcut = 2 ,
k_EGameIDTypeP2P = 3 ,
} ;
struct GameID_t
{
# ifdef VALVE_BIG_ENDIAN
unsigned int m_nModID : 32 ;
unsigned int m_nType : 8 ;
unsigned int m_nAppID : 24 ;
# else
unsigned int m_nAppID : 24 ;
unsigned int m_nType : 8 ;
unsigned int m_nModID : 32 ;
# endif
} ;
union
{
uint64 m_ulGameID ;
GameID_t m_gameID ;
} ;
} ;
# pragma pack( pop )
const int k_cchGameExtraInfoMax = 64 ;
//-----------------------------------------------------------------------------
// Constants used for query ports.
//-----------------------------------------------------------------------------
# define QUERY_PORT_NOT_INITIALIZED 0xFFFF // We haven't asked the GS for this query port's actual value yet.
# define QUERY_PORT_ERROR 0xFFFE // We were unable to get the query port for this server.
//-----------------------------------------------------------------------------
// Purpose: Passed as argument to SteamAPI_UseBreakpadCrashHandler to enable optional callback
// just before minidump file is captured after a crash has occurred. (Allows app to append additional comment data to the dump, etc.)
//-----------------------------------------------------------------------------
typedef void ( * PFNPreMinidumpCallback ) ( void * context ) ;
//-----------------------------------------------------------------------------
// Purpose: Used by ICrashHandler interfaces to reference particular installed crash handlers
//-----------------------------------------------------------------------------
typedef void * BREAKPAD_HANDLE ;
# define BREAKPAD_INVALID_HANDLE (BREAKPAD_HANDLE)0
enum EGameSearchErrorCode_t
{
k_EGameSearchErrorCode_OK = 1 ,
k_EGameSearchErrorCode_Failed_Search_Already_In_Progress = 2 ,
k_EGameSearchErrorCode_Failed_No_Search_In_Progress = 3 ,
k_EGameSearchErrorCode_Failed_Not_Lobby_Leader = 4 , // if not the lobby leader can not call SearchForGameWithLobby
k_EGameSearchErrorCode_Failed_No_Host_Available = 5 , // no host is available that matches those search params
k_EGameSearchErrorCode_Failed_Search_Params_Invalid = 6 , // search params are invalid
k_EGameSearchErrorCode_Failed_Offline = 7 , // offline, could not communicate with server
k_EGameSearchErrorCode_Failed_NotAuthorized = 8 , // either the user or the application does not have priveledges to do this
k_EGameSearchErrorCode_Failed_Unknown_Error = 9 , // unknown error
} ;
enum EPlayerResult_t
{
k_EPlayerResultFailedToConnect = 1 , // failed to connect after confirming
k_EPlayerResultAbandoned = 2 , // quit game without completing it
k_EPlayerResultKicked = 3 , // kicked by other players/moderator/server rules
k_EPlayerResultIncomplete = 4 , // player stayed to end but game did not conclude successfully ( nofault to player )
k_EPlayerResultCompleted = 5 , // player completed game
} ;
2019-12-10 01:49:55 +08:00
enum ESteamIPv6ConnectivityProtocol
{
k_ESteamIPv6ConnectivityProtocol_Invalid = 0 ,
k_ESteamIPv6ConnectivityProtocol_HTTP = 1 , // because a proxy may make this different than other protocols
k_ESteamIPv6ConnectivityProtocol_UDP = 2 , // test UDP connectivity. Uses a port that is commonly needed for other Steam stuff. If UDP works, TCP probably works.
} ;
// For the above transport protocol, what do we think the local machine's connectivity to the internet over ipv6 is like
enum ESteamIPv6ConnectivityState
{
k_ESteamIPv6ConnectivityState_Unknown = 0 , // We haven't run a test yet
k_ESteamIPv6ConnectivityState_Good = 1 , // We have recently been able to make a request on ipv6 for the given protocol
k_ESteamIPv6ConnectivityState_Bad = 2 , // We failed to make a request, either because this machine has no ipv6 address assigned, or it has no upstream connectivity
} ;
2019-04-14 00:21:56 +08:00
// Define compile time assert macros to let us validate the structure sizes.
# define VALVE_COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
# if defined(__linux__) || defined(__APPLE__)
// The 32-bit version of gcc has the alignment requirement for uint64 and double set to
// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
// The 64-bit version of gcc has the alignment requirement for these types set to
// 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
// The 64-bit structure packing has to match the 32-bit structure packing for each platform.
# define VALVE_CALLBACK_PACK_SMALL
# else
# define VALVE_CALLBACK_PACK_LARGE
# endif
# if defined( VALVE_CALLBACK_PACK_SMALL )
# pragma pack( push, 4 )
# elif defined( VALVE_CALLBACK_PACK_LARGE )
# pragma pack( push, 8 )
# else
# error ???
# endif
typedef struct ValvePackingSentinel_t
{
uint32 m_u32 ;
uint64 m_u64 ;
uint16 m_u16 ;
double m_d ;
} ValvePackingSentinel_t ;
# pragma pack( pop )
# if defined(VALVE_CALLBACK_PACK_SMALL)
VALVE_COMPILE_TIME_ASSERT ( sizeof ( ValvePackingSentinel_t ) = = 24 )
# elif defined(VALVE_CALLBACK_PACK_LARGE)
VALVE_COMPILE_TIME_ASSERT ( sizeof ( ValvePackingSentinel_t ) = = 32 )
# else
# error ???
# endif
# endif // STEAMCLIENTPUBLIC_H