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