duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

rc_client_internal.h (14153B)


      1 #ifndef RC_CLIENT_INTERNAL_H
      2 #define RC_CLIENT_INTERNAL_H
      3 
      4 #include "rc_client.h"
      5 
      6 #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
      7  #include "rc_client_raintegration_internal.h"
      8 #endif
      9 #ifdef RC_CLIENT_SUPPORTS_EXTERNAL
     10  #include "rc_client_external.h"
     11 #endif
     12 
     13 #include "rc_compat.h"
     14 #include "rc_runtime.h"
     15 #include "rc_runtime_types.h"
     16 
     17 RC_BEGIN_C_DECLS
     18 
     19 /*****************************************************************************\
     20 | Callbacks                                                                   |
     21 \*****************************************************************************/
     22 
     23 struct rc_api_fetch_game_data_response_t;
     24 typedef void (RC_CCONV *rc_client_post_process_game_data_response_t)(const rc_api_server_response_t* server_response,
     25               struct rc_api_fetch_game_data_response_t* game_data_response, rc_client_t* client, void* userdata);
     26 typedef int (RC_CCONV *rc_client_can_submit_achievement_unlock_t)(uint32_t achievement_id, rc_client_t* client);
     27 typedef int (RC_CCONV *rc_client_can_submit_leaderboard_entry_t)(uint32_t leaderboard_id, rc_client_t* client);
     28 typedef int (RC_CCONV *rc_client_rich_presence_override_t)(rc_client_t* client, char buffer[], size_t buffersize);
     29 typedef uint32_t (RC_CCONV* rc_client_identify_hash_func_t)(uint32_t console_id, const char* hash,
     30                   rc_client_t* client, void* callback_userdata);
     31 
     32 typedef struct rc_client_callbacks_t {
     33   rc_client_read_memory_func_t read_memory;
     34   rc_client_event_handler_t event_handler;
     35   rc_client_server_call_t server_call;
     36   rc_client_message_callback_t log_call;
     37   rc_get_time_millisecs_func_t get_time_millisecs;
     38   rc_client_identify_hash_func_t identify_unknown_hash;
     39   rc_client_post_process_game_data_response_t post_process_game_data_response;
     40   rc_client_can_submit_achievement_unlock_t can_submit_achievement_unlock;
     41   rc_client_can_submit_leaderboard_entry_t can_submit_leaderboard_entry;
     42   rc_client_rich_presence_override_t rich_presence_override;
     43 
     44   void* client_data;
     45 } rc_client_callbacks_t;
     46 
     47 struct rc_client_scheduled_callback_data_t;
     48 typedef 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);
     49 
     50 typedef struct rc_client_scheduled_callback_data_t
     51 {
     52   rc_clock_t when;
     53   uint32_t related_id;
     54   rc_client_scheduled_callback_t callback;
     55   void* data;
     56   struct rc_client_scheduled_callback_data_t* next;
     57 } rc_client_scheduled_callback_data_t;
     58 
     59 void rc_client_schedule_callback(rc_client_t* client, rc_client_scheduled_callback_data_t* scheduled_callback);
     60 
     61 struct rc_client_async_handle_t {
     62   uint8_t aborted;
     63 };
     64 
     65 int rc_client_async_handle_aborted(rc_client_t* client, rc_client_async_handle_t* async_handle);
     66 
     67 /*****************************************************************************\
     68 | Achievements                                                                |
     69 \*****************************************************************************/
     70 
     71 enum {
     72   RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_NONE = 0,
     73   RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_TRIGGERED = (1 << 1),
     74   RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_SHOW = (1 << 2),
     75   RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_CHALLENGE_INDICATOR_HIDE = (1 << 3),
     76   RC_CLIENT_ACHIEVEMENT_PENDING_EVENT_UPDATE = (1 << 4) /* not a real event, just triggers update */
     77 };
     78 
     79 typedef struct rc_client_achievement_info_t {
     80   rc_client_achievement_t public_;
     81 
     82   rc_trigger_t* trigger;
     83   uint8_t md5[16];
     84 
     85   time_t unlock_time_hardcore;
     86   time_t unlock_time_softcore;
     87 
     88   uint8_t pending_events;
     89 
     90   const char* author;
     91   time_t created_time;
     92   time_t updated_time;
     93 } rc_client_achievement_info_t;
     94 
     95 struct rc_client_achievement_list_info_t;
     96 typedef void (RC_CCONV *rc_client_destroy_achievement_list_func_t)(struct rc_client_achievement_list_info_t* list);
     97 
     98 typedef struct rc_client_achievement_list_info_t {
     99   rc_client_achievement_list_t public_;
    100   rc_client_destroy_achievement_list_func_t destroy_func;
    101 } rc_client_achievement_list_info_t;
    102 
    103 enum {
    104   RC_CLIENT_PROGRESS_TRACKER_ACTION_NONE,
    105   RC_CLIENT_PROGRESS_TRACKER_ACTION_SHOW,
    106   RC_CLIENT_PROGRESS_TRACKER_ACTION_UPDATE,
    107   RC_CLIENT_PROGRESS_TRACKER_ACTION_HIDE
    108 };
    109 
    110 typedef struct rc_client_progress_tracker_t {
    111   rc_client_achievement_info_t* achievement;
    112   float progress;
    113 
    114   rc_client_scheduled_callback_data_t* hide_callback;
    115   uint8_t action;
    116 } rc_client_progress_tracker_t;
    117 
    118 /*****************************************************************************\
    119 | Leaderboard Trackers                                                        |
    120 \*****************************************************************************/
    121 
    122 enum {
    123   RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_NONE = 0,
    124   RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_UPDATE = (1 << 1),
    125   RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_SHOW = (1 << 2),
    126   RC_CLIENT_LEADERBOARD_TRACKER_PENDING_EVENT_HIDE = (1 << 3)
    127 };
    128 
    129 typedef struct rc_client_leaderboard_tracker_info_t {
    130   rc_client_leaderboard_tracker_t public_;
    131   struct rc_client_leaderboard_tracker_info_t* next;
    132   int32_t raw_value;
    133 
    134   uint32_t value_djb2;
    135 
    136   uint8_t format;
    137   uint8_t pending_events;
    138   uint8_t reference_count;
    139   uint8_t value_from_hits;
    140 } rc_client_leaderboard_tracker_info_t;
    141 
    142 /*****************************************************************************\
    143 | Leaderboards                                                                |
    144 \*****************************************************************************/
    145 
    146 enum {
    147   RC_CLIENT_LEADERBOARD_PENDING_EVENT_NONE = 0,
    148   RC_CLIENT_LEADERBOARD_PENDING_EVENT_STARTED = (1 << 1),
    149   RC_CLIENT_LEADERBOARD_PENDING_EVENT_FAILED = (1 << 2),
    150   RC_CLIENT_LEADERBOARD_PENDING_EVENT_SUBMITTED = (1 << 3)
    151 };
    152 
    153 typedef struct rc_client_leaderboard_info_t {
    154   rc_client_leaderboard_t public_;
    155 
    156   rc_lboard_t* lboard;
    157   uint8_t md5[16];
    158 
    159   rc_client_leaderboard_tracker_info_t* tracker;
    160 
    161   uint32_t value_djb2;
    162   int32_t value;
    163 
    164   uint8_t format;
    165   uint8_t pending_events;
    166   uint8_t bucket;
    167   uint8_t hidden;
    168 } rc_client_leaderboard_info_t;
    169 
    170 struct rc_client_leaderboard_list_info_t;
    171 typedef void (RC_CCONV *rc_client_destroy_leaderboard_list_func_t)(struct rc_client_leaderboard_list_info_t* list);
    172 
    173 typedef struct rc_client_leaderboard_list_info_t {
    174   rc_client_leaderboard_list_t public_;
    175   rc_client_destroy_leaderboard_list_func_t destroy_func;
    176 } rc_client_leaderboard_list_info_t;
    177 
    178 struct rc_client_leaderboard_entry_list_info_t;
    179 typedef void (RC_CCONV *rc_client_destroy_leaderboard_entry_list_func_t)(struct rc_client_leaderboard_entry_list_info_t* list);
    180 
    181 typedef struct rc_client_leaderboard_entry_list_info_t {
    182   rc_client_leaderboard_entry_list_t public_;
    183   rc_client_destroy_leaderboard_entry_list_func_t destroy_func;
    184 } rc_client_leaderboard_entry_list_info_t;
    185 
    186 uint8_t rc_client_map_leaderboard_format(int format);
    187 
    188 /*****************************************************************************\
    189 | Subsets                                                                     |
    190 \*****************************************************************************/
    191 
    192 enum {
    193   RC_CLIENT_SUBSET_PENDING_EVENT_NONE = 0,
    194   RC_CLIENT_SUBSET_PENDING_EVENT_ACHIEVEMENT = (1 << 1),
    195   RC_CLIENT_SUBSET_PENDING_EVENT_LEADERBOARD = (1 << 2)
    196 };
    197 
    198 typedef struct rc_client_subset_info_t {
    199   rc_client_subset_t public_;
    200 
    201   rc_client_achievement_info_t* achievements;
    202   rc_client_leaderboard_info_t* leaderboards;
    203 
    204   struct rc_client_subset_info_t* next;
    205 
    206   const char* all_label;
    207   const char* inactive_label;
    208   const char* locked_label;
    209   const char* unlocked_label;
    210   const char* unofficial_label;
    211   const char* unsupported_label;
    212 
    213   uint8_t active;
    214   uint8_t mastery;
    215   uint8_t pending_events;
    216 } rc_client_subset_info_t;
    217 
    218 rc_client_async_handle_t* rc_client_begin_load_subset(rc_client_t* client, uint32_t subset_id, rc_client_callback_t callback, void* callback_userdata);
    219 
    220 /*****************************************************************************\
    221 | Game                                                                        |
    222 \*****************************************************************************/
    223 
    224 typedef struct rc_client_game_hash_t {
    225   char hash[33];
    226   uint32_t game_id;
    227   struct rc_client_game_hash_t* next;
    228 } rc_client_game_hash_t;
    229 
    230 rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash);
    231 
    232 typedef struct rc_client_media_hash_t {
    233   rc_client_game_hash_t* game_hash;
    234   struct rc_client_media_hash_t* next;
    235   uint32_t path_djb2;
    236 } rc_client_media_hash_t;
    237 
    238 enum {
    239   RC_CLIENT_GAME_PENDING_EVENT_NONE = 0,
    240   RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER = (1 << 1),
    241   RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS = (1 << 2),
    242   RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER = (1 << 3)
    243 };
    244 
    245 typedef struct rc_client_game_info_t {
    246   rc_client_game_t public_;
    247   rc_client_leaderboard_tracker_info_t* leaderboard_trackers;
    248   rc_client_progress_tracker_t progress_tracker;
    249 
    250   rc_client_subset_info_t* subsets;
    251 
    252   rc_client_media_hash_t* media_hash;
    253 
    254   rc_runtime_t runtime;
    255 
    256   uint32_t max_valid_address;
    257 
    258   uint8_t waiting_for_reset;
    259   uint8_t pending_events;
    260 
    261   rc_buffer_t buffer;
    262 } rc_client_game_info_t;
    263 
    264 void rc_client_update_active_achievements(rc_client_game_info_t* game);
    265 void rc_client_update_active_leaderboards(rc_client_game_info_t* game);
    266 
    267 /*****************************************************************************\
    268 | Client                                                                      |
    269 \*****************************************************************************/
    270 
    271 enum {
    272   RC_CLIENT_USER_STATE_NONE,
    273   RC_CLIENT_USER_STATE_LOGIN_REQUESTED,
    274   RC_CLIENT_USER_STATE_LOGGED_IN
    275 };
    276 
    277 enum {
    278   RC_CLIENT_MASTERY_STATE_NONE,
    279   RC_CLIENT_MASTERY_STATE_PENDING,
    280   RC_CLIENT_MASTERY_STATE_SHOWN
    281 };
    282 
    283 enum {
    284   RC_CLIENT_SPECTATOR_MODE_OFF,
    285   RC_CLIENT_SPECTATOR_MODE_ON,
    286   RC_CLIENT_SPECTATOR_MODE_LOCKED
    287 };
    288 
    289 enum {
    290   RC_CLIENT_DISCONNECT_HIDDEN = 0,
    291   RC_CLIENT_DISCONNECT_VISIBLE = (1 << 0),
    292   RC_CLIENT_DISCONNECT_SHOW_PENDING = (1 << 1),
    293   RC_CLIENT_DISCONNECT_HIDE_PENDING = (1 << 2)
    294 };
    295 
    296 struct rc_client_load_state_t;
    297 
    298 typedef struct rc_client_state_t {
    299   rc_mutex_t mutex;
    300   rc_buffer_t buffer;
    301 
    302   rc_client_scheduled_callback_data_t* scheduled_callbacks;
    303 
    304 #ifdef RC_CLIENT_SUPPORTS_EXTERNAL
    305   rc_client_external_t* external_client;
    306 #endif
    307 #ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
    308   rc_client_raintegration_t* raintegration;
    309 #endif
    310 
    311   uint16_t unpaused_frame_decay;
    312   uint16_t required_unpaused_frames;
    313 
    314   uint8_t hardcore;
    315   uint8_t encore_mode;
    316   uint8_t spectator_mode;
    317   uint8_t unofficial_enabled;
    318   uint8_t log_level;
    319   uint8_t user;
    320   uint8_t disconnect;
    321   uint8_t allow_leaderboards_in_softcore;
    322 
    323   struct rc_client_load_state_t* load;
    324   struct rc_client_async_handle_t* async_handles[4];
    325   rc_memref_t* processing_memref;
    326 
    327   rc_peek_t legacy_peek;
    328 } rc_client_state_t;
    329 
    330 struct rc_client_t {
    331   rc_client_game_info_t* game;
    332   rc_client_game_hash_t* hashes;
    333 
    334   rc_client_user_t user;
    335 
    336   rc_client_callbacks_t callbacks;
    337 
    338   rc_client_state_t state;
    339 };
    340 
    341 /*****************************************************************************\
    342 | Helpers                                                                     |
    343 \*****************************************************************************/
    344 
    345 #ifdef RC_NO_VARIADIC_MACROS
    346  void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...);
    347  void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...);
    348  void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...);
    349  void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...);
    350 #else
    351  void 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 #endif
    357 
    358 void 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); }
    363 
    364 /* internals pulled from runtime.c */
    365 void rc_runtime_checksum(const char* memaddr, uint8_t* md5);
    366 int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref);
    367 int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref);
    368 /* end runtime.c internals */
    369 
    370 /* helper functions for unit tests */
    371 #ifdef RC_CLIENT_SUPPORTS_HASH
    372 struct rc_hash_iterator;
    373 struct rc_hash_iterator* rc_client_get_load_state_hash_iterator(rc_client_t* client);
    374 #endif
    375 /* end helper functions for unit tests */
    376 
    377 enum {
    378   RC_CLIENT_LEGACY_PEEK_AUTO,
    379   RC_CLIENT_LEGACY_PEEK_CONSTRUCTED,
    380   RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS
    381 };
    382 
    383 void rc_client_set_legacy_peek(rc_client_t* client, int method);
    384 
    385 void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);
    386 void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);
    387 
    388 RC_END_C_DECLS
    389 
    390 #endif /* RC_CLIENT_INTERNAL_H */