#ifndef RC_CLIENT_H
#define RC_CLIENT_H
#include "rc_api_request.h"
#include "rc_error.h"
#include <stddef.h>
#include <stdint.h>
#include <time.h>
RC_BEGIN_C_DECLS
typedef struct rc_client_t rc_client_t;
typedef struct rc_client_async_handle_t rc_client_async_handle_t;
typedef uint32_t (RC_CCONV *rc_client_read_memory_func_t)(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client);
typedef void (RC_CCONV *rc_client_server_callback_t)(const rc_api_server_response_t* server_response, void* callback_data);
typedef void (RC_CCONV *rc_client_server_call_t)(const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client);
typedef void (RC_CCONV *rc_client_callback_t)(int result, const char* error_message, rc_client_t* client, void* userdata);
typedef void (RC_CCONV *rc_client_message_callback_t)(const char* message, const rc_client_t* client);
RC_EXPORT rc_client_t* RC_CCONV rc_client_create(rc_client_read_memory_func_t read_memory_function, rc_client_server_call_t server_call_function);
RC_EXPORT void RC_CCONV rc_client_destroy(rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_hardcore_enabled(rc_client_t* client, int enabled);
RC_EXPORT int RC_CCONV rc_client_get_hardcore_enabled(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_encore_mode_enabled(rc_client_t* client, int enabled);
RC_EXPORT int RC_CCONV rc_client_get_encore_mode_enabled(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_unofficial_enabled(rc_client_t* client, int enabled);
RC_EXPORT int RC_CCONV rc_client_get_unofficial_enabled(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_spectator_mode_enabled(rc_client_t* client, int enabled);
RC_EXPORT int RC_CCONV rc_client_get_spectator_mode_enabled(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_userdata(rc_client_t* client, void* userdata);
RC_EXPORT void* RC_CCONV rc_client_get_userdata(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_host(rc_client_t* client, const char* hostname);
typedef uint64_t rc_clock_t;
typedef rc_clock_t (RC_CCONV *rc_get_time_millisecs_func_t)(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_get_time_millisecs_function(rc_client_t* client, rc_get_time_millisecs_func_t handler);
RC_EXPORT void RC_CCONV rc_client_abort_async(rc_client_t* client, rc_client_async_handle_t* async_handle);
RC_EXPORT size_t RC_CCONV rc_client_get_user_agent_clause(rc_client_t* client, char buffer[], size_t buffer_size);
RC_EXPORT int RC_CCONV rc_client_is_disconnected(rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_enable_logging(rc_client_t* client, int level, rc_client_message_callback_t callback);
enum {
RC_CLIENT_LOG_LEVEL_NONE = 0,
RC_CLIENT_LOG_LEVEL_ERROR = 1,
RC_CLIENT_LOG_LEVEL_WARN = 2,
RC_CLIENT_LOG_LEVEL_INFO = 3,
RC_CLIENT_LOG_LEVEL_VERBOSE = 4,
NUM_RC_CLIENT_LOG_LEVELS = 5
};
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_password(rc_client_t* client,
const char* username, const char* password,
rc_client_callback_t callback, void* callback_userdata);
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_token(rc_client_t* client,
const char* username, const char* token,
rc_client_callback_t callback, void* callback_userdata);
RC_EXPORT void RC_CCONV rc_client_logout(rc_client_t* client);
typedef struct rc_client_user_t {
const char* display_name;
const char* username;
const char* token;
uint32_t score;
uint32_t score_softcore;
uint32_t num_unread_messages;
const char* avatar_url;
} rc_client_user_t;
RC_EXPORT const rc_client_user_t* RC_CCONV rc_client_get_user_info(const rc_client_t* client);
RC_EXPORT int RC_CCONV rc_client_user_get_image_url(const rc_client_user_t* user, char buffer[], size_t buffer_size);
typedef struct rc_client_user_game_summary_t {
uint32_t num_core_achievements;
uint32_t num_unofficial_achievements;
uint32_t num_unlocked_achievements;
uint32_t num_unsupported_achievements;
uint32_t points_core;
uint32_t points_unlocked;
time_t beaten_time;
time_t completed_time;
} rc_client_user_game_summary_t;
RC_EXPORT void RC_CCONV rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary);
typedef struct rc_client_all_user_progress_entry_t {
uint32_t game_id;
uint32_t num_achievements;
uint32_t num_unlocked_achievements;
uint32_t num_unlocked_achievements_hardcore;
} rc_client_all_user_progress_entry_t;
typedef struct rc_client_all_user_progress_t {
rc_client_all_user_progress_entry_t* entries;
uint32_t num_entries;
} rc_client_all_user_progress_t;
typedef void(RC_CCONV* rc_client_fetch_all_user_progress_callback_t)(int result, const char* error_message,
rc_client_all_user_progress_t* list,
rc_client_t* client, void* callback_userdata);
RC_EXPORT rc_client_async_handle_t* RC_CCONV
rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id,
rc_client_fetch_all_user_progress_callback_t callback, void* callback_userdata);
RC_EXPORT void RC_CCONV rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list);
#ifdef RC_CLIENT_SUPPORTS_HASH
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_load_game(rc_client_t* client,
uint32_t console_id, const char* file_path,
const uint8_t* data, size_t data_size,
rc_client_callback_t callback, void* callback_userdata);
#endif
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_game(rc_client_t* client, const char* hash,
rc_client_callback_t callback, void* callback_userdata);
RC_EXPORT int RC_CCONV rc_client_get_load_game_state(const rc_client_t* client);
enum {
RC_CLIENT_LOAD_GAME_STATE_NONE,
RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME,
RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN,
RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA,
RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION,
RC_CLIENT_LOAD_GAME_STATE_DONE,
RC_CLIENT_LOAD_GAME_STATE_ABORTED
};
RC_EXPORT int RC_CCONV rc_client_is_game_loaded(const rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_unload_game(rc_client_t* client);
typedef struct rc_client_game_t {
uint32_t id;
uint32_t console_id;
const char* title;
const char* hash;
const char* badge_name;
const char* badge_url;
} rc_client_game_t;
RC_EXPORT const rc_client_game_t* RC_CCONV rc_client_get_game_info(const rc_client_t* client);
RC_EXPORT int RC_CCONV rc_client_game_get_image_url(const rc_client_game_t* game, char buffer[], size_t buffer_size);
#ifdef RC_CLIENT_SUPPORTS_HASH
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* file_path,
const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata);
#endif
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media_from_hash(rc_client_t* client, const char* hash,
rc_client_callback_t callback, void* callback_userdata);
typedef struct rc_client_subset_t {
uint32_t id;
const char* title;
char badge_name[16];
uint32_t num_achievements;
uint32_t num_leaderboards;
const char* badge_url;
} rc_client_subset_t;
RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id);
typedef struct rc_client_hash_library_entry_t {
char hash[33];
uint32_t game_id;
} rc_client_hash_library_entry_t;
typedef struct rc_client_hash_library_t {
rc_client_hash_library_entry_t* entries;
uint32_t num_entries;
} rc_client_hash_library_t;
typedef void(RC_CCONV* rc_client_fetch_hash_library_callback_t)(int result, const char* error_message,
rc_client_hash_library_t* list, rc_client_t* client,
void* callback_userdata);
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_hash_library(
rc_client_t* client, uint32_t console_id, rc_client_fetch_hash_library_callback_t callback, void* callback_userdata);
RC_EXPORT void RC_CCONV rc_client_destroy_hash_library(rc_client_hash_library_t* list);
enum {
RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE = 0,
RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE = 1,
RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED = 2,
RC_CLIENT_ACHIEVEMENT_STATE_DISABLED = 3,
NUM_RC_CLIENT_ACHIEVEMENT_STATES = 4
};
enum {
RC_CLIENT_ACHIEVEMENT_CATEGORY_NONE = 0,
RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE = (1 << 0),
RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL = (1 << 1),
RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL = RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE | RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL
};
enum {
RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD = 0,
RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE = 1,
RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION = 2,
RC_CLIENT_ACHIEVEMENT_TYPE_WIN = 3
};
enum {
RC_CLIENT_ACHIEVEMENT_BUCKET_UNKNOWN = 0,
RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED = 1,
RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED = 2,
RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED = 3,
RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL = 4,
RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED = 5,
RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE = 6,
RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE = 7,
RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED = 8,
NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS = 9
};
enum {
RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE = 0,
RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE = (1 << 0),
RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE = (1 << 1),
RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH = RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE | RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE
};
typedef struct rc_client_achievement_t {
const char* title;
const char* description;
char badge_name[8];
char measured_progress[24];
float measured_percent;
uint32_t id;
uint32_t points;
time_t unlock_time;
uint8_t state;
uint8_t category;
uint8_t bucket;
uint8_t unlocked;
float rarity;
float rarity_hardcore;
uint8_t type;
const char* badge_url;
const char* badge_locked_url;
} rc_client_achievement_t;
RC_EXPORT const rc_client_achievement_t* RC_CCONV rc_client_get_achievement_info(rc_client_t* client, uint32_t id);
RC_EXPORT int RC_CCONV rc_client_achievement_get_image_url(const rc_client_achievement_t* achievement, int state, char buffer[], size_t buffer_size);
typedef struct rc_client_achievement_bucket_t {
const rc_client_achievement_t** achievements;
uint32_t num_achievements;
const char* label;
uint32_t subset_id;
uint8_t bucket_type;
} rc_client_achievement_bucket_t;
typedef struct rc_client_achievement_list_t {
const rc_client_achievement_bucket_t* buckets;
uint32_t num_buckets;
} rc_client_achievement_list_t;
enum {
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE = 0,
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS = 1
};
RC_EXPORT rc_client_achievement_list_t* RC_CCONV rc_client_create_achievement_list(rc_client_t* client, int category, int grouping);
RC_EXPORT void RC_CCONV rc_client_destroy_achievement_list(rc_client_achievement_list_t* list);
RC_EXPORT int RC_CCONV rc_client_has_achievements(rc_client_t* client);
RC_EXPORT int RC_CCONV rc_client_get_award_achievement_pending_count(rc_client_t* client);
enum {
RC_CLIENT_LEADERBOARD_STATE_INACTIVE = 0,
RC_CLIENT_LEADERBOARD_STATE_ACTIVE = 1,
RC_CLIENT_LEADERBOARD_STATE_TRACKING = 2,
RC_CLIENT_LEADERBOARD_STATE_DISABLED = 3,
NUM_RC_CLIENT_LEADERBOARD_STATES = 4
};
enum {
RC_CLIENT_LEADERBOARD_FORMAT_TIME = 0,
RC_CLIENT_LEADERBOARD_FORMAT_SCORE = 1,
RC_CLIENT_LEADERBOARD_FORMAT_VALUE = 2,
NUM_RC_CLIENT_LEADERBOARD_FORMATS = 3
};
#define RC_CLIENT_LEADERBOARD_DISPLAY_SIZE 24
typedef struct rc_client_leaderboard_t {
const char* title;
const char* description;
const char* tracker_value;
uint32_t id;
uint8_t state;
uint8_t format;
uint8_t lower_is_better;
} rc_client_leaderboard_t;
RC_EXPORT const rc_client_leaderboard_t* RC_CCONV rc_client_get_leaderboard_info(const rc_client_t* client, uint32_t id);
typedef struct rc_client_leaderboard_tracker_t {
char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
uint32_t id;
} rc_client_leaderboard_tracker_t;
typedef struct rc_client_leaderboard_bucket_t {
const rc_client_leaderboard_t** leaderboards;
uint32_t num_leaderboards;
const char* label;
uint32_t subset_id;
uint8_t bucket_type;
} rc_client_leaderboard_bucket_t;
typedef struct rc_client_leaderboard_list_t {
const rc_client_leaderboard_bucket_t* buckets;
uint32_t num_buckets;
} rc_client_leaderboard_list_t;
enum {
RC_CLIENT_LEADERBOARD_BUCKET_UNKNOWN = 0,
RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE = 1,
RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE = 2,
RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED = 3,
RC_CLIENT_LEADERBOARD_BUCKET_ALL = 4,
NUM_RC_CLIENT_LEADERBOARD_BUCKETS = 5
};
enum {
RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE = 0,
RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING = 1
};
RC_EXPORT rc_client_leaderboard_list_t* RC_CCONV rc_client_create_leaderboard_list(rc_client_t* client, int grouping);
RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_list(rc_client_leaderboard_list_t* list);
RC_EXPORT int RC_CCONV rc_client_has_leaderboards(rc_client_t* client, int include_hidden);
typedef struct rc_client_leaderboard_entry_t {
const char* user;
char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
time_t submitted;
uint32_t rank;
uint32_t index;
} rc_client_leaderboard_entry_t;
typedef struct rc_client_leaderboard_entry_list_t {
rc_client_leaderboard_entry_t* entries;
uint32_t num_entries;
uint32_t total_entries;
int32_t user_index;
} rc_client_leaderboard_entry_list_t;
typedef void (RC_CCONV *rc_client_fetch_leaderboard_entries_callback_t)(int result, const char* error_message,
rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata);
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries(rc_client_t* client, uint32_t leaderboard_id,
uint32_t first_entry, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries_around_user(rc_client_t* client, uint32_t leaderboard_id,
uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
RC_EXPORT int RC_CCONV rc_client_leaderboard_entry_get_user_image_url(const rc_client_leaderboard_entry_t* entry, char buffer[], size_t buffer_size);
RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_entry_list(rc_client_leaderboard_entry_list_t* list);
typedef struct rc_client_leaderboard_scoreboard_entry_t {
const char* username;
uint32_t rank;
char score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
} rc_client_leaderboard_scoreboard_entry_t;
typedef struct rc_client_leaderboard_scoreboard_t {
uint32_t leaderboard_id;
char submitted_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
char best_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
uint32_t new_rank;
uint32_t num_entries;
rc_client_leaderboard_scoreboard_entry_t* top_entries;
uint32_t num_top_entries;
} rc_client_leaderboard_scoreboard_t;
RC_EXPORT int RC_CCONV rc_client_has_rich_presence(rc_client_t* client);
RC_EXPORT size_t RC_CCONV rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size);
RC_EXPORT int RC_CCONV rc_client_get_rich_presence_strings(rc_client_t* client, const char** buffer, size_t buffer_size, size_t* count);
enum {
RC_CLIENT_EVENT_TYPE_NONE = 0,
RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED = 1,
RC_CLIENT_EVENT_LEADERBOARD_STARTED = 2,
RC_CLIENT_EVENT_LEADERBOARD_FAILED = 3,
RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED = 4,
RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW = 5,
RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE = 6,
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW = 7,
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE = 8,
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE = 9,
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW = 10,
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE = 11,
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE = 12,
RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD = 13,
RC_CLIENT_EVENT_RESET = 14,
RC_CLIENT_EVENT_GAME_COMPLETED = 15,
RC_CLIENT_EVENT_SERVER_ERROR = 16,
RC_CLIENT_EVENT_DISCONNECTED = 17,
RC_CLIENT_EVENT_RECONNECTED = 18,
RC_CLIENT_EVENT_SUBSET_COMPLETED = 19
};
typedef struct rc_client_server_error_t {
const char* error_message;
const char* api;
int result;
uint32_t related_id;
} rc_client_server_error_t;
typedef struct rc_client_event_t {
uint32_t type;
rc_client_achievement_t* achievement;
rc_client_leaderboard_t* leaderboard;
rc_client_leaderboard_tracker_t* leaderboard_tracker;
rc_client_leaderboard_scoreboard_t* leaderboard_scoreboard;
rc_client_server_error_t* server_error;
rc_client_subset_t* subset;
} rc_client_event_t;
typedef void (RC_CCONV *rc_client_event_handler_t)(const rc_client_event_t* event, rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler);
RC_EXPORT void RC_CCONV rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler);
RC_EXPORT int RC_CCONV rc_client_is_processing_required(rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_do_frame(rc_client_t* client);
RC_EXPORT void RC_CCONV rc_client_idle(rc_client_t* client);
RC_EXPORT int RC_CCONV rc_client_can_pause(rc_client_t* client, uint32_t* frames_remaining);
RC_EXPORT void RC_CCONV rc_client_reset(rc_client_t* client);
RC_EXPORT size_t RC_CCONV rc_client_progress_size(rc_client_t* client);
RC_EXPORT int RC_CCONV rc_client_serialize_progress(rc_client_t* client, uint8_t* buffer);
RC_EXPORT int RC_CCONV rc_client_serialize_progress_sized(rc_client_t* client, uint8_t* buffer, size_t buffer_size);
RC_EXPORT int RC_CCONV rc_client_deserialize_progress(rc_client_t* client, const uint8_t* serialized);
RC_EXPORT int RC_CCONV rc_client_deserialize_progress_sized(rc_client_t* client, const uint8_t* serialized, size_t serialized_size);
RC_END_C_DECLS
#endif