API Reference
Important Notes
Except for TapSDK_RestartAppIfNecessary, all other API functions must successfully call TapSDK_Init for initialization before use.
Calling other functions without initialization or after initialization failure will return errors or unexpected results.
- It is recommended to register the system state change callback immediately after successful initialization to get real-time notifications of TapTap client state changes.
- After registration, calling
TapSDK_RunCallbacks()will trigger the callback function to get the current system state. - After that, the callback function will only be triggered again when the system state changes, and you will get the changed system state.
TapSDK_RegisterCallback(TapEventID::SystemStateChanged, yourSystemStateNotificationHandler);
Data Type Definitions
Basic Types
typedef char ErrMsg[1024]; // Error message, maximum length 1023 bytes + '\0'
typedef void (T_CALLTYPE *callback_t)(TapEventID, void *); // Callback function type
// TapSDK interface return type; see enum TapSDK_Result_* for values
// - Note: For historical reasons, some APIs (e.g. Initialization, Authorization, CloudSave) use a different return type; see the respective API docs
typedef uint32_t TapSDK_Result;
typedef int64_t TapSDK_ErrorCode; // Error code, values refer to enum TapSDK_ErrorCode_*
typedef uint32_t TapSystemState; // TapTap client system state, values refer to enum TapSystemState_*
#pragma pack(push, 8)
// Error information structure
typedef struct {
TapSDK_ErrorCode code; // Error code
const char* message; // Error message
} TapSDK_Error;
// TapTap client system state notification
typedef struct {
TapSystemState state; // TapTap client current system state
const void* detail; // Notification details, available for some notifications; NULL if none
} TapSystemStateNotification;
// Information about the most recently started game session. When TapSystemStateNotification::state
// is TapSystemState_DupGameSession, use this structure to parse TapSystemStateNotification::detail
typedef struct {
const char* device_name; // Name of the device where the game was started
} TapSystemStateNotificationGameSessionInfo;
#pragma pack(pop)
Enumeration Types
Constants
Limits on lengths, counts, and other numeric values:
enum {
TapDLC_IdMaxLength = 32, // Maximum DLC ID length, including '\0'
TapDLC_NameMaxLength = 64, // Maximum DLC name length, including '\0'
TapDLC_MaxRequestedIdCount = 50, // Maximum number of DLC IDs allowed in the request array. Requests are currently limited to 20; the array size is 50 to allow future expansion
};
TapSDK_Init_Result
SDK initialization result enumeration:
enum class TapSDK_Init_Result : uint32_t {
OK = 0, // Initialization successful
FailedGeneric = 1, // Other errors
NoPlatform = 2, // TapTap platform not found
NotLaunchedByPlatform = 3, // Not launched through TapTap
PlatformVersionMismatch = 4 // Platform version mismatch; guide the user to upgrade both TapTap and the game to the latest version, then restart the game
};
TapUser_AsyncAuthorize_Result
User authorization request result enumeration:
enum class TapUser_AsyncAuthorize_Result : uint32_t {
Unknown = 0, // Unknown error, usually caused by uninitialized (TapSDK_Init not called) or initialization failure
OK = 1, // Successfully initiated authorization flow
Failed = 2, // Failed to initiate authorization flow, suggest prompting user to retry
InFlight = 3 // Authorization flow in progress, suggest ignoring error or prompting user to wait
};
TapEventID
Event ID enumeration:
enum class TapEventID : uint32_t {
Unknown = 0,
// TapTap client system state change notification.
// Register the callback function for this event after SDK initialization succeeds to get timely notifications of TapTap client state changes.
// Use TapSystemStateNotification structure to parse.
SystemStateChanged = 1,
AuthorizeFinished = 2002, // Authorization completion event
UserGetApprovedScopes = 2003, // Get user's currently approved scopes callback; parse with TapUserGetApprovedScopesResponse
GamePlayableStatusChanged = 4001, // Game playable status change event
DLCPlayableStatusChanged = 4002, // DLC playable status change event
CloudSaveList = 6001, // Get cloud save list
CloudSaveCreate = 6002, // Create cloud save
CloudSaveUpdate = 6003, // Update cloud save
CloudSaveDelete = 6004, // Delete cloud save
CloudSaveGetData = 6005, // Get cloud save data
CloudSaveGetCover = 6006, // Get cloud save cover
AchievementUnlock = 7001, // Unlock achievement
AchievementIncrement = 7002, // Increment steps
ComplianceEnsureRealName = 8001, // Real-name verification result callback; parse with TapComplianceEnsureRealNameResponse
ComplianceActionsEvent = 8002, // Anti-addiction notification; parse with TapComplianceActionsEvent
LeaderboardSubmitScores = 9001, // Submit scores; parse with TapLeaderboardSubmitScoresResponse
LeaderboardLoadScores = 9002, // Load leaderboard scores; parse with TapLeaderboardLoadScoresResponse
LeaderboardLoadMyScores = 9003, // Load current user's rank; parse with TapLeaderboardLoadMyScoresResponse
LeaderboardLoadMyCenteredScores = 9004, // Load scores near the user; parse with TapLeaderboardLoadMyCenteredScoresResponse
RelationGetFriendList = 10001, // Get friend list callback; parse with TapRelationGetFriendListResponse
RelationGetFollowingList = 10002, // Get following list callback; parse with TapRelationGetFollowingListResponse
RelationGetFanList = 10003, // Get fan list callback; parse with TapRelationGetFanListResponse
RelationSyncRelationshipWithOpenID = 10004, // Sync relationship (by OpenID) callback; parse with TapRelationSyncRelationshipResponse
RelationSyncRelationshipWithUnionID = 10005, // Sync relationship (by UnionID) callback; parse with TapRelationSyncRelationshipResponse
// Unread message count change notification. Register the callback for this event after SDK initialization succeeds to get timely notifications of unread message count changes.
// Parse with TapRelationUnreadMessageCountNotification structure.
RelationUnreadMessageCountChanged = 10101,
// New fan count change notification. Register the callback for this event after SDK initialization succeeds to get timely notifications of new fan count changes.
// Parse with TapRelationNewFanCountNotification structure.
RelationNewFanCountChanged = 10102,
// After the invitee accepts an "enter game" invitation, the game (on the invitee's side), if running, receives this event notification.
RelationGameInviteReceived = 10103,
// After the invitee accepts a "join team" invitation, , the game (on the invitee's side), if running, receives this event notification.
RelationTeamInviteReceived = 10104,
};
TapSDK_Result
TapSDK interface return value enumeration:
enum {
// [0, 1000) reserved for general errors
TapSDK_Result_OK = 0,
TapSDK_Result_Uninitialized = 1, // SDK not initialized; call TapSDK_Init and ensure it returns TapSDK_Init_Result::OK
TapSDK_Result_NoTapTapClient = 2, // TapTap client is not running
TapSDK_Result_TapTapClientOutdated = 3, // TapTap client is outdated; prompt the user to update to the latest TapTap client
TapSDK_Result_InvalidArgument = 4, // Invalid argument, e.g. NULL passed where not allowed
TapSDK_Result_SdkFailed = 5, // SDK internal error
TapSDK_Result_TapTapClientNotLoggedIn = 6, // TapTap client not logged in
TapSDK_Result_UnknownError = 7, // Unknown error
TapSDK_Result_NetworkError = 8, // Network error
TapSDK_Result_ForbiddenError = 9, // User does not have permission for the current action (e.g. the corresponding game service is not enabled)
};
For historical reasons, some APIs (e.g. Initialization, Authorization, CloudSave) do not use the TapSDK_Result return type; refer to the respective API documentation.
TapSDK_ErrorCode
Error code enumeration:
enum {
TapSDK_ErrorCode_Success = 0, // Request executed successfully
TapSDK_ErrorCode_Unknown = 1, // Unknown error
TapSDK_ErrorCode_Unauthorized = 2, // Invalid user credentials, please guide the user to re-login to TapTap
TapSDK_ErrorCode_MethodNotAllowed = 3, // Method not allowed
TapSDK_ErrorCode_Unimplemented = 4, // Method not implemented
TapSDK_ErrorCode_InvalidArguments = 5, // Invalid arguments
TapSDK_ErrorCode_Forbidden = 6, // User does not have permission for current action
TapSDK_ErrorCode_UserIsDeactivated = 7, // User is deactivated
TapSDK_ErrorCode_InternalServerError = 8, // Internal server error
TapSDK_ErrorCode_InternalSdkError = 9, // SDK internal error
TapSDK_ErrorCode_NetworkError = 10, // Network error
TapSDK_ErrorCode_NotFound = 11, // Resource not found
TapSDK_ErrorCode_InsufficientScope = 12, // The user has not granted access to this product/service; prompt about insufficient permission
TapSDK_ErrorCode_CloudSave_InvalidFileSize = 400000, // Invalid save file/cover size
TapSDK_ErrorCode_CloudSave_UploadRateLimit = 400001, // Save upload rate limit exceeded
TapSDK_ErrorCode_CloudSave_FileNotFound = 400002, // Save file not found
TapSDK_ErrorCode_CloudSave_FileCountLimitPerClient = 400003, // User's save file count limit exceeded for this app
TapSDK_ErrorCode_CloudSave_StorageSizeLimitPerClient = 400004, // User's storage size limit exceeded for this app
TapSDK_ErrorCode_CloudSave_TotalStorageSizeLimit = 400005, // User's total storage size limit exceeded
TapSDK_ErrorCode_CloudSave_Timeout = 400006, // Request timeout, usually due to network lag
TapSDK_ErrorCode_CloudSave_ConcurrentCallDisallowed = 400007, // Cloud save upload concurrent calls exceed 10, or concurrently updating the same cloud save
TapSDK_ErrorCode_CloudSave_StorageServerError = 400008, // Storage server error
TapSDK_ErrorCode_CloudSave_InvalidName = 400009, // Invalid save name
TapSDK_ErrorCode_Leaderboard_PeriodExpired = 500000, // The leaderboard period has expired; prompt the user to view other periods
TapSDK_ErrorCode_Leaderboard_NotFound = 500001, // Leaderboard ID not found; verify the ID is correct
TapSDK_ErrorCode_Leaderboard_InvalidArgument = 500002, // Invalid arguments, e.g. leaderboard_id does not match client_id
TapSDK_ErrorCode_OnlineBattle_RequestRateLimitExceeded = 600001, // Request rate limit exceeded
TapSDK_ErrorCode_OnlineBattle_MaliciousUser = 600002, // Identified as malicious user; request denied or connection closed. Do not reconnect
TapSDK_ErrorCode_OnlineBattle_TooManyConnections = 600003, // Kicked due to too many concurrent connections. Do not reconnect to avoid reconnect loops
TapSDK_ErrorCode_OnlineBattle_InvalidAuthorization = 600004, // Invalid auth info; uncommon. If it occurs, try reconnecting
TapSDK_ErrorCode_OnlineBattle_Unauthorized = 600005, // Connection auth not completed; uncommon. If it occurs, try reconnecting
TapSDK_ErrorCode_OnlineBattle_AlreadyConnected = 600006, // Already connected. Second Connect after success returns this
TapSDK_ErrorCode_OnlineBattle_PreviousRequestInProgress = 600007, // Previous request still in progress; new request rejected
TapSDK_ErrorCode_OnlineBattle_NotInRoom = 600009, // Not in a room yet
TapSDK_ErrorCode_OnlineBattle_AlreadyInRoom = 600010, // Already in a room; cannot join again
TapSDK_ErrorCode_OnlineBattle_NotRoomOwner = 600011, // Not room owner; cannot perform this action
TapSDK_ErrorCode_OnlineBattle_RoomFull = 600012, // Room is full; cannot join
TapSDK_ErrorCode_OnlineBattle_RoomNotExist = 600013, // Room does not exist
TapSDK_ErrorCode_OnlineBattle_FrameSyncNotStarted = 600014, // Frame sync not started; cannot perform this action
TapSDK_ErrorCode_OnlineBattle_FrameSyncAlreadyStarted = 600015, // Frame sync already started; cannot perform this action
TapSDK_ErrorCode_OnlineBattle_FrameInputSizeLimitExceeded = 600016, // Frame input data size exceeds limit
TapSDK_ErrorCode_OnlineBattle_FrameInputCountLimitExceeded = 600017, // Per-frame input count exceeds limit
TapSDK_ErrorCode_OnlineBattle_PlayerNotFound = 600018 // Player not found
};
TapSystemState
TapTap client system state enumeration:
enum {
TapSystemState_Unknown = 0,
// TapTap client can currently access TapTap server normally.
// When developers receive this state notification,
// they can remove the restrictions imposed on the game when they received the TapSystemState_PlatformOffline state notification.
TapSystemState_PlatformOnline = 1,
// TapTap client currently cannot access TapTap server: network down or TapTap server failure.
// When TapTap client is in this state, it cannot get real-time notifications of game/DLC ownership changes, such as refunds.
// When developers receive this state notification, they can remind players to check network status or impose other game restrictions.
TapSystemState_PlatformOffline = 2,
// TapTap client exits.
// When developers receive this state notification, they should immediately save the game state and then exit the game.
TapSystemState_PlatformShutdown = 3,
// When the same user starts the same game on multiple devices, the game process started earlier receives this state notification.
// When this notification is received, use TapSystemStateNotificationGameSessionInfo
// to parse TapSystemStateNotification::detail and get information about the most recently started game session, such as the device name.
TapSystemState_DupGameSession = 4,
};
Structure Types
AuthorizeFinishedResponse
Authorization completion response structure:
struct AuthorizeFinishedResponse {
bool is_cancel; // Whether user canceled authorization
char error[1024]; // Error message
char token_type[32]; // Token type
char kid[8*1024]; // Key ID
char mac_key[8*1024]; // MAC key
char mac_algorithm[32]; // MAC algorithm
char scope[1024]; // Permission scope
};
TapUserGetApprovedScopesResponse
Response structure for fetching the user's approved scopes:
typedef struct {
int64_t request_id; // Request ID. Returned as-is from the developer's asynchronous call, used to correlate with the original request
const TapSDK_Error* error; // Error info. NULL indicates success; non-NULL indicates failure—handle according to the error code
uint32_t scope_count; // Number of approved scopes
const char** scopes; // Array of the user's currently approved scopes
} TapUserGetApprovedScopesResponse;
GamePlayableStatusChangedResponse
Game playable status change response structure:
struct GamePlayableStatusChangedResponse {
bool is_playable; // Whether game is playable
};
DLCPlayableStatusChangedResponse
DLC playable status change response structure:
struct DLCPlayableStatusChangedResponse {
char dlc_id[TapDLC_IdMaxLength]; // DLC ID
bool is_playable; // Whether DLC is playable
};
TapDLCQueryDetailsRequest
Request structure for querying DLC product details:
typedef struct {
int32_t id_count; // Number of product IDs, up to 20 per request
char ids[TapDLC_MaxRequestedIdCount][TapDLC_IdMaxLength]; // Product ID list
} TapDLCQueryDetailsRequest;
DLC product detail structure:
typedef struct {
char id[TapDLC_IdMaxLength]; // Product ID
char name[TapDLC_NameMaxLength]; // Product name
int32_t type; // 0: unknown, 1: DLC, 2: full game
bool owned; // true: purchased, false: not purchased
int32_t original_price; // Original price in cents
int32_t discounted_price; // Discounted price in cents. Equals original_price when no discount is active
int64_t discount_start_time; // Seconds since 1970. 0 when no discount is active
int64_t discount_end_time; // Seconds since 1970. 0 when no discount is active
} TapDLCDetails;
Response structure for querying DLC product details:
typedef struct {
int32_t detail_count; // Number of product details returned
TapDLCDetails details[TapDLC_MaxRequestedIdCount]; // Product details
} TapDLCQueryDetailsResponse;
SDK Core Interfaces
TapSDK_RestartAppIfNecessary
Check if app restart is necessary.
bool TapSDK_RestartAppIfNecessary(const char *clientID);
Parameters:
clientID: Client ID
Return Value:
true: Restart required, TapTap will reopen the game, please exit the game process immediatelyfalse: Restart not required, can continue initialization
Usage Example:
const char* clientID = "your_client_id";
if (TapSDK_RestartAppIfNecessary(clientID)) {
std::cout << "App restart required" << std::endl;
return 0; // Exit immediately
}
Notes:
- This function must be called before
TapSDK_Init - If it returns true, exit the program immediately and wait for TapTap to restart the game
TapSDK_Init
Initialize SDK.
TapSDK_Init_Result TapSDK_Init(ErrMsg *errMsg, const char *pubKey);
Parameters:
errMsg: Error message buffer, length 1024 bytespubKey: Public key obtained from TapTap Developer Center
Return Value:
TapSDK_Init_Result: Initialization result enumeration
Usage Example:
ErrMsg errMsg;
const char* pubKey = "your_public_key";
TapSDK_Init_Result result = TapSDK_Init(&errMsg, pubKey);
switch (result) {
case TapSDK_Init_Result::OK:
std::cout << "Initialization successful" << std::endl;
// It is recommended to register the system state change callback immediately after successful initialization to get real-time notifications of TapTap client state changes.
// After registration, calling TapSDK_RunCallbacks() will trigger the callback function to get the current system state.
// After that, the callback function will only be triggered again when the system state changes, and you will get the changed system state.
TapSDK_RegisterCallback(TapEventID::SystemStateChanged, yourSystemStateNotificationHandler);
break;
case TapSDK_Init_Result::NoPlatform:
std::cout << "TapTap platform not found, please download and install TapTap launcher" << std::endl;
std::cout << "Download URL: https://www.taptap.cn/mobile" << std::endl;
break;
case TapSDK_Init_Result::NotLaunchedByPlatform:
std::cout << "Game not launched through TapTap launcher, please reopen the game from the launcher" << std::endl;
break;
case TapSDK_Init_Result::PlatformVersionMismatch:
std::cout << "Platform version mismatch, please upgrade TapTap launcher or game to the latest version" << std::endl;
break;
default:
std::cout << "Initialization failed: " << errMsg << std::endl;
std::cout << "Please close the game and reopen it from TapTap" << std::endl;
break;
}
TapSDK_Shutdown
Shutdown SDK and release resources.
bool TapSDK_Shutdown();
Return Value:
true: Successfully shut downfalse: Shutdown failed (usually due to uninitialized (TapSDK_Init not called) or initialization failure)
Usage Example:
if (TapSDK_Shutdown()) {
std::cout << "SDK successfully shut down" << std::endl;
} else {
std::cout << "SDK shutdown failed" << std::endl;
}
TapSDK_GetClientID
Get current client ID.
bool TapSDK_GetClientID(char *buffer);
Parameters:
buffer: Buffer for storing client ID, fixed length 256 bytes
Return Value:
true: Successfully retrievedfalse: Retrieval failed (usually due to uninitialized (TapSDK_Init not called) or initialization failure)
Usage Example:
char clientID[256];
if (TapSDK_GetClientID(clientID)) {
std::cout << "Client ID: " << clientID << std::endl;
} else {
std::cout << "Failed to get Client ID, please check if SDK is properly initialized" << std::endl;
}
Callback Related Functions
- The memory pointed to by the data pointer
datain the callback function is managed by the SDK, callers do not need to release it - After the callback function returns, the SDK will automatically release this memory. If you need to use it for a long time, please make a copy yourself
TapSDK_RegisterCallback
Register event callback.
void TapSDK_RegisterCallback(TapEventID eventID, callback_t callback);
Parameters:
eventID: Event IDcallback: Callback function
Usage Example:
void T_CALLTYPE OnAuthorizeFinished(TapEventID eventID, void* data) {
if (eventID == TapEventID::AuthorizeFinished) {
AuthorizeFinishedResponse* response = (AuthorizeFinishedResponse*)data;
// Handle authorization completion event
}
}
// Register callback
TapSDK_RegisterCallback(TapEventID::AuthorizeFinished, OnAuthorizeFinished);
TapSDK_UnregisterCallback
Unregister event callback.
void TapSDK_UnregisterCallback(TapEventID eventID, callback_t callback);
Parameters:
eventID: Event IDcallback: Callback function to unregister
Usage Example:
// Unregister callback
TapSDK_UnregisterCallback(TapEventID::AuthorizeFinished, OnAuthorizeFinished);
TapSDK_RunCallbacks
Process callback events, recommended to call every frame.
void TapSDK_RunCallbacks();
Usage Example:
// Call in game main loop
while (gameRunning) {
TapSDK_RunCallbacks(); // Process SDK events
// Game logic
UpdateGame();
RenderGame();
Sleep(16); // Control frame rate
}
User Related Functions
TapUser_AsyncAuthorize
Asynchronously request user authorization (simplified version).
TapUser_AsyncAuthorize_Result TapUser_AsyncAuthorize(const char* scopes);
Parameters:
scopes: Permission scope string, multiple permissions separated by commas
Return Value:
TapUser_AsyncAuthorize_Result::Unknown: Unknown error, usually due to uninitialized or initialization failureTapUser_AsyncAuthorize_Result::OK: Successfully initiated authorization flow, waiting for user confirmationTapUser_AsyncAuthorize_Result::Failed: Failed to initiate authorization flow, suggest prompting user to retryTapUser_AsyncAuthorize_Result::InFlight: Authorization flow in progress, suggest ignoring or prompting user to wait
Common Permission Scopes:
"public_profile": Basic user information"user_friends": Friend information"public_profile,user_friends": Multiple permissions
Usage Example:
// Register authorization completion callback
TapSDK_RegisterCallback(TapEventID::AuthorizeFinished, OnAuthorizeFinished);
// Request basic user information permission
TapUser_AsyncAuthorize_Result result = TapUser_AsyncAuthorize("public_profile");
switch (result) {
case TapUser_AsyncAuthorize_Result::OK:
std::cout << "Authorization request sent, waiting for user confirmation" << std::endl;
break;
case TapUser_AsyncAuthorize_Result::Failed:
std::cout << "Failed to initiate authorization, please retry" << std::endl;
break;
case TapUser_AsyncAuthorize_Result::InFlight:
std::cout << "Authorization flow in progress, please wait" << std::endl;
break;
case TapUser_AsyncAuthorize_Result::Unknown:
std::cout << "Authorization failed, please check SDK initialization status" << std::endl;
break;
}
TapUser_AsyncGetApprovedScopes
Asynchronously fetch the user's currently approved scopes.
TapSDK_Result TapUser_AsyncGetApprovedScopes(int64_t request_id);
Parameters:
request_id: Developer-generated request ID. It is returned as-is in the callback once the request completes, allowing the developer to correlate it with the original request
Return Value:
- Result of initiating the request. If it is not
TapSDK_Result_OK, the request failed to start and the callback will not be triggered
Usage Example:
// Register the approved-scopes callback
void T_CALLTYPE OnUserGetApprovedScopes(TapEventID eventID, void* data) {
TapUserGetApprovedScopesResponse* response = (TapUserGetApprovedScopesResponse*)data;
std::cout << "request_id: " << response->request_id << std::endl;
if (response->error != nullptr) {
std::cout << "Failed to get approved scopes, error code: " << response->error->code
<< ", message: " << response->error->message << std::endl;
return;
}
std::cout << "Approved scope count: " << response->scope_count << std::endl;
for (uint32_t i = 0; i < response->scope_count; ++i) {
std::cout << "scope[" << i << "] = " << response->scopes[i] << std::endl;
}
}
TapSDK_RegisterCallback(TapEventID::UserGetApprovedScopes, OnUserGetApprovedScopes);
// Initiate the async request
int64_t requestID = 1001; // Generated by the developer
TapSDK_Result result = TapUser_AsyncGetApprovedScopes(requestID);
if (result != TapSDK_Result_OK) {
std::cout << "Failed to initiate get-approved-scopes request, error code: " << result << std::endl;
}
TapUser_GetOpenID
Get user OpenID.
bool TapUser_GetOpenID(char *buffer);
Parameters:
buffer: Buffer for storing OpenID, fixed length 256 bytes
Return Value:
true: Successfully retrievedfalse: Retrieval failed (usually due to uninitialized or initialization failure)
Usage Example:
char openID[256];
if (TapUser_GetOpenID(openID)) {
std::cout << "User OpenID: " << openID << std::endl;
} else {
std::cout << "Failed to get OpenID, please check SDK initialization status and user authorization status" << std::endl;
}
License Verification Functions
TapApps_IsOwned
Check if user owns the current game.
- Only premium games need to call: Free games do not need ownership verification
- Verified at initialization: Game ownership is verified when
TapSDK_Initsucceeds - Runtime monitoring: During game runtime, it only returns
falsewhen user loses ownership (e.g., refund)
bool TapApps_IsOwned();
Return Value:
true: User owns the current gamefalse: User does not own the current game (usually occurs in cases like refund)
Usage Example:
// Only premium games need to check
if (TapApps_IsOwned()) {
std::cout << "User owns this game, can continue running" << std::endl;
// Continue game logic
} else {
std::cout << "User has lost game ownership (possibly refunded)" << std::endl;
// Save progress and exit game
SaveGameAndExit();
return -1;
}
DLC Related Functions
TapDLC_IsOwned
Query if user owns the specified DLC.
bool TapDLC_IsOwned(const char *dlc_id);
Parameters:
dlc_id: DLC ID
Return Value:
true: User owns the DLCfalse: User does not own the DLC
Usage Example:
const char* dlcID = "expansion_pack_1";
if (TapDLC_IsOwned(dlcID)) {
std::cout << "User owns DLC: " << dlcID << std::endl;
EnableDLCContent(dlcID);
} else {
std::cout << "User does not own DLC: " << dlcID << std::endl;
DisableDLCContent(dlcID);
}
TapDLC_QueryDetails
Queries product details for multiple DLC products, including the product name, type, ownership status, original price, and discount information. You can query up to 20 DLC IDs in one call.
TapSDK_Result TapDLC_QueryDetails(
const TapDLCQueryDetailsRequest* request,
TapDLCQueryDetailsResponse* response
);
Parameters:
request: The query request.id_countis the number of DLC IDs to query, andidsis the DLC ID list.response: The query result.detail_countis the number of products actually returned, anddetailsis the product detail list. If none of the specified IDs exist,detail_countis 0.
Product Detail Fields:
id: Product IDname: Product nametype: Product type.0means unknown,1means DLC, and2means the full game.owned: Whether the product has been purchasedoriginal_price: Original price in centsdiscounted_price: Discounted price in cents. When no discount is active, this equalsoriginal_price.discount_start_time,discount_end_time: Discount start and end times as Unix timestamps in seconds. When no discount is active, both values are0.
Return Value:
TapSDK_Result_OK: The query succeeded andresponsecan be read.- Other values: The query failed. See
TapSDK_Resultfor details.
Usage Example:
TapDLCQueryDetailsRequest request = {
2,
{"your_dlc_id_1", "your_dlc_id_2"}
};
TapDLCQueryDetailsResponse response{};
TapSDK_Result result = TapDLC_QueryDetails(&request, &response);
if (result != TapSDK_Result_OK) {
std::cout << "Failed to query DLC product details. Error code: " << result << std::endl;
return;
}
for (int32_t i = 0; i < response.detail_count; ++i) {
const TapDLCDetails& detail = response.details[i];
std::cout << "DLC ID: " << detail.id << std::endl;
std::cout << "Product name: " << detail.name << std::endl;
std::cout << "Product type: " << detail.type << std::endl;
std::cout << "Owned: " << (detail.owned ? "Yes" : "No") << std::endl;
std::cout << "Original price (cents): " << detail.original_price << std::endl;
std::cout << "Discounted price (cents): " << detail.discounted_price << std::endl;
std::cout << "Discount start time: " << detail.discount_start_time << std::endl;
std::cout << "Discount end time: " << detail.discount_end_time << std::endl;
}
TapDLC_ShowStore
Show the store page for the specified DLC.
bool TapDLC_ShowStore(const char *dlc_id);
Parameters:
dlc_id: DLC ID
Return Value:
true: Successfully displayed store pagefalse: Display failed
Usage Example:
const char* dlcID = "expansion_pack_1";
if (!TapDLC_IsOwned(dlcID)) {
// User does not own the DLC, guide the user to purchase it
if (TapDLC_ShowStore(dlcID)) {
std::cout << "DLC store page opened" << std::endl;
} else {
std::cout << "Failed to open DLC store page" << std::endl;
}
}
Event Handling Examples
Complete Event Handling Example
#include "taptap_api.h"
#include <iostream>
// Authorization completion event handling
void T_CALLTYPE OnAuthorizeFinished(TapEventID eventID, void* data) {
if (eventID == TapEventID::AuthorizeFinished) {
AuthorizeFinishedResponse* response = (AuthorizeFinishedResponse*)data;
if (response->is_cancel) {
std::cout << "User canceled authorization" << std::endl;
} else if (strlen(response->error) > 0) {
std::cout << "Authorization failed: " << response->error << std::endl;
} else {
std::cout << "Authorization successful!" << std::endl;
std::cout << "Token type: " << response->token_type << std::endl;
std::cout << "Permission scope: " << response->scope << std::endl;
// Get user information
char openID[256];
if (TapUser_GetOpenID(openID)) {
std::cout << "User OpenID: " << openID << std::endl;
}
}
}
}
// Game playable status change event handling
void T_CALLTYPE OnGameStatusChanged(TapEventID eventID, void* data) {
if (eventID == TapEventID::GamePlayableStatusChanged) {
GamePlayableStatusChangedResponse* response = (GamePlayableStatusChangedResponse*)data;
if (response->is_playable) {
std::cout << "Game can now continue running" << std::endl;
} else {
std::cout << "Game is no longer available, possibly refunded" << std::endl;
// Should save game progress and exit
SaveGameAndExit();
}
}
}
// DLC status change event handling
void T_CALLTYPE OnDLCStatusChanged(TapEventID eventID, void* data) {
if (eventID == TapEventID::DLCPlayableStatusChanged) {
DLCPlayableStatusChangedResponse* response = (DLCPlayableStatusChangedResponse*)data;
std::cout << "DLC " << response->dlc_id
<< (response->is_playable ? " is now available" : " is now unavailable") << std::endl;
if (response->is_playable) {
EnableDLCFeatures(response->dlc_id);
} else {
DisableDLCFeatures(response->dlc_id);
}
}
}
void SetupEventHandlers() {
// Register all event callbacks
TapSDK_RegisterCallback(TapEventID::AuthorizeFinished, OnAuthorizeFinished);
TapSDK_RegisterCallback(TapEventID::GamePlayableStatusChanged, OnGameStatusChanged);
TapSDK_RegisterCallback(TapEventID::DLCPlayableStatusChanged, OnDLCStatusChanged);
}
Consistent Random Number Generator
TapSDK_CreateRandomNumberGenerator
Create a consistent random number generator; thread-safe. Generators created with the same seed produce the same random sequence.
int64_t TapSDK_CreateRandomNumberGenerator(int32_t seed);
Parameters:
seed: Random seed; generators created with the same seed produce the same random sequence
Return Value:
- Non-zero: Success, returns generator ID
0: Failure, returns 0
TapSDK_RandomInt
Generate a random integer in [0, 0x7fffffff]; thread-safe.
int32_t TapSDK_RandomInt(int64_t rand_generator_id);
Parameters:
rand_generator_id: Random number generator ID returned by TapSDK_CreateRandomNumberGenerator()
Return Value:
[0, 0x7fffffff]: Random positive integer when generator ID is valid-1: When generator ID is invalid or destroyed
TapSDK_DestroyRandomNumberGenerator
Destroy the random number generator; thread-safe. No-op if the given generator ID is invalid or already destroyed.
void TapSDK_DestroyRandomNumberGenerator(int64_t rand_generator_id);
Parameters:
rand_generator_id: Random number generator ID returned by TapSDK_CreateRandomNumberGenerator()
Usage Example
// Create random number generator
int32_t seed = 12345;
int64_t randGenID = TapSDK_CreateRandomNumberGenerator(seed);
if (randGenID == 0) {
std::cout << "TapSDK_CreateRandomNumberGenerator() failed" << std::endl;
return -1;
}
// Generate random integer
int32_t randomValue = TapSDK_RandomInt(randGenID);
if (randomValue >= 0) {
std::cout << "Random number: " << randomValue << std::endl;
} else {
std::cout << "Invalid Random Number Generator ID" << std::endl;
}
// Destroy random number generator
TapSDK_DestroyRandomNumberGenerator(randGenID);