holywyvern/carbuncle

View on GitHub
gems/carbuncle-steamworks/include/steamclientpublic.h

Summary

Maintainability
Test Coverage
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose:
//
//=============================================================================

#ifndef STEAMCLIENTPUBLIC_H
#define STEAMCLIENTPUBLIC_H
#ifdef _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
{
    k_EResultNone = 0,                            // no result
    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
    k_EResultAccountDeleted = 114,                // account has been deleted
    k_EResultExistingUserCancelledLicense = 115,    // A license for this already exists, but cancelled
    k_EResultCommunityCooldown = 116,            // access is denied because of a community cooldown (probably from support profile data resets)
    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
};

// 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
    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
    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
    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.
    k_EAppOwnershipFlags_TimedTrial            = 0x200000,    // App is playable only for limited time
};


//-----------------------------------------------------------------------------
// 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
    k_EAppType_MusicAlbum            = 0x2000,    // "Video game soundtrack album"
    k_EAppType_Series                = 0x4000,    // Container app for video series
    k_EAppType_Comic_UNUSED            = 0x8000,    // Comic Book
    k_EAppType_Beta                    = 0x10000,    // this is a beta version of a game
        
    k_EAppType_Shortcut                = 0x40000000,    // just a shortcut, client side only
    k_EAppType_DepotOnly_DEPRECATED = 0x80000000,    // there shouldn't be any appinfo for depots
};



//-----------------------------------------------------------------------------
// 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;
const unsigned int k_unSteamUserDefaultInstance    = 1; // fixed instance for all individual users

// 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 |
        k_EMarketingMessageFlagsPlatformMac |
        k_EMarketingMessageFlagsPlatformLinux,
};



//-----------------------------------------------------------------------------
// 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;
}


//-----------------------------------------------------------------------------
// 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;
}


//-----------------------------------------------------------------------------
// 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
    k_eEVRHMDType_HTC_ViveCosmos = 5,    // HTC Vive Cosmos

    k_eEVRHMDType_HTC_Unknown = 20, // unknown htc hmd

    k_eEVRHMDType_Oculus_DK1 = 21, // Oculus DK1 
    k_eEVRHMDType_Oculus_DK2 = 22, // Oculus DK2
    k_eEVRHMDType_Oculus_Rift = 23, // Oculus Rift
    k_eEVRHMDType_Oculus_RiftS = 24, // Oculus Rift S
    k_eEVRHMDType_Oculus_Quest = 25, // Oculus Quest

    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
    k_eEVRHMDType_HP_Reverb = 82, // HP Reverb Windows MR headset
    k_eEVRHMDType_HP_ReverbG2 = 1463, // HP Reverb G2 Windows MR headset

    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

    k_eEVRHmdType_Valve_Unknown = 130, // Valve Unknown HMD
    k_eEVRHmdType_Valve_Index = 131, // Valve Index HMD

};


//-----------------------------------------------------------------------------
// Purpose: true if this is from an Oculus HMD
//-----------------------------------------------------------------------------
static inline bool BIsOculusHMD( EVRHMDType eType )
{
    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;
}


//-----------------------------------------------------------------------------
// 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),
};


//
// describes XP / progress restrictions to apply for games with duration control /
// anti-indulgence enabled for minor Steam China users.
//
// WARNING: DO NOT RENUMBER
enum EDurationControlProgress
{
    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
};


//
// describes which notification timer has expired, for steam china duration control feature
//
// WARNING: DO NOT RENUMBER
enum EDurationControlNotification
{
    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
};


//
// 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
};


#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)
        Assert( ( k_EAccountTypeIndividual != eAccountType ) || ( unAccountInstance == k_unSteamUserDefaultInstance ) );    // enforce that for individual accounts, instance is always 1
#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
        {
            m_steamid.m_comp.m_unAccountInstance = k_unSteamUserDefaultInstance;
        }
    }


    //-----------------------------------------------------------------------------
    // 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
        m_steamid.m_comp.m_unAccountInstance = k_unSteamUserDefaultInstance; // Steam2 only knew one instance
    }

    //-----------------------------------------------------------------------------
    // 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; }
        
    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 )
    {
        if ( m_steamid.m_comp.m_unAccountID == 0 || m_steamid.m_comp.m_unAccountInstance != k_unSteamUserDefaultInstance )
            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;
    }

    CGameID( const CGameID &that )
    {
        m_ulGameID = that.m_ulGameID;
    }

    CGameID& operator=( const CGameID & that )
    {
        m_ulGameID = that.m_ulGameID;
        return *this;
    }

    // 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
};


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
};


// 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