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