Path: blob/master/dep/rcheevos/src/rc_client_internal.h
7545 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#endif11#ifdef RC_CLIENT_SUPPORTS_HASH12#include "rhash/rc_hash_internal.h"13#endif1415#include "rc_compat.h"16#include "rc_runtime.h"17#include "rc_runtime_types.h"1819RC_BEGIN_C_DECLS2021/*****************************************************************************\22| Callbacks |23\*****************************************************************************/2425struct rc_api_fetch_game_sets_response_t;26typedef void (RC_CCONV *rc_client_post_process_game_sets_response_t)(const rc_api_server_response_t* server_response,27struct rc_api_fetch_game_sets_response_t* game_sets_response, rc_client_t* client, void* userdata);28typedef int (RC_CCONV *rc_client_can_submit_achievement_unlock_t)(uint32_t achievement_id, rc_client_t* client);29typedef int (RC_CCONV *rc_client_can_submit_leaderboard_entry_t)(uint32_t leaderboard_id, rc_client_t* client);30typedef int (RC_CCONV *rc_client_rich_presence_override_t)(rc_client_t* client, char buffer[], size_t buffersize);31typedef uint32_t (RC_CCONV* rc_client_identify_hash_func_t)(uint32_t console_id, const char* hash,32rc_client_t* client, void* callback_userdata);3334typedef struct rc_client_callbacks_t {35rc_client_read_memory_func_t read_memory;36rc_client_event_handler_t event_handler;37rc_client_server_call_t server_call;38rc_client_message_callback_t log_call;39rc_get_time_millisecs_func_t get_time_millisecs;40rc_client_identify_hash_func_t identify_unknown_hash;41rc_client_post_process_game_sets_response_t post_process_game_sets_response;42rc_client_can_submit_achievement_unlock_t can_submit_achievement_unlock;43rc_client_can_submit_leaderboard_entry_t can_submit_leaderboard_entry;44rc_client_rich_presence_override_t rich_presence_override;4546#ifdef RC_CLIENT_SUPPORTS_HASH47rc_hash_callbacks_t hash;48#endif4950void* client_data;51} rc_client_callbacks_t;5253struct rc_client_scheduled_callback_data_t;54typedef 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);5556typedef struct rc_client_scheduled_callback_data_t57{58rc_clock_t when;59uint32_t related_id;60rc_client_scheduled_callback_t callback;61void* data;62struct rc_client_scheduled_callback_data_t* next;63} rc_client_scheduled_callback_data_t;6465void rc_client_schedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* scheduled_callback);6667struct rc_client_async_handle_t {68uint8_t aborted;69};7071int rc_client_async_handle_aborted(rc_client_t* client, rc_client_async_handle_t* async_handle);7273/*****************************************************************************\74| Achievements |75\*****************************************************************************/7677enum {78RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE = 0,79RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED = (1 << 1),80RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW = (1 << 2),81RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE = (1 << 3),82RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_UPDATE = (1 << 4) /* not a real event, just triggers update */83};8485typedef struct rc_client_achievement_info_t {86rc_client_achievement_t public_;8788rc_trigger_t* trigger;89uint8_t md5[16];9091time_t unlock_time_hardcore;92time_t unlock_time_softcore;9394uint8_t pending_events;9596const char* author;97time_t created_time;98time_t updated_time;99} rc_client_achievement_info_t;100101struct rc_client_achievement_list_info_t;102typedef void (RC_CCONV *rc_client_destroy_achievement_list_func_t)(struct rc_client_achievement_list_info_t* list);103104typedef struct rc_client_achievement_list_info_t {105rc_client_achievement_list_t public_;106rc_client_destroy_achievement_list_func_t destroy_func;107} rc_client_achievement_list_info_t;108109enum {110RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE,111RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW,112RC_CLIENT_PROGRESS_TRACKER_ACTION_UPDATE,113RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE114};115116typedef struct rc_client_progress_tracker_t {117rc_client_achievement_info_t* achievement;118float progress;119120rc_client_scheduled_callback_data_t* hide_callback;121uint8_t action;122} rc_client_progress_tracker_t;123124/*****************************************************************************\125| Leaderboard Trackers |126\*****************************************************************************/127128enum {129RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE = 0,130RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE = (1 << 1),131RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW = (1 << 2),132RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE = (1 << 3)133};134135typedef struct rc_client_leaderboard_tracker_info_t {136rc_client_leaderboard_tracker_t public_;137struct rc_client_leaderboard_tracker_info_t* next;138int32_t raw_value;139140uint32_t value_djb2;141142uint8_t format;143uint8_t pending_events;144uint8_t reference_count;145uint8_t value_from_hits;146} rc_client_leaderboard_tracker_info_t;147148/*****************************************************************************\149| Leaderboards |150\*****************************************************************************/151152enum {153RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE = 0,154RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED = (1 << 1),155RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED = (1 << 2),156RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED = (1 << 3)157};158159typedef struct rc_client_leaderboard_info_t {160rc_client_leaderboard_t public_;161162rc_lboard_t* lboard;163uint8_t md5[16];164165rc_client_leaderboard_tracker_info_t* tracker;166167uint32_t value_djb2;168int32_t value;169170uint8_t format;171uint8_t pending_events;172uint8_t bucket;173uint8_t hidden;174} rc_client_leaderboard_info_t;175176struct rc_client_leaderboard_list_info_t;177typedef void (RC_CCONV *rc_client_destroy_leaderboard_list_func_t)(struct rc_client_leaderboard_list_info_t* list);178179typedef struct rc_client_leaderboard_list_info_t {180rc_client_leaderboard_list_t public_;181rc_client_destroy_leaderboard_list_func_t destroy_func;182} rc_client_leaderboard_list_info_t;183184struct rc_client_leaderboard_entry_list_info_t;185typedef void (RC_CCONV *rc_client_destroy_leaderboard_entry_list_func_t)(struct rc_client_leaderboard_entry_list_info_t* list);186187typedef struct rc_client_leaderboard_entry_list_info_t {188rc_client_leaderboard_entry_list_t public_;189rc_client_destroy_leaderboard_entry_list_func_t destroy_func;190} rc_client_leaderboard_entry_list_info_t;191192uint8_t rc_client_map_leaderboard_format(int format);193194/*****************************************************************************\195| Subsets |196\*****************************************************************************/197198enum {199RC_CLIENT_SUBSET_PENDING_EVENT_NONE = 0,200RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT = (1 << 1),201RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD = (1 << 2)202};203204typedef struct rc_client_subset_info_t {205rc_client_subset_t public_;206207rc_client_achievement_info_t* achievements;208rc_client_leaderboard_info_t* leaderboards;209210struct rc_client_subset_info_t* next;211212const char* all_label;213const char* inactive_label;214const char* locked_label;215const char* unlocked_label;216const char* unlocked_softcore_label;217const char* unofficial_label;218const char* unsupported_label;219220uint8_t active;221uint8_t mastery;222uint8_t pending_events;223} rc_client_subset_info_t;224225struct rc_client_subset_list_info_t;226typedef void (RC_CCONV* rc_client_destroy_subset_list_func_t)(struct rc_client_subset_list_info_t* list);227228typedef struct rc_client_subset_list_info_t {229rc_client_subset_list_t public_;230rc_client_destroy_subset_list_func_t destroy_func;231} rc_client_subset_list_info_t;232233/*****************************************************************************\234| Game |235\*****************************************************************************/236237typedef struct rc_client_game_hash_t {238char hash[33];239uint8_t is_unknown;240uint32_t game_id;241struct rc_client_game_hash_t* next;242} rc_client_game_hash_t;243244rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash);245246typedef struct rc_client_media_hash_t {247rc_client_game_hash_t* game_hash;248struct rc_client_media_hash_t* next;249uint32_t path_djb2;250} rc_client_media_hash_t;251252enum {253RC_CLIENT_GAME_PENDING_EVENT_NONE = 0,254RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER = (1 << 1),255RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS = (1 << 2),256RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER = (1 << 3)257};258259typedef struct rc_client_game_info_t {260rc_client_game_t public_;261rc_client_leaderboard_tracker_info_t* leaderboard_trackers;262rc_client_progress_tracker_t progress_tracker;263264rc_client_subset_info_t* subsets;265266rc_client_media_hash_t* media_hash;267268rc_runtime_t runtime;269270uint32_t max_valid_address;271272uint8_t waiting_for_reset;273uint8_t pending_events;274275rc_buffer_t buffer;276} rc_client_game_info_t;277278void rc_client_update_active_achievements(rc_client_game_info_t* game);279void rc_client_update_active_leaderboards(rc_client_game_info_t* game);280281/*****************************************************************************\282| Client |283\*****************************************************************************/284285enum {286RC_CLIENT_USER_STATE_NONE,287RC_CLIENT_USER_STATE_LOGIN_REQUESTED,288RC_CLIENT_USER_STATE_LOGGED_IN289};290291enum {292RC_CLIENT_MASTERY_STATE_NONE,293RC_CLIENT_MASTERY_STATE_PENDING,294RC_CLIENT_MASTERY_STATE_SHOWN295};296297enum {298RC_CLIENT_SPECTATOR_MODE_OFF,299RC_CLIENT_SPECTATOR_MODE_ON,300RC_CLIENT_SPECTATOR_MODE_LOCKED301};302303enum {304RC_CLIENT_DISCONNECT_HIDDEN = 0,305RC_CLIENT_DISCONNECT_VISIBLE = (1 << 0),306RC_CLIENT_DISCONNECT_SHOW_PENDING = (1 << 1),307RC_CLIENT_DISCONNECT_HIDE_PENDING = (1 << 2)308};309310struct rc_client_load_state_t;311312typedef struct rc_client_state_t {313rc_mutex_t mutex;314rc_buffer_t buffer;315316rc_client_scheduled_callback_data_t* scheduled_callbacks;317rc_api_host_t host;318319#ifdef RC_CLIENT_SUPPORTS_EXTERNAL320rc_client_external_t* external_client;321struct rc_client_external_conversions_t* external_client_conversions;322#endif323#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION324rc_client_raintegration_t* raintegration;325#endif326327uint32_t frames_processed;328uint32_t frames_at_last_ping;329uint16_t unpaused_frame_decay;330uint16_t required_unpaused_frames;331332uint8_t hardcore;333uint8_t encore_mode;334uint8_t spectator_mode;335uint8_t unofficial_enabled;336uint8_t log_level;337uint8_t user;338uint8_t disconnect;339uint8_t allow_leaderboards_in_softcore;340uint8_t allow_background_memory_reads;341342struct rc_client_load_state_t* load;343struct rc_client_async_handle_t* async_handles[4];344rc_memref_t* processing_memref;345346rc_peek_t legacy_peek;347} rc_client_state_t;348349struct rc_client_t {350rc_client_game_info_t* game;351rc_client_game_hash_t* hashes;352353rc_client_user_t user;354355rc_client_callbacks_t callbacks;356357rc_client_state_t state;358};359360/*****************************************************************************\361| Helpers |362\*****************************************************************************/363364#ifdef RC_NO_VARIADIC_MACROS365void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...);366void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...);367void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...);368void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...);369#else370void rc_client_log_message_formatted(const rc_client_t* client, const char* format, ...);371#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__); }372#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__); }373#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__); }374#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__); }375#endif376377void rc_client_log_message(const rc_client_t* client, const char* message);378#define RC_CLIENT_LOG_ERR(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message(client, message); }379#define RC_CLIENT_LOG_WARN(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message(client, message); }380#define RC_CLIENT_LOG_INFO(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message(client, message); }381#define RC_CLIENT_LOG_VERBOSE(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message(client, message); }382383/* internals pulled from runtime.c */384void rc_runtime_checksum(const char* memaddr, uint8_t* md5);385int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref);386int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref);387/* end runtime.c internals */388389/* helper functions for unit tests */390#ifdef RC_CLIENT_SUPPORTS_HASH391struct rc_hash_iterator;392struct rc_hash_iterator* rc_client_get_load_state_hash_iterator(rc_client_t* client);393#endif394/* end helper functions for unit tests */395396enum {397RC_CLIENT_LEGACY_PEEK_AUTO,398RC_CLIENT_LEGACY_PEEK_CONSTRUCTED,399RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS400};401402void rc_client_set_legacy_peek(rc_client_t* client, int method);403404void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);405void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);406407RC_END_C_DECLS408409#endif /* RC_CLIENT_INTERNAL_H */410411412