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 */