Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rcheevos/src/rc_client_internal.h
7545 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* unlocked_softcore_label;
218
const char* unofficial_label;
219
const char* unsupported_label;
220
221
uint8_t active;
222
uint8_t mastery;
223
uint8_t pending_events;
224
} rc_client_subset_info_t;
225
226
struct rc_client_subset_list_info_t;
227
typedef void (RC_CCONV* rc_client_destroy_subset_list_func_t)(struct rc_client_subset_list_info_t* list);
228
229
typedef struct rc_client_subset_list_info_t {
230
rc_client_subset_list_t public_;
231
rc_client_destroy_subset_list_func_t destroy_func;
232
} rc_client_subset_list_info_t;
233
234
/*****************************************************************************\
235
| Game |
236
\*****************************************************************************/
237
238
typedef struct rc_client_game_hash_t {
239
char hash[33];
240
uint8_t is_unknown;
241
uint32_t game_id;
242
struct rc_client_game_hash_t* next;
243
} rc_client_game_hash_t;
244
245
rc_client_game_hash_t* rc_client_find_game_hash(rc_client_t* client, const char* hash);
246
247
typedef struct rc_client_media_hash_t {
248
rc_client_game_hash_t* game_hash;
249
struct rc_client_media_hash_t* next;
250
uint32_t path_djb2;
251
} rc_client_media_hash_t;
252
253
enum {
254
RC_CLIENT_GAME_PENDING_EVENT_NONE = 0,
255
RC_CLIENT_GAME_PENDING_EVENT_LEADERBOARD_TRACKER = (1 << 1),
256
RC_CLIENT_GAME_PENDING_EVENT_UPDATE_ACTIVE_ACHIEVEMENTS = (1 << 2),
257
RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER = (1 << 3)
258
};
259
260
typedef struct rc_client_game_info_t {
261
rc_client_game_t public_;
262
rc_client_leaderboard_tracker_info_t* leaderboard_trackers;
263
rc_client_progress_tracker_t progress_tracker;
264
265
rc_client_subset_info_t* subsets;
266
267
rc_client_media_hash_t* media_hash;
268
269
rc_runtime_t runtime;
270
271
uint32_t max_valid_address;
272
273
uint8_t waiting_for_reset;
274
uint8_t pending_events;
275
276
rc_buffer_t buffer;
277
} rc_client_game_info_t;
278
279
void rc_client_update_active_achievements(rc_client_game_info_t* game);
280
void rc_client_update_active_leaderboards(rc_client_game_info_t* game);
281
282
/*****************************************************************************\
283
| Client |
284
\*****************************************************************************/
285
286
enum {
287
RC_CLIENT_USER_STATE_NONE,
288
RC_CLIENT_USER_STATE_LOGIN_REQUESTED,
289
RC_CLIENT_USER_STATE_LOGGED_IN
290
};
291
292
enum {
293
RC_CLIENT_MASTERY_STATE_NONE,
294
RC_CLIENT_MASTERY_STATE_PENDING,
295
RC_CLIENT_MASTERY_STATE_SHOWN
296
};
297
298
enum {
299
RC_CLIENT_SPECTATOR_MODE_OFF,
300
RC_CLIENT_SPECTATOR_MODE_ON,
301
RC_CLIENT_SPECTATOR_MODE_LOCKED
302
};
303
304
enum {
305
RC_CLIENT_DISCONNECT_HIDDEN = 0,
306
RC_CLIENT_DISCONNECT_VISIBLE = (1 << 0),
307
RC_CLIENT_DISCONNECT_SHOW_PENDING = (1 << 1),
308
RC_CLIENT_DISCONNECT_HIDE_PENDING = (1 << 2)
309
};
310
311
struct rc_client_load_state_t;
312
313
typedef struct rc_client_state_t {
314
rc_mutex_t mutex;
315
rc_buffer_t buffer;
316
317
rc_client_scheduled_callback_data_t* scheduled_callbacks;
318
rc_api_host_t host;
319
320
#ifdef RC_CLIENT_SUPPORTS_EXTERNAL
321
rc_client_external_t* external_client;
322
struct rc_client_external_conversions_t* external_client_conversions;
323
#endif
324
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
325
rc_client_raintegration_t* raintegration;
326
#endif
327
328
uint32_t frames_processed;
329
uint32_t frames_at_last_ping;
330
uint16_t unpaused_frame_decay;
331
uint16_t required_unpaused_frames;
332
333
uint8_t hardcore;
334
uint8_t encore_mode;
335
uint8_t spectator_mode;
336
uint8_t unofficial_enabled;
337
uint8_t log_level;
338
uint8_t user;
339
uint8_t disconnect;
340
uint8_t allow_leaderboards_in_softcore;
341
uint8_t allow_background_memory_reads;
342
343
struct rc_client_load_state_t* load;
344
struct rc_client_async_handle_t* async_handles[4];
345
rc_memref_t* processing_memref;
346
347
rc_peek_t legacy_peek;
348
} rc_client_state_t;
349
350
struct rc_client_t {
351
rc_client_game_info_t* game;
352
rc_client_game_hash_t* hashes;
353
354
rc_client_user_t user;
355
356
rc_client_callbacks_t callbacks;
357
358
rc_client_state_t state;
359
};
360
361
/*****************************************************************************\
362
| Helpers |
363
\*****************************************************************************/
364
365
#ifdef RC_NO_VARIADIC_MACROS
366
void RC_CLIENT_LOG_ERR_FORMATTED(const rc_client_t* client, const char* format, ...);
367
void RC_CLIENT_LOG_WARN_FORMATTED(const rc_client_t* client, const char* format, ...);
368
void RC_CLIENT_LOG_INFO_FORMATTED(const rc_client_t* client, const char* format, ...);
369
void RC_CLIENT_LOG_VERBOSE_FORMATTED(const rc_client_t* client, const char* format, ...);
370
#else
371
void rc_client_log_message_formatted(const rc_client_t* client, const char* format, ...);
372
#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__); }
373
#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__); }
374
#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__); }
375
#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__); }
376
#endif
377
378
void rc_client_log_message(const rc_client_t* client, const char* message);
379
#define RC_CLIENT_LOG_ERR(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_ERROR) rc_client_log_message(client, message); }
380
#define RC_CLIENT_LOG_WARN(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_WARN) rc_client_log_message(client, message); }
381
#define RC_CLIENT_LOG_INFO(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_INFO) rc_client_log_message(client, message); }
382
#define RC_CLIENT_LOG_VERBOSE(client, message) { if (client->state.log_level >= RC_CLIENT_LOG_LEVEL_VERBOSE) rc_client_log_message(client, message); }
383
384
/* internals pulled from runtime.c */
385
void rc_runtime_checksum(const char* memaddr, uint8_t* md5);
386
int rc_trigger_contains_memref(const rc_trigger_t* trigger, const rc_memref_t* memref);
387
int rc_value_contains_memref(const rc_value_t* value, const rc_memref_t* memref);
388
/* end runtime.c internals */
389
390
/* helper functions for unit tests */
391
#ifdef RC_CLIENT_SUPPORTS_HASH
392
struct rc_hash_iterator;
393
struct rc_hash_iterator* rc_client_get_load_state_hash_iterator(rc_client_t* client);
394
#endif
395
/* end helper functions for unit tests */
396
397
enum {
398
RC_CLIENT_LEGACY_PEEK_AUTO,
399
RC_CLIENT_LEGACY_PEEK_CONSTRUCTED,
400
RC_CLIENT_LEGACY_PEEK_LITTLE_ENDIAN_READS
401
};
402
403
void rc_client_set_legacy_peek(rc_client_t* client, int method);
404
405
void rc_client_allocate_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);
406
void rc_client_release_leaderboard_tracker(rc_client_game_info_t* game, rc_client_leaderboard_info_t* leaderboard);
407
408
RC_END_C_DECLS
409
410
#endif /* RC_CLIENT_INTERNAL_H */
411
412