Path: blob/master/dep/rcheevos/src/rc_client_internal.h
4246 views
#ifndef RC_CLIENT_INTERNAL_H1#define RC_CLIENT_INTERNAL_H23#include "rc_client.h"45#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION6#include "rc_client_raintegration_internal.h"7#endif8#ifdef RC_CLIENT_SUPPORTS_EXTERNAL9#include "rc_client_external.h"10#endif1112#include "rc_compat.h"13#include "rc_runtime.h"14#include "rc_runtime_types.h"1516RC_BEGIN_C_DECLS1718/*****************************************************************************\19| Callbacks |20\*****************************************************************************/2122struct rc_api_fetch_game_data_response_t;23typedef void (RC_CCONV *rc_client_post_process_game_data_response_t)(const rc_api_server_response_t* server_response,24struct rc_api_fetch_game_data_response_t* game_data_response, rc_client_t* client, void* userdata);25typedef int (RC_CCONV *rc_client_can_submit_achievement_unlock_t)(uint32_t achievement_id, rc_client_t* client);26typedef int (RC_CCONV *rc_client_can_submit_leaderboard_entry_t)(uint32_t leaderboard_id, rc_client_t* client);27typedef int (RC_CCONV *rc_client_rich_presence_override_t)(rc_client_t* client, char buffer[], size_t buffersize);28typedef uint32_t (RC_CCONV* rc_client_identify_hash_func_t)(uint32_t console_id, const char* hash,29rc_client_t* client, void* callback_userdata);3031typedef struct rc_client_callbacks_t {32rc_client_read_memory_func_t read_memory;33rc_client_event_handler_t event_handler;34rc_client_server_call_t server_call;35rc_client_message_callback_t log_call;36rc_get_time_millisecs_func_t get_time_millisecs;37rc_client_identify_hash_func_t identify_unknown_hash;38rc_client_post_process_game_data_response_t post_process_game_data_response;39rc_client_can_submit_achievement_unlock_t can_submit_achievement_unlock;40rc_client_can_submit_leaderboard_entry_t can_submit_leaderboard_entry;41rc_client_rich_presence_override_t rich_presence_override;4243void* client_data;44} rc_client_callbacks_t;4546struct rc_client_scheduled_callback_data_t;47typedef void (RC_CCONV *rc_client_scheduled_callback_t)(struct rc_client_scheduled_callback_data_t* callback_data, rc_client_t* client, rc_clock_t now);4849typedef struct rc_client_scheduled_callback_data_t50{51rc_clock_t when;52uint32_t related_id;53rc_client_scheduled_callback_t callback;54void* data;55struct rc_client_scheduled_callback_data_t* next;56} rc_client_scheduled_callback_data_t;5758void rc_client_schedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* scheduled_callback);5960struct rc_client_async_handle_t {61uint8_t aborted;62};6364int rc_client_async_handle_aborted(rc_client_t* client, rc_client_async_handle_t* async_handle);6566/*****************************************************************************\67| Achievements |68\*****************************************************************************/6970enum {71RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE = 0,72RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED = (1 << 1),73RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW = (1 << 2),74RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE = (1 << 3),75RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_UPDATE = (1 << 4) /* not a real event, just triggers update */76};7778typedef struct rc_client_achievement_info_t {79rc_client_achievement_t public_;8081rc_trigger_t* trigger;82uint8_t md5[16];8384time_t unlock_time_hardcore;85time_t unlock_time_softcore;8687uint8_t pending_events;8889const char* author;90time_t created_time;91time_t updated_time;92} rc_client_achievement_info_t;9394struct rc_client_achievement_list_info_t;95typedef void (RC_CCONV *rc_client_destroy_achievement_list_func_t)(struct rc_client_achievement_list_info_t* list);9697typedef struct rc_client_achievement_list_info_t {98rc_client_achievement_list_t public_;99rc_client_destroy_achievement_list_func_t destroy_func;100} rc_client_achievement_list_info_t;101102enum {103RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE,104RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW,105RC_CLIENT_PROGRESS_TRACKER_ACTION_UPDATE,106RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE107};108109typedef struct rc_client_progress_tracker_t {110rc_client_achievement_info_t* achievement;111float progress;112113rc_client_scheduled_callback_data_t* hide_callback;114uint8_t action;115} rc_client_progress_tracker_t;116117/*****************************************************************************\118| Leaderboard Trackers |119\*****************************************************************************/120121enum {122RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE = 0,123RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE = (1 << 1),124RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW = (1 << 2),125RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE = (1 << 3)126};127128typedef struct rc_client_leaderboard_tracker_info_t {129rc_client_leaderboard_tracker_t public_;130struct rc_client_leaderboard_tracker_info_t* next;131int32_t raw_value;132133uint32_t value_djb2;134135uint8_t format;136uint8_t pending_events;137uint8_t reference_count;138uint8_t value_from_hits;139} rc_client_leaderboard_tracker_info_t;140141/*****************************************************************************\142| Leaderboards |143\*****************************************************************************/144145enum {146RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE = 0,147RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED = (1 << 1),148RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED = (1 << 2),149RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED = (1 << 3)150};151152typedef struct rc_client_leaderboard_info_t {153rc_client_leaderboard_t public_;154155rc_lboard_t* lboard;156uint8_t md5[16];157158rc_client_leaderboard_tracker_info_t* tracker;159160uint32_t value_djb2;161int32_t value;162163uint8_t format;164uint8_t pending_events;165uint8_t bucket;166uint8_t hidden;167} rc_client_leaderboard_info_t;168169struct rc_client_leaderboard_list_info_t;170typedef void (RC_CCONV *rc_client_destroy_leaderboard_list_func_t)(struct rc_client_leaderboard_list_info_t* list);171172typedef struct rc_client_leaderboard_list_info_t {173rc_client_leaderboard_list_t public_;174rc_client_destroy_leaderboard_list_func_t destroy_func;175} rc_client_leaderboard_list_info_t;176177struct rc_client_leaderboard_entry_list_info_t;178typedef void (RC_CCONV *rc_client_destroy_leaderboard_entry_list_func_t)(struct rc_client_leaderboard_entry_list_info_t* list);179180typedef struct rc_client_leaderboard_entry_list_info_t {181rc_client_leaderboard_entry_list_t public_;182rc_client_destroy_leaderboard_entry_list_func_t destroy_func;183} rc_client_leaderboard_entry_list_info_t;184185uint8_t rc_client_map_leaderboard_format(int format);186187/*****************************************************************************\188| Subsets |189\*****************************************************************************/190191enum {192RC_CLIENT_SUBSET_PENDING_EVENT_NONE = 0,193RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT = (1 << 1),194RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD = (1 << 2)195};196197typedef struct rc_client_subset_info_t {198rc_client_subset_t public_;199200rc_client_achievement_info_t* achievements;201rc_client_leaderboard_info_t* leaderboards;202203struct rc_client_subset_info_t* next;204205const char* all_label;206const char* inactive_label;207const char* locked_label;208const char* unlocked_label;209const char* unofficial_label;210const char* unsupported_label;211212uint8_t active;213uint8_t mastery;214uint8_t pending_events;215} rc_client_subset_info_t;216217/*****************************************************************************\218| Game |219\*****************************************************************************/220221typedef struct rc_client_game_hash_t {222char hash[33];223uint8_t is_unknown;224uint32_t game_id;225struct rc_client_game_hash_t* next;226} rc_client_game_hash_t;227228rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash);229230typedef struct rc_client_media_hash_t {231rc_client_game_hash_t* game_hash;232struct rc_client_media_hash_t* next;233uint32_t path_djb2;234} rc_client_media_hash_t;235236enum {237RC_CLIENT_GAME_PENDING_EVENT_NONE = 0,238RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER = (1 << 1),239RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS = (1 << 2),240RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER = (1 << 3)241};242243typedef struct rc_client_game_info_t {244rc_client_game_t public_;245rc_client_leaderboard_tracker_info_t* leaderboard_trackers;246rc_client_progress_tracker_t progress_tracker;247248rc_client_subset_info_t* subsets;249250rc_client_media_hash_t* media_hash;251252rc_runtime_t runtime;253254uint32_t max_valid_address;255256uint8_t waiting_for_reset;257uint8_t pending_events;258259rc_buffer_t buffer;260} rc_client_game_info_t;261262void rc_client_update_active_achievements(rc_client_game_info_t* game);263void rc_client_update_active_leaderboards(rc_client_game_info_t* game);264265/*****************************************************************************\266| Client |267\*****************************************************************************/268269enum {270RC_CLIENT_USER_STATE_NONE,271RC_CLIENT_USER_STATE_LOGIN_REQUESTED,272RC_CLIENT_USER_STATE_LOGGED_IN273};274275enum {276RC_CLIENT_MASTERY_STATE_NONE,277RC_CLIENT_MASTERY_STATE_PENDING,278RC_CLIENT_MASTERY_STATE_SHOWN279};280281enum {282RC_CLIENT_SPECTATOR_MODE_OFF,283RC_CLIENT_SPECTATOR_MODE_ON,284RC_CLIENT_SPECTATOR_MODE_LOCKED285};286287enum {288RC_CLIENT_DISCONNECT_HIDDEN = 0,289RC_CLIENT_DISCONNECT_VISIBLE = (1 << 0),290RC_CLIENT_DISCONNECT_SHOW_PENDING = (1 << 1),291RC_CLIENT_DISCONNECT_HIDE_PENDING = (1 << 2)292};293294struct rc_client_load_state_t;295296typedef struct rc_client_state_t {297rc_mutex_t mutex;298rc_buffer_t buffer;299300rc_client_scheduled_callback_data_t* scheduled_callbacks;301rc_api_host_t host;302303#ifdef RC_CLIENT_SUPPORTS_EXTERNAL304rc_client_external_t* external_client;305struct rc_client_external_conversions_t* external_client_conversions;306#endif307#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION308rc_client_raintegration_t* raintegration;309#endif310311uint16_t unpaused_frame_decay;312uint16_t required_unpaused_frames;313314uint8_t hardcore;315uint8_t encore_mode;316uint8_t spectator_mode;317uint8_t unofficial_enabled;318uint8_t log_level;319uint8_t user;320uint8_t disconnect;321uint8_t allow_leaderboards_in_softcore;322323struct rc_client_load_state_t* load;324struct rc_client_async_handle_t* async_handles[4];325rc_memref_t* processing_memref;326327rc_peek_t legacy_peek;328} rc_client_state_t;329330struct rc_client_t {331rc_client_game_info_t* game;332rc_client_game_hash_t* hashes;333334rc_client_user_t user;335336rc_client_callbacks_t callbacks;337338rc_client_state_t state;339};340341/*****************************************************************************\342| Helpers |343\*****************************************************************************/344345#ifdef RC_NO_VARIADIC_MACROS346void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...);347void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...);348void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...);349void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...);350#else351void rc_client_log_message_formatted(const rc_client_t* client, const char* format, ...);352#define RC_CLIENT_LOG_ERR_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message_formatted(client, format, __VA_ARGS__); }353#define RC_CLIENT_LOG_WARN_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message_formatted(client, format, __VA_ARGS__); }354#define RC_CLIENT_LOG_INFO_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message_formatted(client, format, __VA_ARGS__); }355#define RC_CLIENT_LOG_VERBOSE_FORMATTED(client, format, ...) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message_formatted(client, format, __VA_ARGS__); }356#endif357358void rc_client_log_message(const rc_client_t* client, const char* message);359#define RC_CLIENT_LOG_ERR(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message(client, message); }360#define RC_CLIENT_LOG_WARN(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message(client, message); }361#define RC_CLIENT_LOG_INFO(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message(client, message); }362#define RC_CLIENT_LOG_VERBOSE(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message(client, message); }363364/* internals pulled from runtime.c */365void rc_runtime_checksum(const char* memaddr, uint8_t* md5);366int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref);367int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref);368/* end runtime.c internals */369370/* helper functions for unit tests */371#ifdef RC_CLIENT_SUPPORTS_HASH372struct rc_hash_iterator;373struct rc_hash_iterator* rc_client_get_load_state_hash_iterator(rc_client_t* client);374#endif375/* end helper functions for unit tests */376377enum {378RC_CLIENT_LEGACY_PEEK_AUTO,379RC_CLIENT_LEGACY_PEEK_CONSTRUCTED,380RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS381};382383void rc_client_set_legacy_peek(rc_client_t* client, int method);384385void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);386void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);387388RC_END_C_DECLS389390#endif /* RC_CLIENT_INTERNAL_H */391392393