mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
3rdparty: Update rcheevos to v12.0.0
This commit is contained in:
Vendored
+69
@@ -1,3 +1,72 @@
|
||||
# v12.0.0
|
||||
* rc_client changes
|
||||
* add RC_CLIENT_EVENT_SUBSET_COMPLETED event
|
||||
* add 'avatar_url' to rc_client_user_t
|
||||
* add 'badge_url' to rc_client_game_t
|
||||
* add 'badge_url' and 'badge_locked_url' to rc_client_achievement_t
|
||||
* add rc_client_set_hash_callbacks
|
||||
* add rc_client_set_allow_background_memory_reads
|
||||
* renamed rc_client_begin_change_media to rc_client_begin_identify_and_change_media
|
||||
* renamed rc_client_begin_change_media_from_hash to rc_client_begin_change_media
|
||||
* use slim read/write locks for rc_mutex on Windows Vista+
|
||||
* use critical sections for rc_mutex on older versions of Windows
|
||||
* add translation layer in rc_client_external for cross-version support
|
||||
* rhash changes
|
||||
* rc_hash_init_verbose_message_callback and rc_hash_init_error_message_callback have been deprecated.
|
||||
- set values in iterator.callbacks instead.
|
||||
* rc_hash_init_custom_filereader and rc_hash_init_custom_cdreader have been deprecated.
|
||||
- set values in iterator.callbacks instead.
|
||||
* rc_hash_generate_from_file and rc_hash_generate_from_buffer have been deprecated.
|
||||
- use rc_hash_initialize_iterator and rc_hash_generate instead.
|
||||
* hash.c has been split into several smaller files which can be conditionally excluded from the build.
|
||||
- hash_disc.c can be excluded by defining RC_HASH_NO_DISC
|
||||
- hash_encrypted.c can be excluded by defining RC_HASH_NO_ENCRYPTED
|
||||
- hash_rom.c can be excluded by defining RC_HASH_NO_ROM
|
||||
- hash_zip.c can be excluded by defining RC_HASH_NO_ZIP
|
||||
* add hash method for RC_CONSOLE_WII
|
||||
* add hash method for Arduboy FX games (RC_CONSOLE_ARDUBOY)
|
||||
* fix hash for PCE homebrew games that aren't multiples of 128KB
|
||||
* rapi changes
|
||||
* add _hosted variations of rc_api_init functions for interacting with custom hosts
|
||||
- rc_api_set_host and rc_api_set_image_host have been deprecated
|
||||
* add rc_api_fetch_game_sets
|
||||
* add rc_api_fetch_followed_users
|
||||
* add rc_api_fetch_hash_library
|
||||
* add rc_api_fetch_all_user_progress
|
||||
* add 'avatar_url' to login response, achievement_info response, and leaderboard_info responses
|
||||
* add 'badge_url' to game_data response
|
||||
* rurl has been removed (deprecated in v10.0.0)
|
||||
* trigger parsing/processing code has been largely modified to improve processing performance
|
||||
* AddAddress/AddSource chains can now be shared across triggers to avoid recalculating them multiple times
|
||||
* triggers are preprocessed to allocate conditions as array instead of linked list.
|
||||
- array is sorted such that similar conditions (pause/reset/hittarget/etc) can be processed together
|
||||
without having to scan the linked list multiple times
|
||||
- the linked list still exists for backwards compatibility and to maintain the original ordering
|
||||
* each condition type has its own handler, eliminating many switches and branches when processing triggers
|
||||
* memrefs are now allocated in arrays (eliminating the linked list pointer from each to reduce memory footprint)
|
||||
* commas are now inserted into all numeric formats except SCORE. a new format type UNFORMATTED (@Unformatted) has
|
||||
been added to display a number without commas.
|
||||
- To forcibly exclude commas in a backwards-compatible way, use the @Unformatted macro and define Unformatted as
|
||||
a VALUE formatter. Legacy clients will use the VALUE formatted and new clients will use the @Unformatted macro.
|
||||
* add RC_CONSOLE_FAMICOM_DISK_SYSTEM (split off of RC_CONSOLE_NINTENDO)
|
||||
* update RC_CONSOLE_SNES memory map to support SA-1 I-RAM and BW-RAM
|
||||
* update RC_CONSOLE_SEGACD memory map to supprot WORD RAM
|
||||
* update RC_CONSOLE_N64 memory map to place RDRAM at $80000000 and expansion pak RAM at $80400000
|
||||
* remove HAVE_LUA define and support (implementation was never finished)
|
||||
* report error when RP contains address starting with `0x0x`.
|
||||
* add .natvis files to improve debugging in Visual Studio
|
||||
|
||||
# v11.6.0
|
||||
* backdate retried unlocks in rc_client
|
||||
* add memory map and hash method for RC_CONSOLE_ZX_SPECTRUM
|
||||
* add RC_CONSOLE_GAMECUBE to supported consoles for iso file extension
|
||||
* add DTCM to RC_CONSOLE_NINTENDO_DS and RC_CONSOLE_NINTENDO_DSI memory maps
|
||||
* don't report conflict if last conditions of OrNext chain conflict
|
||||
* don't report conflict if last conditions of AddSource chain conflict
|
||||
* fix hits not being reset on leaderboard value when start and submit are both true in a single frame
|
||||
* fix crash when multiple items in a CSV lookup overlap
|
||||
* fix crash if game is unloaded while activating achievements
|
||||
|
||||
# v11.5.0
|
||||
* add total_entries to rc_api_fetch_leaderboard_info_response_t
|
||||
* add RC_CLIENT_RAINTEGRATION_EVENT_MENU_CHANGED event
|
||||
|
||||
Vendored
+1
-2
@@ -43,10 +43,9 @@ add_library(rcheevos
|
||||
src/rc_version.h
|
||||
src/rhash/md5.c
|
||||
src/rhash/md5.h
|
||||
src/rurl/url.c
|
||||
)
|
||||
|
||||
target_include_directories(rcheevos PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_include_directories(rcheevos INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_compile_definitions(rcheevos PRIVATE "RC_DISABLE_LUA=1" "RCHEEVOS_URL_SSL=1" "RC_NO_THREADS=1")
|
||||
target_compile_definitions(rcheevos PRIVATE "RC_DISABLE_LUA=1" "RCHEEVOS_URL_SSL=1" "RC_NO_THREADS=1" "RC_HASH_NO_DISC" "RC_HASH_NO_ENCRYPTED" "RC_HASH_NO_ROM" "RC_HASH_NO_ZIP")
|
||||
|
||||
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
- aes and 3DS functions in hash.c removed, due to potential legal issues.
|
||||
- .github/test/validator directories removed, as they are unnecessary.
|
||||
Vendored
+12
-26
@@ -6,23 +6,11 @@ Keep in mind that **rcheevos** does *not* provide HTTP network connections. Clie
|
||||
|
||||
Not all structures defined by **rcheevos** can be created via the public API, but are exposed to allow interactions beyond just creation, destruction, and testing, such as the ones required by UI code that helps to create them.
|
||||
|
||||
## Lua
|
||||
|
||||
RetroAchievements previously considered the use of the [Lua](https://www.lua.org) language to expand the syntax supported for creating achievements.
|
||||
|
||||
To enable Lua support, you must compile with an additional compilation flag: `HAVE_LUA`, as neither the backend nor the UI for editing achievements are currently Lua-enabled. We do not foresee enabling it any time soon, but the code has not yet been completely eliminated as many of the low-level API fuctions have parameters for LUA data.
|
||||
|
||||
> **rcheevos** does *not* create or maintain a Lua state, you have to create your own state and provide it to **rcheevos** to be used when Lua-coded achievements are found. Calls to **rcheevos** may allocate and/or free additional memory as part of the Lua runtime.
|
||||
|
||||
Lua functions used in trigger operands receive two parameters: `peek`, which is used to read from the emulated system's memory, and `userdata`, which must be passed to `peek`. `peek`'s signature is the same as its C counterpart:
|
||||
|
||||
```lua
|
||||
function peek(address, num_bytes, userdata)
|
||||
```
|
||||
**NOTE**: development occurs on the _develop_ branch, which is set as the default branch in GitHub so newly opened PRs will request to be merged into the _develop_ branch. When integrating **rcheevos** into your project, we recommend using the _master_ branch, which corresponds to the last official release, and minimizes the risk of encountering a bug that has been introduced since the last official release.
|
||||
|
||||
## API
|
||||
|
||||
An understanding about how achievements are developed may be useful, you can read more about it [here](http://docs.retroachievements.org/Developer-docs/).
|
||||
An understanding about how achievements are developed may be useful, you can read more about it [here](https://docs.retroachievements.org/developer-docs/).
|
||||
|
||||
Most of the exposed APIs are documented [here](https://github.com/RetroAchievements/rcheevos/wiki)
|
||||
|
||||
@@ -41,13 +29,7 @@ Platforms supported by RetroAchievements are enumerated in `rc_consoles.h`. Note
|
||||
|
||||
## Runtime support
|
||||
|
||||
Provides a set of functions for managing an active game - initializing and processing achievements, leaderboards, and rich presence. When important things occur, events are raised for the caller via a callback.
|
||||
|
||||
These are in `rc_runtime.h`.
|
||||
|
||||
Note: `rc_runtime_t` still requires the client implement all of the logic that calls the APIs to retrieve the data and perform the unlocks.
|
||||
|
||||
The `rc_client_t` functions wrap a `rc_runtime_t` and manage the API calls and other common functionality (like managing the user information, identifying/loading a game, and building the active/inactive achievements list for the UI). Please see [the wiki](https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration) for details on using the `rc_client_t` functions.
|
||||
A set of functions for managing an active game is provided by the library. If you are considering adding achievement support to your emulator, you should look at the `rc_client_t` functions which will prepare the API calls and other implement other common functionality (like managing the user information, identifying/loading a game, and building the active/inactive achievements list for the UI). It has several callback functions which allow the client to implement dependent functionality (UI and HTTP calls). Please see [the wiki](https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration) for details on using the `rc_client_t` functions.
|
||||
|
||||
## Server Communication
|
||||
|
||||
@@ -55,11 +37,9 @@ The `rc_client_t` functions wrap a `rc_runtime_t` and manage the API calls and o
|
||||
|
||||
**rapi** does *not* make HTTP requests.
|
||||
|
||||
NOTE: **rapi** is a replacement for **rurl**. **rurl** has been deprecated.
|
||||
|
||||
NOTE: `rc_client` is the preferred way to have a client interact with the server.
|
||||
|
||||
These are in `rc_api_user.h`, `rc_api_runtime.h` and `rc_api_common.h`.
|
||||
**rapi** headers are `rc_api_user.h`, `rc_api_runtime.h` and `rc_api_common.h`.
|
||||
|
||||
The basic process of making an **rapi** call is to initialize a params object, call a function to convert it to a URL, send that to the server, then pass the response to a function to convert it into a response object, and handle the response values.
|
||||
|
||||
@@ -76,6 +56,12 @@ Please see the [wiki](https://github.com/RetroAchievements/rcheevos/wiki) for de
|
||||
These are in `rc_hash.h`.
|
||||
|
||||
```c
|
||||
int rc_hash_generate_from_buffer(char hash[33], int console_id, uint8_t* buffer, size_t buffer_size);
|
||||
int rc_hash_generate_from_file(char hash[33], int console_id, const char* path);
|
||||
void rc_hash_initialize_iterator(rc_hash_iterator_t* iterator, const char* path, const uint8_t* buffer, size_t buffer_size);
|
||||
int rc_hash_generate(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator);
|
||||
int rc_hash_iterate(char hash[33], rc_hash_iterator_t* iterator);
|
||||
void rc_hash_destroy_iterator(rc_hash_iterator_t* iterator);
|
||||
```
|
||||
|
||||
### Custom file handling
|
||||
|
||||
**rhash** (and by extension **rc_client**) support custom handlers for opening/reading files. This allows the client to redirect file reads to support custom file formats (like ZIP or CHD).
|
||||
|
||||
+6
@@ -43,6 +43,7 @@ typedef struct rc_api_fetch_code_notes_response_t {
|
||||
rc_api_fetch_code_notes_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_code_notes_request(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_code_notes_request_hosted(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_code_notes_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -77,6 +78,7 @@ typedef struct rc_api_update_code_note_response_t {
|
||||
rc_api_update_code_note_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_code_note_request(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_code_note_request_hosted(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_update_code_note_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_code_note_response(rc_api_update_code_note_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_code_note_server_response(rc_api_update_code_note_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -126,6 +128,7 @@ typedef struct rc_api_update_achievement_response_t {
|
||||
rc_api_update_achievement_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_achievement_request_hosted(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_update_achievement_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_achievement_response(rc_api_update_achievement_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_achievement_server_response(rc_api_update_achievement_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -177,6 +180,7 @@ typedef struct rc_api_update_leaderboard_response_t {
|
||||
rc_api_update_leaderboard_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_leaderboard_request(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_update_leaderboard_request_hosted(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_update_leaderboard_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_leaderboard_response(rc_api_update_leaderboard_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_update_leaderboard_server_response(rc_api_update_leaderboard_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -208,6 +212,7 @@ typedef struct rc_api_fetch_badge_range_response_t {
|
||||
rc_api_fetch_badge_range_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_badge_range_request(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_badge_range_request_hosted(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_badge_range_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_badge_range_server_response(rc_api_fetch_badge_range_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -249,6 +254,7 @@ typedef struct rc_api_add_game_hash_response_t {
|
||||
rc_api_add_game_hash_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_add_game_hash_request(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_add_game_hash_request_hosted(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_add_game_hash_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_add_game_hash_response(rc_api_add_game_hash_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_add_game_hash_server_response(rc_api_add_game_hash_response_t* response, const rc_api_server_response_t* server_response);
|
||||
|
||||
+48
@@ -33,6 +33,8 @@ rc_api_fetch_achievement_info_request_t;
|
||||
typedef struct rc_api_achievement_awarded_entry_t {
|
||||
/* The user associated to the entry */
|
||||
const char* username;
|
||||
/* A URL to the user's avatar image */
|
||||
const char* avatar_url;
|
||||
/* When the achievement was awarded */
|
||||
time_t awarded;
|
||||
}
|
||||
@@ -62,6 +64,7 @@ typedef struct rc_api_fetch_achievement_info_response_t {
|
||||
rc_api_fetch_achievement_info_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_achievement_info_request(rc_api_request_t* request, const rc_api_fetch_achievement_info_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_achievement_info_request_hosted(rc_api_request_t* request, const rc_api_fetch_achievement_info_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_achievement_info_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achievement_info_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -88,6 +91,8 @@ rc_api_fetch_leaderboard_info_request_t;
|
||||
typedef struct rc_api_lboard_info_entry_t {
|
||||
/* The user associated to the entry */
|
||||
const char* username;
|
||||
/* A URL to the user's avatar image */
|
||||
const char* avatar_url;
|
||||
/* The rank of the entry */
|
||||
uint32_t rank;
|
||||
/* The index of the entry */
|
||||
@@ -138,6 +143,7 @@ typedef struct rc_api_fetch_leaderboard_info_response_t {
|
||||
rc_api_fetch_leaderboard_info_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_leaderboard_info_request(rc_api_request_t* request, const rc_api_fetch_leaderboard_info_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_leaderboard_info_request_hosted(rc_api_request_t* request, const rc_api_fetch_leaderboard_info_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_leaderboard_info_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboard_info_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -178,6 +184,7 @@ typedef struct rc_api_fetch_games_list_response_t {
|
||||
rc_api_fetch_games_list_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_games_list_request(rc_api_request_t* request, const rc_api_fetch_games_list_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_games_list_request_hosted(rc_api_request_t* request, const rc_api_fetch_games_list_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_games_list_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_games_list_response(rc_api_fetch_games_list_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -222,9 +229,50 @@ typedef struct rc_api_fetch_game_titles_response_t {
|
||||
rc_api_fetch_game_titles_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_titles_request(rc_api_request_t* request, const rc_api_fetch_game_titles_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_titles_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_titles_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_game_titles_server_response(rc_api_fetch_game_titles_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_titles_response(rc_api_fetch_game_titles_response_t* response);
|
||||
|
||||
/* --- Fetch Game Hashes --- */
|
||||
|
||||
/**
|
||||
* API parameters for a fetch games list request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_hash_library_request_t {
|
||||
/**
|
||||
* The unique identifier of the console to query.
|
||||
* Passing RC_CONSOLE_UNKNOWN will return hashes for all consoles.
|
||||
*/
|
||||
uint32_t console_id;
|
||||
} rc_api_fetch_hash_library_request_t;
|
||||
|
||||
/* A hash library entry */
|
||||
typedef struct rc_api_hash_library_entry_t {
|
||||
/* The hash for the game */
|
||||
const char* hash;
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
} rc_api_hash_library_entry_t;
|
||||
|
||||
/**
|
||||
* Response data for a fetch hash library request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_hash_library_response_t {
|
||||
/* An array of entries, one per game */
|
||||
rc_api_hash_library_entry_t* entries;
|
||||
/* The number of items in the entries array */
|
||||
uint32_t num_entries;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
}
|
||||
rc_api_fetch_hash_library_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_hash_library_request(rc_api_request_t* request, const rc_api_fetch_hash_library_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_hash_library_request_hosted(rc_api_request_t* request, const rc_api_fetch_hash_library_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_hash_library_server_response(rc_api_fetch_hash_library_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_hash_library_response(rc_api_fetch_hash_library_response_t* response);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
#endif /* RC_API_INFO_H */
|
||||
|
||||
+13
@@ -8,6 +8,17 @@
|
||||
|
||||
RC_BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* Information about the server being connected to.
|
||||
*/
|
||||
typedef struct rc_api_host_t {
|
||||
/* The host name for the API calls (retroachievements.org) */
|
||||
const char* host;
|
||||
/* The host name for media URLs (media.retroachievements.org) */
|
||||
const char* media_host;
|
||||
}
|
||||
rc_api_host_t;
|
||||
|
||||
/**
|
||||
* A constructed request to send to the retroachievements server.
|
||||
*/
|
||||
@@ -42,7 +53,9 @@ rc_api_response_t;
|
||||
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_request(rc_api_request_t* request);
|
||||
|
||||
/* [deprecated] use rc_api_init_*_hosted instead */
|
||||
RC_EXPORT void RC_CCONV rc_api_set_host(const char* hostname);
|
||||
/* [deprecated] use rc_api_init_*_hosted instead */
|
||||
RC_EXPORT void RC_CCONV rc_api_set_image_host(const char* hostname);
|
||||
|
||||
typedef struct rc_api_server_response_t {
|
||||
|
||||
+104
-1
@@ -28,6 +28,7 @@ rc_api_fetch_image_request_t;
|
||||
#define RC_IMAGE_TYPE_USER 4
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_image_request_hosted(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params, const rc_api_host_t* host);
|
||||
|
||||
/* --- Resolve Hash --- */
|
||||
|
||||
@@ -57,6 +58,8 @@ typedef struct rc_api_resolve_hash_response_t {
|
||||
rc_api_resolve_hash_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_resolve_hash_request(rc_api_request_t* request, const rc_api_resolve_hash_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_resolve_hash_request_hosted(rc_api_request_t* request, const rc_api_resolve_hash_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_resolve_hash_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_resolve_hash_response(rc_api_resolve_hash_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_resolve_hash_server_response(rc_api_resolve_hash_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_resolve_hash_response(rc_api_resolve_hash_response_t* response);
|
||||
@@ -73,6 +76,8 @@ typedef struct rc_api_fetch_game_data_request_t {
|
||||
const char* api_token;
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
/* The generated hash of the game to be identified (ignored if game_id is not 0) */
|
||||
const char* game_hash;
|
||||
}
|
||||
rc_api_fetch_game_data_request_t;
|
||||
|
||||
@@ -105,7 +110,7 @@ typedef struct rc_api_achievement_definition_t {
|
||||
uint32_t category;
|
||||
/* The title of the achievement */
|
||||
const char* title;
|
||||
/* The dscription of the achievement */
|
||||
/* The description of the achievement */
|
||||
const char* description;
|
||||
/* The definition of the achievement to be passed to rc_runtime_activate_achievement */
|
||||
const char* definition;
|
||||
@@ -123,6 +128,10 @@ typedef struct rc_api_achievement_definition_t {
|
||||
float rarity;
|
||||
/* The approximate rarity of the achievement in hardcore (X% of users have earned the achievement in hardcore) */
|
||||
float rarity_hardcore;
|
||||
/* The URL for the achievement badge */
|
||||
const char* badge_url;
|
||||
/* The URL for the locked achievement badge */
|
||||
const char* badge_locked_url;
|
||||
}
|
||||
rc_api_achievement_definition_t;
|
||||
|
||||
@@ -146,6 +155,8 @@ typedef struct rc_api_fetch_game_data_response_t {
|
||||
const char* title;
|
||||
/* The image name for the game badge */
|
||||
const char* image_name;
|
||||
/* The URL for the game badge */
|
||||
const char* image_url;
|
||||
/* The rich presence script for the game to be passed to rc_runtime_activate_richpresence */
|
||||
const char* rich_presence_script;
|
||||
|
||||
@@ -165,10 +176,96 @@ typedef struct rc_api_fetch_game_data_response_t {
|
||||
rc_api_fetch_game_data_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_data_request(rc_api_request_t* request, const rc_api_fetch_game_data_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_data_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_data_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_game_data_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_game_data_response(rc_api_fetch_game_data_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_data_response(rc_api_fetch_game_data_response_t* response);
|
||||
|
||||
/* --- Fetch Game Sets --- */
|
||||
|
||||
/**
|
||||
* API parameters for a fetch game data request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_game_sets_request_t {
|
||||
/* The username of the player */
|
||||
const char* username;
|
||||
/* The API token from the login request */
|
||||
const char* api_token;
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
/* The generated hash of the game to be identified (ignored if game_id is not 0) */
|
||||
const char* game_hash;
|
||||
}
|
||||
rc_api_fetch_game_sets_request_t;
|
||||
|
||||
#define RC_ACHIEVEMENT_SET_TYPE_CORE 0
|
||||
#define RC_ACHIEVEMENT_SET_TYPE_BONUS 1
|
||||
#define RC_ACHIEVEMENT_SET_TYPE_SPECIALTY 2
|
||||
#define RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE 3
|
||||
|
||||
/* A game subset definition */
|
||||
typedef struct rc_api_achievement_set_definition_t {
|
||||
/* The unique identifier of the achievement set */
|
||||
uint32_t id;
|
||||
/* The legacy game_id of the achievement set (used for editor API calls) */
|
||||
uint32_t game_id;
|
||||
/* The title of the achievement set */
|
||||
const char* title;
|
||||
/* The image name for the achievement set badge */
|
||||
const char* image_name;
|
||||
/* The URL for the achievement set badge */
|
||||
const char* image_url;
|
||||
|
||||
/* An array of achievements for the achievement set */
|
||||
rc_api_achievement_definition_t* achievements;
|
||||
/* The number of items in the achievements array */
|
||||
uint32_t num_achievements;
|
||||
|
||||
/* An array of leaderboards for the achievement set */
|
||||
rc_api_leaderboard_definition_t* leaderboards;
|
||||
/* The number of items in the leaderboards array */
|
||||
uint32_t num_leaderboards;
|
||||
|
||||
/* The type of the achievement set */
|
||||
uint8_t type;
|
||||
}
|
||||
rc_api_achievement_set_definition_t;
|
||||
|
||||
/**
|
||||
* Response data for a fetch game sets request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_game_sets_response_t {
|
||||
/* The unique identifier of the game */
|
||||
uint32_t id;
|
||||
/* The console associated to the game */
|
||||
uint32_t console_id;
|
||||
/* The title of the game */
|
||||
const char* title;
|
||||
/* The image name for the game badge */
|
||||
const char* image_name;
|
||||
/* The URL for the game badge */
|
||||
const char* image_url;
|
||||
/* The rich presence script for the game to be passed to rc_runtime_activate_richpresence */
|
||||
const char* rich_presence_script;
|
||||
/* The unique identifier of the game to use for session requests (startsession/ping/etc) */
|
||||
uint32_t session_game_id;
|
||||
|
||||
/* An array of sets for the game */
|
||||
rc_api_achievement_set_definition_t* sets;
|
||||
/* The number of items in the sets array */
|
||||
uint32_t num_sets;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
}
|
||||
rc_api_fetch_game_sets_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_sets_request(rc_api_request_t* request, const rc_api_fetch_game_sets_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_game_sets_request_hosted(rc_api_request_t* request, const rc_api_fetch_game_sets_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_game_sets_server_response(rc_api_fetch_game_sets_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_sets_response(rc_api_fetch_game_sets_response_t* response);
|
||||
|
||||
/* --- Ping --- */
|
||||
|
||||
/**
|
||||
@@ -200,6 +297,8 @@ typedef struct rc_api_ping_response_t {
|
||||
rc_api_ping_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_ping_request(rc_api_request_t* request, const rc_api_ping_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_ping_request_hosted(rc_api_request_t* request, const rc_api_ping_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_ping_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_ping_response(rc_api_ping_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_ping_server_response(rc_api_ping_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_ping_response(rc_api_ping_response_t* response);
|
||||
@@ -245,6 +344,8 @@ typedef struct rc_api_award_achievement_response_t {
|
||||
rc_api_award_achievement_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_api_award_achievement_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_award_achievement_request_hosted(rc_api_request_t* request, const rc_api_award_achievement_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_award_achievement_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_award_achievement_response(rc_api_award_achievement_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_award_achievement_server_response(rc_api_award_achievement_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_award_achievement_response(rc_api_award_achievement_response_t* response);
|
||||
@@ -305,6 +406,8 @@ typedef struct rc_api_submit_lboard_entry_response_t {
|
||||
rc_api_submit_lboard_entry_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_api_submit_lboard_entry_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_submit_lboard_entry_request_hosted(rc_api_request_t* request, const rc_api_submit_lboard_entry_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_submit_lboard_entry_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entry_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response);
|
||||
|
||||
+110
@@ -40,6 +40,8 @@ typedef struct rc_api_login_response_t {
|
||||
uint32_t num_unread_messages;
|
||||
/* The preferred name to display for the player */
|
||||
const char* display_name;
|
||||
/* A URL to the user's avatar image */
|
||||
const char* avatar_url;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
@@ -47,6 +49,7 @@ typedef struct rc_api_login_response_t {
|
||||
rc_api_login_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_login_request(rc_api_request_t* request, const rc_api_login_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_login_request_hosted(rc_api_request_t* request, const rc_api_login_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_login_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_login_response(rc_api_login_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_login_server_response(rc_api_login_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -105,6 +108,7 @@ typedef struct rc_api_start_session_response_t {
|
||||
rc_api_start_session_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_start_session_request(rc_api_request_t* request, const rc_api_start_session_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_start_session_request_hosted(rc_api_request_t* request, const rc_api_start_session_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_start_session_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_start_session_response(rc_api_start_session_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_start_session_server_response(rc_api_start_session_response_t* response, const rc_api_server_response_t* server_response);
|
||||
@@ -142,11 +146,117 @@ typedef struct rc_api_fetch_user_unlocks_response_t {
|
||||
rc_api_fetch_user_unlocks_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_user_unlocks_request(rc_api_request_t* request, const rc_api_fetch_user_unlocks_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_user_unlocks_request_hosted(rc_api_request_t* request, const rc_api_fetch_user_unlocks_request_t* api_params, const rc_api_host_t* host);
|
||||
/* [deprecated] use rc_api_process_fetch_user_unlocks_server_response instead */
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response, const char* server_response);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_user_unlocks_server_response(rc_api_fetch_user_unlocks_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response);
|
||||
|
||||
/* --- Fetch Followed Users --- */
|
||||
|
||||
/**
|
||||
* API parameters for a fetch followed users request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_followed_users_request_t {
|
||||
/* The username of the player */
|
||||
const char* username;
|
||||
/* The API token from the login request */
|
||||
const char* api_token;
|
||||
}
|
||||
rc_api_fetch_followed_users_request_t;
|
||||
|
||||
typedef struct rc_api_followed_user_activity_t {
|
||||
/* The record associated to the activity */
|
||||
const char* context;
|
||||
/* The image of the record associated to the activity */
|
||||
const char* context_image_url;
|
||||
/* The description of the activity */
|
||||
const char* description;
|
||||
/* The time of the activity */
|
||||
time_t when;
|
||||
/* The unique identifier of the record associated to the activity */
|
||||
uint32_t context_id;
|
||||
}
|
||||
rc_api_followed_user_activity_t;
|
||||
|
||||
/**
|
||||
* Response data for a followed user.
|
||||
*/
|
||||
typedef struct rc_api_followed_user_t {
|
||||
/* The preferred name to display for the player */
|
||||
const char* display_name;
|
||||
/* A URL to the user's avatar image */
|
||||
const char* avatar_url;
|
||||
/* The player's last registered activity */
|
||||
rc_api_followed_user_activity_t recent_activity;
|
||||
/* The current score of the player */
|
||||
uint32_t score;
|
||||
}
|
||||
rc_api_followed_user_t;
|
||||
|
||||
/**
|
||||
* Response data for a fetch followed users request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_followed_users_response_t {
|
||||
/* An array of followed user information */
|
||||
rc_api_followed_user_t* users;
|
||||
/* The number of items in the users array */
|
||||
uint32_t num_users;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
}
|
||||
rc_api_fetch_followed_users_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_followed_users_request(rc_api_request_t* request, const rc_api_fetch_followed_users_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_followed_users_request_hosted(rc_api_request_t* request, const rc_api_fetch_followed_users_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_followed_users_server_response(rc_api_fetch_followed_users_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_followed_users_response(rc_api_fetch_followed_users_response_t* response);
|
||||
|
||||
/* --- Fetch All Progress --- */
|
||||
|
||||
/**
|
||||
* API parameters for a fetch all user progress request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_all_user_progress_request_t {
|
||||
/* The username of the player */
|
||||
const char* username;
|
||||
/* The API token from the login request */
|
||||
const char* api_token;
|
||||
/* The unique identifier of the console to query */
|
||||
uint32_t console_id;
|
||||
} rc_api_fetch_all_user_progress_request_t;
|
||||
|
||||
/* An all-user-progress entry */
|
||||
typedef struct rc_api_all_user_progress_entry_t {
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
/* The total number of achievements for this game */
|
||||
uint32_t num_achievements;
|
||||
/* The total number of unlocked achievements for this game in softcore mode */
|
||||
uint32_t num_unlocked_achievements;
|
||||
/* The total number of unlocked achievements for this game in hardcore mode */
|
||||
uint32_t num_unlocked_achievements_hardcore;
|
||||
} rc_api_all_user_progress_entry_t;
|
||||
|
||||
/**
|
||||
* Response data for a fetch all user progress request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_all_user_progress_response_t {
|
||||
/* An array of entries, one per game */
|
||||
rc_api_all_user_progress_entry_t* entries;
|
||||
/* The number of items in the entries array */
|
||||
uint32_t num_entries;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
} rc_api_fetch_all_user_progress_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request_hosted(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user_progress_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_all_user_progress_response(rc_api_fetch_all_user_progress_response_t* response);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
#endif /* RC_API_H */
|
||||
|
||||
+102
-10
@@ -121,7 +121,7 @@ RC_EXPORT void* RC_CCONV rc_client_get_userdata(const rc_client_t* client);
|
||||
/**
|
||||
* Sets the name of the server to use.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_set_host(const rc_client_t* client, const char* hostname);
|
||||
RC_EXPORT void RC_CCONV rc_client_set_host(rc_client_t* client, const char* hostname);
|
||||
|
||||
typedef uint64_t rc_clock_t;
|
||||
typedef rc_clock_t (RC_CCONV *rc_get_time_millisecs_func_t)(const rc_client_t* client);
|
||||
@@ -188,6 +188,8 @@ typedef struct rc_client_user_t {
|
||||
uint32_t score;
|
||||
uint32_t score_softcore;
|
||||
uint32_t num_unread_messages;
|
||||
/* minimum version: 12.0 */
|
||||
const char* avatar_url;
|
||||
} rc_client_user_t;
|
||||
|
||||
/**
|
||||
@@ -217,6 +219,39 @@ typedef struct rc_client_user_game_summary_t {
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary);
|
||||
|
||||
typedef struct rc_client_all_user_progress_entry_t {
|
||||
uint32_t game_id;
|
||||
uint32_t num_achievements;
|
||||
uint32_t num_unlocked_achievements;
|
||||
uint32_t num_unlocked_achievements_hardcore;
|
||||
} rc_client_all_user_progress_entry_t;
|
||||
|
||||
typedef struct rc_client_all_user_progress_t {
|
||||
rc_client_all_user_progress_entry_t* entries;
|
||||
uint32_t num_entries;
|
||||
} rc_client_all_user_progress_t;
|
||||
|
||||
/**
|
||||
* Callback that is fired when an all progress query completes. list may be null if the query failed.
|
||||
*/
|
||||
typedef void(RC_CCONV* rc_client_fetch_all_user_progress_callback_t)(int result, const char* error_message,
|
||||
rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
|
||||
/**
|
||||
* Starts an asynchronous request for all progress for the given console.
|
||||
* This query returns the total number of achievements for all games tracked by this console, as well as
|
||||
* the user's achievement unlock count for both softcore and hardcore modes.
|
||||
*/
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV
|
||||
rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id,
|
||||
rc_client_fetch_all_user_progress_callback_t callback, void* callback_userdata);
|
||||
|
||||
/**
|
||||
* Destroys a previously-allocated result from the rc_client_begin_fetch_all_progress_list() callback.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Game |
|
||||
\*****************************************************************************/
|
||||
@@ -229,6 +264,12 @@ RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_load_g
|
||||
uint32_t console_id, const char* file_path,
|
||||
const uint8_t* data, size_t data_size,
|
||||
rc_client_callback_t callback, void* callback_userdata);
|
||||
|
||||
struct rc_hash_callbacks;
|
||||
/**
|
||||
* Provide callback functions for interacting with the file system and processing disc-based files when generating hashes.
|
||||
*/
|
||||
RC_EXPORT void rc_client_set_hash_callbacks(rc_client_t* client, const struct rc_hash_callbacks* callbacks);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -243,9 +284,9 @@ RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_game(rc_client
|
||||
RC_EXPORT int RC_CCONV rc_client_get_load_game_state(const rc_client_t* client);
|
||||
enum {
|
||||
RC_CLIENT_LOAD_GAME_STATE_NONE,
|
||||
RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME,
|
||||
RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN,
|
||||
RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA,
|
||||
RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME,
|
||||
RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA, /* [deprecated] - game data is now returned by identify call */
|
||||
RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION,
|
||||
RC_CLIENT_LOAD_GAME_STATE_DONE,
|
||||
RC_CLIENT_LOAD_GAME_STATE_ABORTED
|
||||
@@ -267,6 +308,8 @@ typedef struct rc_client_game_t {
|
||||
const char* title;
|
||||
const char* hash;
|
||||
const char* badge_name;
|
||||
/* minimum version: 12.0 */
|
||||
const char* badge_url;
|
||||
} rc_client_game_t;
|
||||
|
||||
/**
|
||||
@@ -285,15 +328,17 @@ RC_EXPORT int RC_CCONV rc_client_game_get_image_url(const rc_client_game_t* game
|
||||
/**
|
||||
* Changes the active disc in a multi-disc game.
|
||||
*/
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* file_path,
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_change_media(rc_client_t* client, const char* file_path,
|
||||
const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Changes the active disc in a multi-disc game.
|
||||
*/
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media_from_hash(rc_client_t* client, const char* hash,
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* hash,
|
||||
rc_client_callback_t callback, void* callback_userdata);
|
||||
/* this function was renamed in rcheevos 12.0 */
|
||||
#define rc_client_begin_change_media_from_hash rc_client_begin_change_media
|
||||
|
||||
/*****************************************************************************\
|
||||
| Subsets |
|
||||
@@ -306,10 +351,47 @@ typedef struct rc_client_subset_t {
|
||||
|
||||
uint32_t num_achievements;
|
||||
uint32_t num_leaderboards;
|
||||
|
||||
/* minimum version: 12.0 */
|
||||
const char* badge_url;
|
||||
} rc_client_subset_t;
|
||||
|
||||
RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Fetch Game Hashes |
|
||||
\*****************************************************************************/
|
||||
|
||||
typedef struct rc_client_hash_library_entry_t {
|
||||
char hash[33];
|
||||
uint32_t game_id;
|
||||
} rc_client_hash_library_entry_t;
|
||||
|
||||
typedef struct rc_client_hash_library_t {
|
||||
rc_client_hash_library_entry_t* entries;
|
||||
uint32_t num_entries;
|
||||
} rc_client_hash_library_t;
|
||||
|
||||
/**
|
||||
* Callback that is fired when a hash library request completes. list may be null if the query failed.
|
||||
*/
|
||||
typedef void(RC_CCONV* rc_client_fetch_hash_library_callback_t)(int result, const char* error_message,
|
||||
rc_client_hash_library_t* list, rc_client_t* client,
|
||||
void* callback_userdata);
|
||||
|
||||
/**
|
||||
* Starts an asynchronous request for all hashes for the given console.
|
||||
* This request returns a mapping from hashes to the game's unique identifier. A single game may have multiple
|
||||
* hashes in the case of multi-disc games, or variants that are still compatible with the same achievement set.
|
||||
*/
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_hash_library(
|
||||
rc_client_t* client, uint32_t console_id, rc_client_fetch_hash_library_callback_t callback, void* callback_userdata);
|
||||
|
||||
/**
|
||||
* Destroys a previously-allocated result from the rc_client_destroy_hash_library() callback.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_destroy_hash_library(rc_client_hash_library_t* list);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Achievements |
|
||||
\*****************************************************************************/
|
||||
@@ -373,6 +455,9 @@ typedef struct rc_client_achievement_t {
|
||||
float rarity;
|
||||
float rarity_hardcore;
|
||||
uint8_t type;
|
||||
/* minimum version: 12.0 */
|
||||
const char* badge_url;
|
||||
const char* badge_locked_url;
|
||||
} rc_client_achievement_t;
|
||||
|
||||
/**
|
||||
@@ -387,7 +472,7 @@ RC_EXPORT const rc_client_achievement_t* RC_CCONV rc_client_get_achievement_info
|
||||
RC_EXPORT int RC_CCONV rc_client_achievement_get_image_url(const rc_client_achievement_t* achievement, int state, char buffer[], size_t buffer_size);
|
||||
|
||||
typedef struct rc_client_achievement_bucket_t {
|
||||
rc_client_achievement_t** achievements;
|
||||
const rc_client_achievement_t** achievements;
|
||||
uint32_t num_achievements;
|
||||
|
||||
const char* label;
|
||||
@@ -396,7 +481,7 @@ typedef struct rc_client_achievement_bucket_t {
|
||||
} rc_client_achievement_bucket_t;
|
||||
|
||||
typedef struct rc_client_achievement_list_t {
|
||||
rc_client_achievement_bucket_t* buckets;
|
||||
const rc_client_achievement_bucket_t* buckets;
|
||||
uint32_t num_buckets;
|
||||
} rc_client_achievement_list_t;
|
||||
|
||||
@@ -463,7 +548,7 @@ typedef struct rc_client_leaderboard_tracker_t {
|
||||
} rc_client_leaderboard_tracker_t;
|
||||
|
||||
typedef struct rc_client_leaderboard_bucket_t {
|
||||
rc_client_leaderboard_t** leaderboards;
|
||||
const rc_client_leaderboard_t** leaderboards;
|
||||
uint32_t num_leaderboards;
|
||||
|
||||
const char* label;
|
||||
@@ -472,7 +557,7 @@ typedef struct rc_client_leaderboard_bucket_t {
|
||||
} rc_client_leaderboard_bucket_t;
|
||||
|
||||
typedef struct rc_client_leaderboard_list_t {
|
||||
rc_client_leaderboard_bucket_t* buckets;
|
||||
const rc_client_leaderboard_bucket_t* buckets;
|
||||
uint32_t num_buckets;
|
||||
} rc_client_leaderboard_list_t;
|
||||
|
||||
@@ -619,7 +704,8 @@ enum {
|
||||
RC_CLIENT_EVENT_GAME_COMPLETED = 15, /* all achievements for the game have been earned */
|
||||
RC_CLIENT_EVENT_SERVER_ERROR = 16, /* an API response returned a [server_error] and will not be retried */
|
||||
RC_CLIENT_EVENT_DISCONNECTED = 17, /* an unlock request could not be completed and is pending */
|
||||
RC_CLIENT_EVENT_RECONNECTED = 18 /* all pending unlocks have been completed */
|
||||
RC_CLIENT_EVENT_RECONNECTED = 18, /* all pending unlocks have been completed */
|
||||
RC_CLIENT_EVENT_SUBSET_COMPLETED = 19 /* all achievements for the subset have been earned */
|
||||
};
|
||||
|
||||
typedef struct rc_client_server_error_t {
|
||||
@@ -637,6 +723,7 @@ typedef struct rc_client_event_t {
|
||||
rc_client_leaderboard_tracker_t* leaderboard_tracker;
|
||||
rc_client_leaderboard_scoreboard_t* leaderboard_scoreboard;
|
||||
rc_client_server_error_t* server_error;
|
||||
rc_client_subset_t* subset;
|
||||
|
||||
} rc_client_event_t;
|
||||
|
||||
@@ -655,6 +742,11 @@ RC_EXPORT void RC_CCONV rc_client_set_event_handler(rc_client_t* client, rc_clie
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler);
|
||||
|
||||
/**
|
||||
* Specifies whether rc_client is allowed to read memory outside of rc_client_do_frame/rc_client_idle.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_set_allow_background_memory_reads(rc_client_t* client, int allowed);
|
||||
|
||||
/**
|
||||
* Determines if there are any active achievements/leaderboards/rich presence that need processing.
|
||||
*/
|
||||
|
||||
+1
@@ -93,6 +93,7 @@ enum {
|
||||
RC_CONSOLE_NINTENDO_DSI = 78,
|
||||
RC_CONSOLE_TI83 = 79,
|
||||
RC_CONSOLE_UZEBOX = 80,
|
||||
RC_CONSOLE_FAMICOM_DISK_SYSTEM = 81,
|
||||
|
||||
RC_CONSOLE_HUBS = 100,
|
||||
RC_CONSOLE_EVENTS = 101,
|
||||
|
||||
Vendored
+3
-2
@@ -11,7 +11,7 @@ RC_BEGIN_C_DECLS
|
||||
|
||||
enum {
|
||||
RC_OK = 0,
|
||||
RC_INVALID_LUA_OPERAND = -1,
|
||||
RC_INVALID_FUNC_OPERAND = -1,
|
||||
RC_INVALID_MEMORY_OPERAND = -2,
|
||||
RC_INVALID_CONST_OPERAND = -3,
|
||||
RC_INVALID_FP_OPERAND = -4,
|
||||
@@ -48,7 +48,8 @@ enum {
|
||||
RC_EXPIRED_TOKEN = -35,
|
||||
RC_INSUFFICIENT_BUFFER = -36,
|
||||
RC_INVALID_VARIABLE_NAME = -37,
|
||||
RC_UNKNOWN_VARIABLE_NAME = -38
|
||||
RC_UNKNOWN_VARIABLE_NAME = -38,
|
||||
RC_NOT_FOUND = -39
|
||||
};
|
||||
|
||||
RC_EXPORT const char* RC_CCONV rc_error_str(int ret);
|
||||
|
||||
Vendored
+115
-46
@@ -9,54 +9,19 @@
|
||||
|
||||
RC_BEGIN_C_DECLS
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
/* generates a hash from a block of memory.
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_hash_generate_from_buffer(char hash[33], uint32_t console_id, const uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
/* generates a hash from a file.
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* path);
|
||||
struct rc_hash_iterator;
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
/* data for rc_hash_iterate
|
||||
*/
|
||||
typedef struct rc_hash_iterator
|
||||
{
|
||||
const uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
uint8_t consoles[12];
|
||||
int index;
|
||||
const char* path;
|
||||
} rc_hash_iterator_t;
|
||||
|
||||
/* initializes a rc_hash_iterator
|
||||
* - path must be provided
|
||||
* - if buffer and buffer_size are provided, path may be a filename (i.e. for something extracted from a zip file)
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char* path, const uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
/* releases resources associated to a rc_hash_iterator
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_hash_destroy_iterator(struct rc_hash_iterator* iterator);
|
||||
|
||||
/* generates the next hash for the data in the rc_hash_iterator.
|
||||
* returns non-zero if a hash was generated, or zero if no more hashes can be generated for the data.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_hash_iterate(char hash[33], struct rc_hash_iterator* iterator);
|
||||
|
||||
/* ===================================================== */
|
||||
typedef void (RC_CCONV *rc_hash_message_callback_deprecated)(const char*);
|
||||
|
||||
/* specifies a function to call when an error occurs to display the error message */
|
||||
typedef void (RC_CCONV *rc_hash_message_callback)(const char*);
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_error_message_callback(rc_hash_message_callback callback);
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_error_message_callback(rc_hash_message_callback_deprecated callback);
|
||||
|
||||
/* specifies a function to call for verbose logging */
|
||||
RC_EXPORT void rc_hash_init_verbose_message_callback(rc_hash_message_callback callback);
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void rc_hash_init_verbose_message_callback(rc_hash_message_callback_deprecated callback);
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
@@ -77,19 +42,22 @@ RC_BEGIN_C_DECLS
|
||||
/* closes the file */
|
||||
typedef void (RC_CCONV *rc_hash_filereader_close_file_handler)(void* file_handle);
|
||||
|
||||
struct rc_hash_filereader
|
||||
typedef struct rc_hash_filereader
|
||||
{
|
||||
rc_hash_filereader_open_file_handler open;
|
||||
rc_hash_filereader_seek_handler seek;
|
||||
rc_hash_filereader_tell_handler tell;
|
||||
rc_hash_filereader_read_handler read;
|
||||
rc_hash_filereader_close_file_handler close;
|
||||
};
|
||||
} rc_hash_filereader_t;
|
||||
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_custom_filereader(struct rc_hash_filereader* reader);
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
#ifndef RC_HASH_NO_DISC
|
||||
|
||||
#define RC_HASH_CDTRACK_FIRST_DATA ((uint32_t)-1) /* the first data track (skip audio tracks) */
|
||||
#define RC_HASH_CDTRACK_LAST ((uint32_t)-2) /* the last data/audio track */
|
||||
#define RC_HASH_CDTRACK_LARGEST ((uint32_t)-3) /* the largest data/audio track */
|
||||
@@ -99,6 +67,7 @@ RC_BEGIN_C_DECLS
|
||||
* returns a handle to be passed to the other functions, or NULL if the track could not be opened.
|
||||
*/
|
||||
typedef void* (RC_CCONV *rc_hash_cdreader_open_track_handler)(const char* path, uint32_t track);
|
||||
typedef void* (RC_CCONV* rc_hash_cdreader_open_track_iterator_handler)(const char* path, uint32_t track, const struct rc_hash_iterator* iterator);
|
||||
|
||||
/* attempts to read the specified number of bytes from the file starting at the specified absolute sector.
|
||||
* returns the number of bytes actually read.
|
||||
@@ -111,19 +80,119 @@ RC_BEGIN_C_DECLS
|
||||
/* gets the absolute sector index for the first sector of a track */
|
||||
typedef uint32_t(RC_CCONV *rc_hash_cdreader_first_track_sector_handler)(void* track_handle);
|
||||
|
||||
struct rc_hash_cdreader
|
||||
typedef struct rc_hash_cdreader
|
||||
{
|
||||
rc_hash_cdreader_open_track_handler open_track;
|
||||
rc_hash_cdreader_read_sector_handler read_sector;
|
||||
rc_hash_cdreader_close_track_handler close_track;
|
||||
rc_hash_cdreader_first_track_sector_handler first_track_sector;
|
||||
};
|
||||
rc_hash_cdreader_open_track_iterator_handler open_track_iterator;
|
||||
} rc_hash_cdreader_t;
|
||||
|
||||
RC_EXPORT void RC_CCONV rc_hash_get_default_cdreader(struct rc_hash_cdreader* cdreader);
|
||||
/* [deprecated] don't set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_default_cdreader(void);
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_custom_cdreader(struct rc_hash_cdreader* reader);
|
||||
|
||||
/* ===================================================== */
|
||||
#endif /* RC_HASH_NO_DISC */
|
||||
|
||||
#ifndef RC_HASH_NO_ENCRYPTED
|
||||
|
||||
/* specifies a function called to obtain a 3DS CIA decryption normal key.
|
||||
* this key would be derived from slot0x3DKeyX and the common key specified by the passed index.
|
||||
* the normal key should be written in big endian format
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
typedef int (RC_CCONV *rc_hash_3ds_get_cia_normal_key_func)(uint8_t common_key_index, uint8_t out_normal_key[16]);
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_3ds_get_cia_normal_key_func(rc_hash_3ds_get_cia_normal_key_func func);
|
||||
|
||||
/* specifies a function called to obtain 3DS NCCH decryption normal keys.
|
||||
* the primary key will always use slot0x2CKeyX and the passed primary KeyY.
|
||||
* the secondary key will use the KeyX slot passed
|
||||
* the secondary KeyY will be identical to the primary keyY if the passed program id is NULL
|
||||
* if the program id is not null, then the secondary KeyY will be obtained with "seed crypto"
|
||||
* with "seed crypto" the 8 byte program id can be used to obtain a 16 byte "seed" within the seeddb.bin firmware file
|
||||
* the primary KeyY then the seed will then be hashed with SHA256, and the upper 16 bytes of the digest will be the secondary KeyY used
|
||||
* the normal keys should be written in big endian format
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
typedef int (RC_CCONV *rc_hash_3ds_get_ncch_normal_keys_func)(uint8_t primary_key_y[16], uint8_t secondary_key_x_slot, uint8_t* optional_program_id,
|
||||
uint8_t out_primary_key[16], uint8_t out_secondary_key[16]);
|
||||
/* [deprecated] set callbacks in rc_hash_iterator_t */
|
||||
RC_EXPORT void RC_CCONV rc_hash_init_3ds_get_ncch_normal_keys_func(rc_hash_3ds_get_ncch_normal_keys_func func);
|
||||
|
||||
#endif /* RC_HASH_NO_ENCRYPTED */
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
typedef void (RC_CCONV* rc_hash_message_callback_func)(const char*, const struct rc_hash_iterator* iterator);
|
||||
|
||||
typedef struct rc_hash_callbacks {
|
||||
rc_hash_message_callback_func verbose_message;
|
||||
rc_hash_message_callback_func error_message;
|
||||
|
||||
rc_hash_filereader_t filereader;
|
||||
#ifndef RC_HASH_NO_DISC
|
||||
rc_hash_cdreader_t cdreader;
|
||||
#endif
|
||||
|
||||
#ifndef RC_HASH_NO_ENCRYPTED
|
||||
struct rc_hash_encryption_callbacks {
|
||||
rc_hash_3ds_get_cia_normal_key_func get_3ds_cia_normal_key;
|
||||
rc_hash_3ds_get_ncch_normal_keys_func get_3ds_ncch_normal_keys;
|
||||
} encryption;
|
||||
#endif
|
||||
} rc_hash_callbacks_t;
|
||||
|
||||
/* data for rc_hash_iterate
|
||||
*/
|
||||
typedef struct rc_hash_iterator {
|
||||
const uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
uint8_t consoles[12];
|
||||
int index;
|
||||
const char* path;
|
||||
|
||||
rc_hash_callbacks_t callbacks;
|
||||
} rc_hash_iterator_t;
|
||||
|
||||
/* initializes a rc_hash_iterator
|
||||
* - path must be provided
|
||||
* - if buffer and buffer_size are provided, path may be a filename (i.e. for something extracted from a zip file)
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_hash_initialize_iterator(rc_hash_iterator_t* iterator, const char* path, const uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
/* releases resources associated to a rc_hash_iterator
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_hash_destroy_iterator(rc_hash_iterator_t* iterator);
|
||||
|
||||
/* generates the next hash for the data in the rc_hash_iterator.
|
||||
* returns non-zero if a hash was generated, or zero if no more hashes can be generated for the data.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_hash_iterate(char hash[33], rc_hash_iterator_t* iterator);
|
||||
|
||||
/* generates a hash for the data in the rc_hash_iterator.
|
||||
* returns non-zero if a hash was generated.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_hash_generate(char hash[33], uint32_t console_id, const rc_hash_iterator_t* iterator);
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
/* generates a hash from a block of memory.
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
/* [deprecated] use rc_hash_generate instead */
|
||||
RC_EXPORT int RC_CCONV rc_hash_generate_from_buffer(char hash[33], uint32_t console_id, const uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
/* generates a hash from a file.
|
||||
* returns non-zero on success, or zero on failure.
|
||||
*/
|
||||
/* [deprecated] use rc_hash_generate instead */
|
||||
RC_EXPORT int RC_CCONV rc_hash_generate_from_file(char hash[33], uint32_t console_id, const char* path);
|
||||
|
||||
/* ===================================================== */
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
|
||||
+11
-21
@@ -14,8 +14,6 @@ RC_BEGIN_C_DECLS
|
||||
|
||||
#ifndef RC_RUNTIME_TYPES_H /* prevents pedantic redefinition error */
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef struct rc_trigger_t rc_trigger_t;
|
||||
typedef struct rc_lboard_t rc_lboard_t;
|
||||
typedef struct rc_richpresence_t rc_richpresence_t;
|
||||
@@ -46,7 +44,6 @@ typedef struct rc_runtime_trigger_t {
|
||||
rc_memref_t* invalid_memref;
|
||||
uint8_t md5[16];
|
||||
int32_t serialized_size;
|
||||
uint8_t owns_memrefs;
|
||||
}
|
||||
rc_runtime_trigger_t;
|
||||
|
||||
@@ -58,16 +55,13 @@ typedef struct rc_runtime_lboard_t {
|
||||
rc_memref_t* invalid_memref;
|
||||
uint8_t md5[16];
|
||||
uint32_t serialized_size;
|
||||
uint8_t owns_memrefs;
|
||||
}
|
||||
rc_runtime_lboard_t;
|
||||
|
||||
typedef struct rc_runtime_richpresence_t {
|
||||
rc_richpresence_t* richpresence;
|
||||
void* buffer;
|
||||
struct rc_runtime_richpresence_t* previous;
|
||||
uint8_t md5[16];
|
||||
uint8_t owns_memrefs;
|
||||
}
|
||||
rc_runtime_richpresence_t;
|
||||
|
||||
@@ -82,11 +76,7 @@ typedef struct rc_runtime_t {
|
||||
|
||||
rc_runtime_richpresence_t* richpresence;
|
||||
|
||||
rc_memref_t* memrefs;
|
||||
rc_memref_t** next_memref;
|
||||
|
||||
rc_value_t* variables;
|
||||
rc_value_t** next_variable;
|
||||
struct rc_memrefs_t* memrefs;
|
||||
|
||||
uint8_t owns_self;
|
||||
}
|
||||
@@ -96,20 +86,20 @@ RC_EXPORT rc_runtime_t* RC_CCONV rc_runtime_alloc(void);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_init(rc_runtime_t* runtime);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_destroy(rc_runtime_t* runtime);
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_achievement(rc_runtime_t* runtime, uint32_t id, const char* memaddr, lua_State* L, int funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_achievement(rc_runtime_t* runtime, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_deactivate_achievement(rc_runtime_t* runtime, uint32_t id);
|
||||
RC_EXPORT rc_trigger_t* RC_CCONV rc_runtime_get_achievement(const rc_runtime_t* runtime, uint32_t id);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_get_achievement_measured(const rc_runtime_t* runtime, uint32_t id, unsigned* measured_value, unsigned* measured_target);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_format_achievement_measured(const rc_runtime_t* runtime, uint32_t id, char *buffer, size_t buffer_size);
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_lboard(rc_runtime_t* runtime, uint32_t id, const char* memaddr, lua_State* L, int funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_lboard(rc_runtime_t* runtime, uint32_t id, const char* memaddr, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_deactivate_lboard(rc_runtime_t* runtime, uint32_t id);
|
||||
RC_EXPORT rc_lboard_t* RC_CCONV rc_runtime_get_lboard(const rc_runtime_t* runtime, uint32_t id);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_format_lboard_value(char* buffer, int size, int32_t value, int format);
|
||||
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, lua_State* L, int funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_get_richpresence(const rc_runtime_t* runtime, char* buffer, size_t buffersize, rc_runtime_peek_t peek, void* peek_ud, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_get_richpresence(const rc_runtime_t* runtime, char* buffer, size_t buffersize, rc_runtime_peek_t peek, void* peek_ud, void* unused_L);
|
||||
|
||||
enum {
|
||||
RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, /* from WAITING, PAUSED, or PRIMED to ACTIVE */
|
||||
@@ -136,22 +126,22 @@ rc_runtime_event_t;
|
||||
|
||||
typedef void (RC_CCONV *rc_runtime_event_handler_t)(const rc_runtime_event_t* runtime_event);
|
||||
|
||||
RC_EXPORT void RC_CCONV rc_runtime_do_frame(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_runtime_peek_t peek, void* ud, lua_State* L);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_do_frame(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_runtime_peek_t peek, void* ud, void* unused_L);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_reset(rc_runtime_t* runtime);
|
||||
|
||||
typedef int (RC_CCONV *rc_runtime_validate_address_t)(uint32_t address);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_validate_addresses(rc_runtime_t* runtime, rc_runtime_event_handler_t event_handler, rc_runtime_validate_address_t validate_handler);
|
||||
RC_EXPORT void RC_CCONV rc_runtime_invalidate_address(rc_runtime_t* runtime, uint32_t address);
|
||||
|
||||
RC_EXPORT uint32_t RC_CCONV rc_runtime_progress_size(const rc_runtime_t* runtime, lua_State* L);
|
||||
RC_EXPORT uint32_t RC_CCONV rc_runtime_progress_size(const rc_runtime_t* runtime, void* unused_L);
|
||||
|
||||
/* [deprecated] use rc_runtime_serialize_progress_sized instead */
|
||||
RC_EXPORT int RC_CCONV rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_serialize_progress_sized(uint8_t* buffer, uint32_t buffer_size, const rc_runtime_t* runtime, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_serialize_progress(void* buffer, const rc_runtime_t* runtime, void* unused_L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_serialize_progress_sized(uint8_t* buffer, uint32_t buffer_size, const rc_runtime_t* runtime, void* unused_L);
|
||||
|
||||
/* [deprecated] use rc_runtime_deserialize_progress_sized instead */
|
||||
RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress(rc_runtime_t* runtime, const uint8_t* serialized, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress_sized(rc_runtime_t* runtime, const uint8_t* serialized, uint32_t serialized_size, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress(rc_runtime_t* runtime, const uint8_t* serialized, void* unused_L);
|
||||
RC_EXPORT int RC_CCONV rc_runtime_deserialize_progress_sized(rc_runtime_t* runtime, const uint8_t* serialized, uint32_t serialized_size, void* unused_L);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
|
||||
+75
-63
@@ -10,8 +10,6 @@ RC_BEGIN_C_DECLS
|
||||
|
||||
#ifndef RC_RUNTIME_H /* prevents pedantic redefiniton error */
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef struct rc_trigger_t rc_trigger_t;
|
||||
typedef struct rc_lboard_t rc_lboard_t;
|
||||
typedef struct rc_richpresence_t rc_richpresence_t;
|
||||
@@ -29,7 +27,7 @@ typedef struct rc_value_t rc_value_t;
|
||||
* num_bytes is greater than 1, the value is read in little-endian from
|
||||
* memory.
|
||||
*/
|
||||
typedef uint32_t(RC_CCONV *rc_peek_t)(uint32_t address, uint32_t num_bytes, void* ud);
|
||||
typedef uint32_t(RC_CCONV* rc_peek_t)(uint32_t address, uint32_t num_bytes, void* ud);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Memory References |
|
||||
@@ -70,15 +68,14 @@ typedef struct rc_memref_value_t {
|
||||
/* The last differing value of this memory reference. */
|
||||
uint32_t prior;
|
||||
|
||||
/* The size of the value. */
|
||||
/* The size of the value. (RC_MEMSIZE_*) */
|
||||
uint8_t size;
|
||||
/* True if the value changed this frame. */
|
||||
uint8_t changed;
|
||||
/* The value type of the value (for variables) */
|
||||
/* The value type of the value. (RC_VALUE_TYPE_*) */
|
||||
uint8_t type;
|
||||
/* True if the reference will be used in indirection.
|
||||
* NOTE: This is actually a property of the rc_memref_t, but we put it here to save space */
|
||||
uint8_t is_indirect;
|
||||
/* The type of memref (RC_MEMREF_TYPE_*) */
|
||||
uint8_t memref_type;
|
||||
}
|
||||
rc_memref_value_t;
|
||||
|
||||
@@ -88,9 +85,6 @@ struct rc_memref_t {
|
||||
|
||||
/* The memory address of this variable. */
|
||||
uint32_t address;
|
||||
|
||||
/* The next memory reference in the chain. */
|
||||
rc_memref_t* next;
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -103,7 +97,7 @@ enum {
|
||||
RC_OPERAND_DELTA, /* The value last known at this address. */
|
||||
RC_OPERAND_CONST, /* A 32-bit unsigned integer. */
|
||||
RC_OPERAND_FP, /* A floating point value. */
|
||||
RC_OPERAND_LUA, /* A Lua function that provides the value. */
|
||||
RC_OPERAND_FUNC, /* A function that provides the value. */
|
||||
RC_OPERAND_PRIOR, /* The last differing value at this address. */
|
||||
RC_OPERAND_BCD, /* The BCD-decoded value of a live address in RAM. */
|
||||
RC_OPERAND_INVERTED, /* The twos-complement value of a live address in RAM. */
|
||||
@@ -120,16 +114,19 @@ typedef struct rc_operand_t {
|
||||
|
||||
/* A floating point value. */
|
||||
double dbl;
|
||||
|
||||
/* A reference to the Lua function that provides the value. */
|
||||
int luafunc;
|
||||
} value;
|
||||
|
||||
/* specifies which member of the value union is being used */
|
||||
/* specifies which member of the value union is being used (RC_OPERAND_*) */
|
||||
uint8_t type;
|
||||
|
||||
/* the actual RC_MEMSIZE of the operand - memref.size may differ */
|
||||
/* the RC_MEMSIZE of the operand specified in the condition definition - memref.size may differ */
|
||||
uint8_t size;
|
||||
|
||||
/* specifies how to read the memref for some types (RC_OPERAND_*) */
|
||||
uint8_t memref_access_type;
|
||||
|
||||
/* if set, this operand is combining the current condition with the previous one */
|
||||
uint8_t is_combining;
|
||||
}
|
||||
rc_operand_t;
|
||||
|
||||
@@ -141,23 +138,16 @@ RC_EXPORT int RC_CCONV rc_operand_is_memref(const rc_operand_t* operand);
|
||||
|
||||
/* types */
|
||||
enum {
|
||||
/* NOTE: this enum is ordered to optimize the switch statements in rc_test_condset_internal. the values may change between releases */
|
||||
|
||||
/* non-combining conditions (third switch) */
|
||||
RC_CONDITION_STANDARD, /* this should always be 0 */
|
||||
RC_CONDITION_PAUSE_IF,
|
||||
RC_CONDITION_RESET_IF,
|
||||
RC_CONDITION_MEASURED_IF,
|
||||
RC_CONDITION_TRIGGER,
|
||||
RC_CONDITION_MEASURED, /* measured also appears in the first switch, so place it at the border between them */
|
||||
|
||||
/* modifiers (first switch) */
|
||||
RC_CONDITION_ADD_SOURCE, /* everything from this point on affects the condition after it */
|
||||
RC_CONDITION_MEASURED,
|
||||
RC_CONDITION_ADD_SOURCE,
|
||||
RC_CONDITION_SUB_SOURCE,
|
||||
RC_CONDITION_ADD_ADDRESS,
|
||||
RC_CONDITION_REMEMBER,
|
||||
|
||||
/* logic flags (second switch) */
|
||||
RC_CONDITION_ADD_HITS,
|
||||
RC_CONDITION_SUB_HITS,
|
||||
RC_CONDITION_RESET_NEXT_IF,
|
||||
@@ -180,7 +170,10 @@ enum {
|
||||
RC_OPERATOR_XOR,
|
||||
RC_OPERATOR_MOD,
|
||||
RC_OPERATOR_ADD,
|
||||
RC_OPERATOR_SUB
|
||||
RC_OPERATOR_SUB,
|
||||
|
||||
RC_OPERATOR_SUB_PARENT, /* internal use */
|
||||
RC_OPERATOR_INDIRECT_READ /* internal use */
|
||||
};
|
||||
|
||||
typedef struct rc_condition_t rc_condition_t;
|
||||
@@ -204,10 +197,15 @@ struct rc_condition_t {
|
||||
/* The comparison operator to use. (RC_OPERATOR_*) */
|
||||
uint8_t oper; /* operator is a reserved word in C++. */
|
||||
|
||||
/* Set if the condition needs to processed as part of the "check if paused" pass. (bool) */
|
||||
uint8_t pause;
|
||||
|
||||
/* Whether or not the condition evaluated true on the last check. (bool) */
|
||||
/* Will be non-zero if the condition evaluated true on the last check.
|
||||
* - The lowest bit indicates whether the condition itself was true.
|
||||
* - The second lowest bit will only ever be set on ResetIf conditions.
|
||||
* If set, it indicates that the condition was responsible for resetting the
|
||||
* trigger. A reset clears all hit counts, so the condition may not appear to
|
||||
* be true just from looking at it (in which case the lower bit will be 0).
|
||||
* Also, the condition might have only met its required_hits target though
|
||||
* an AddHits chain which will have also been reset.
|
||||
*/
|
||||
uint8_t is_true;
|
||||
|
||||
/* Unique identifier of optimized comparator to use. (RC_PROCESSING_COMPARE_*) */
|
||||
@@ -224,17 +222,32 @@ struct rc_condset_t {
|
||||
/* The next condition set in the chain. */
|
||||
rc_condset_t* next;
|
||||
|
||||
/* The list of conditions in this condition set. */
|
||||
/* The first condition in this condition set. Then follow ->next chain. */
|
||||
rc_condition_t* conditions;
|
||||
|
||||
/* True if any condition in the set is a pause condition. */
|
||||
uint8_t has_pause;
|
||||
/* The number of pause conditions in this condition set. */
|
||||
/* The first pause condition is at "this + RC_ALIGN(sizeof(this)). */
|
||||
uint16_t num_pause_conditions;
|
||||
|
||||
/* The number of reset conditions in this condition set. */
|
||||
uint16_t num_reset_conditions;
|
||||
|
||||
/* The number of hittarget conditions in this condition set. */
|
||||
uint16_t num_hittarget_conditions;
|
||||
|
||||
/* The number of non-hittarget measured conditions in this condition set. */
|
||||
uint16_t num_measured_conditions;
|
||||
|
||||
/* The number of other conditions in this condition set. */
|
||||
uint16_t num_other_conditions;
|
||||
|
||||
/* The number of indirect conditions in this condition set. */
|
||||
uint16_t num_indirect_conditions;
|
||||
|
||||
/* True if any condition in the set is a pause condition. */
|
||||
uint8_t has_pause; /* DEPRECATED - just check num_pause_conditions != 0 */
|
||||
/* True if the set is currently paused. */
|
||||
uint8_t is_paused;
|
||||
|
||||
/* True if the set has indirect memory references. */
|
||||
uint8_t has_indirect_memrefs;
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -259,9 +272,6 @@ struct rc_trigger_t {
|
||||
/* The list of sub condition sets in this test. */
|
||||
rc_condset_t* alternative;
|
||||
|
||||
/* The memory references required by the trigger. */
|
||||
rc_memref_t* memrefs;
|
||||
|
||||
/* The current state of the MEASURED condition. */
|
||||
uint32_t measured_value;
|
||||
|
||||
@@ -274,17 +284,17 @@ struct rc_trigger_t {
|
||||
/* True if at least one condition has a non-zero hit count */
|
||||
uint8_t has_hits;
|
||||
|
||||
/* True if at least one condition has a non-zero required hit count */
|
||||
uint8_t has_required_hits;
|
||||
|
||||
/* True if the measured value should be displayed as a percentage */
|
||||
uint8_t measured_as_percent;
|
||||
|
||||
/* True if the trigger has its own rc_memrefs_t */
|
||||
uint8_t has_memrefs;
|
||||
};
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_trigger_size(const char* memaddr);
|
||||
RC_EXPORT rc_trigger_t* RC_CCONV rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
|
||||
RC_EXPORT rc_trigger_t* RC_CCONV rc_parse_trigger(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, void* unused_L);
|
||||
RC_EXPORT int RC_CCONV rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, void* unused_L);
|
||||
RC_EXPORT void RC_CCONV rc_reset_trigger(rc_trigger_t* self);
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -297,11 +307,11 @@ struct rc_value_t {
|
||||
/* The current value of the variable. */
|
||||
rc_memref_value_t value;
|
||||
|
||||
/* The list of conditions to evaluate. */
|
||||
rc_condset_t* conditions;
|
||||
/* True if the value has its own rc_memrefs_t */
|
||||
uint8_t has_memrefs;
|
||||
|
||||
/* The memory references required by the variable. */
|
||||
rc_memref_t* memrefs;
|
||||
/* The list of possible values (traverse next chain, pick max). */
|
||||
rc_condset_t* conditions;
|
||||
|
||||
/* The name of the variable. */
|
||||
const char* name;
|
||||
@@ -311,8 +321,8 @@ struct rc_value_t {
|
||||
};
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_value_size(const char* memaddr);
|
||||
RC_EXPORT rc_value_t* RC_CCONV rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
|
||||
RC_EXPORT int32_t RC_CCONV rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L);
|
||||
RC_EXPORT rc_value_t* RC_CCONV rc_parse_value(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT int32_t RC_CCONV rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, void* unused_L);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Leaderboards |
|
||||
@@ -335,14 +345,14 @@ struct rc_lboard_t {
|
||||
rc_trigger_t cancel;
|
||||
rc_value_t value;
|
||||
rc_value_t* progress;
|
||||
rc_memref_t* memrefs;
|
||||
|
||||
uint8_t state;
|
||||
uint8_t has_memrefs;
|
||||
};
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_lboard_size(const char* memaddr);
|
||||
RC_EXPORT rc_lboard_t* RC_CCONV rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_lboard(rc_lboard_t* lboard, int32_t* value, rc_peek_t peek, void* peek_ud, lua_State* L);
|
||||
RC_EXPORT rc_lboard_t* RC_CCONV rc_parse_lboard(void* buffer, const char* memaddr, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_lboard(rc_lboard_t* lboard, int32_t* value, rc_peek_t peek, void* peek_ud, void* unused_L);
|
||||
RC_EXPORT void RC_CCONV rc_reset_lboard(rc_lboard_t* lboard);
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -370,7 +380,8 @@ enum {
|
||||
RC_FORMAT_TENS,
|
||||
RC_FORMAT_HUNDREDS,
|
||||
RC_FORMAT_THOUSANDS,
|
||||
RC_FORMAT_UNSIGNED_VALUE
|
||||
RC_FORMAT_UNSIGNED_VALUE,
|
||||
RC_FORMAT_UNFORMATTED
|
||||
};
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_parse_format(const char* format_str);
|
||||
@@ -406,7 +417,7 @@ struct rc_richpresence_display_part_t {
|
||||
rc_richpresence_display_part_t* next;
|
||||
const char* text;
|
||||
rc_richpresence_lookup_t* lookup;
|
||||
rc_memref_value_t *value;
|
||||
rc_operand_t value;
|
||||
uint8_t display_type;
|
||||
};
|
||||
|
||||
@@ -416,21 +427,22 @@ struct rc_richpresence_display_t {
|
||||
rc_trigger_t trigger;
|
||||
rc_richpresence_display_t* next;
|
||||
rc_richpresence_display_part_t* display;
|
||||
uint8_t has_required_hits;
|
||||
};
|
||||
|
||||
struct rc_richpresence_t {
|
||||
rc_richpresence_display_t* first_display;
|
||||
rc_richpresence_lookup_t* first_lookup;
|
||||
rc_memref_t* memrefs;
|
||||
rc_value_t* variables;
|
||||
rc_value_t* values;
|
||||
uint8_t has_memrefs;
|
||||
};
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_richpresence_size(const char* script);
|
||||
RC_EXPORT int RC_CCONV rc_richpresence_size_lines(const char* script, int* lines_read);
|
||||
RC_EXPORT rc_richpresence_t* RC_CCONV rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, lua_State* L);
|
||||
RC_EXPORT void RC_CCONV rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, lua_State* L);
|
||||
RC_EXPORT int RC_CCONV rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, lua_State* L);
|
||||
RC_EXPORT rc_richpresence_t* RC_CCONV rc_parse_richpresence(void* buffer, const char* script, void* unused_L, int unused_funcs_idx);
|
||||
RC_EXPORT int RC_CCONV rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L);
|
||||
RC_EXPORT void RC_CCONV rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, void* unused_L);
|
||||
RC_EXPORT int RC_CCONV rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, void* unused_L);
|
||||
RC_EXPORT void RC_CCONV rc_reset_richpresence(rc_richpresence_t* self);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
Vendored
+1
-2
@@ -53,7 +53,6 @@
|
||||
<ClCompile Include="src\rc_compat.c" />
|
||||
<ClCompile Include="src\rc_util.c" />
|
||||
<ClCompile Include="src\rhash\md5.c" />
|
||||
<ClCompile Include="src\rurl\url.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\rcheevos.h" />
|
||||
@@ -80,7 +79,7 @@
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;RC_DISABLE_LUA=1;RCHEEVOS_URL_SSL=1;RC_NO_THREADS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_NONSTDC_NO_WARNINGS;RC_DISABLE_LUA=1;RCHEEVOS_URL_SSL=1;RC_NO_THREADS=1;RC_HASH_NO_DISC=1;RC_HASH_NO_ENCRYPTED=1;RC_HASH_NO_ROM=1;RC_HASH_NO_ZIP=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
|
||||
-6
@@ -4,9 +4,6 @@
|
||||
<Filter Include="rcheevos">
|
||||
<UniqueIdentifier>{0d8ef204-a486-4873-a41d-743ca6cbe840}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="rurl">
|
||||
<UniqueIdentifier>{3aa9379e-4fd1-4772-b18c-b899631a4161}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="rhash">
|
||||
<UniqueIdentifier>{c95da822-5bca-4274-b57e-d2092e76e8f1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -36,9 +33,6 @@
|
||||
<ClCompile Include="src\rhash\md5.c">
|
||||
<Filter>rhash</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\rurl\url.c">
|
||||
<Filter>rurl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\rc_client.c" />
|
||||
<ClCompile Include="src\rc_compat.c" />
|
||||
<ClCompile Include="src\rc_util.c" />
|
||||
|
||||
+123
-16
@@ -13,8 +13,7 @@
|
||||
#define RETROACHIEVEMENTS_IMAGE_HOST "https://media.retroachievements.org"
|
||||
#define RETROACHIEVEMENTS_HOST_NONSSL "http://retroachievements.org"
|
||||
#define RETROACHIEVEMENTS_IMAGE_HOST_NONSSL "http://media.retroachievements.org"
|
||||
static char* g_host = NULL;
|
||||
static char* g_imagehost = NULL;
|
||||
rc_api_host_t g_host = { NULL, NULL };
|
||||
|
||||
/* --- rc_json --- */
|
||||
|
||||
@@ -318,6 +317,18 @@ static int rc_json_convert_error_code(const char* server_error_code)
|
||||
case 'i':
|
||||
if (strcmp(server_error_code, "invalid_credentials") == 0)
|
||||
return RC_INVALID_CREDENTIALS;
|
||||
if (strcmp(server_error_code, "invalid_parameter") == 0)
|
||||
return RC_INVALID_STATE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (strcmp(server_error_code, "missing_parameter") == 0)
|
||||
return RC_INVALID_STATE;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (strcmp(server_error_code, "not_found") == 0)
|
||||
return RC_NOT_FOUND;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -696,6 +707,57 @@ int rc_json_get_string(const char** out, rc_buffer_t* buffer, const rc_json_fiel
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc_json_field_string_matches(const rc_json_field_t* field, const char* text) {
|
||||
int is_quoted = 0;
|
||||
const char* ptr = field->value_start;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
if (*ptr == '"') {
|
||||
is_quoted = 1;
|
||||
++ptr;
|
||||
}
|
||||
|
||||
while (ptr < field->value_end) {
|
||||
if (*ptr != *text) {
|
||||
if (*ptr != '\\') {
|
||||
if (*ptr == '"' && is_quoted && (*text == '\0')) {
|
||||
is_quoted = 0;
|
||||
++ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
++ptr;
|
||||
switch (*ptr) {
|
||||
case 'n':
|
||||
if (*text != '\n')
|
||||
return 0;
|
||||
break;
|
||||
case 'r':
|
||||
if (*text != '\r')
|
||||
return 0;
|
||||
break;
|
||||
case 't':
|
||||
if (*text != '\t')
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
if (*text != *ptr)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++text;
|
||||
++ptr;
|
||||
}
|
||||
|
||||
return !is_quoted && (*text == '\0');
|
||||
}
|
||||
|
||||
void rc_json_get_optional_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name, const char* default_value) {
|
||||
if (!rc_json_get_string(out, &response->buffer, field, field_name))
|
||||
*out = default_value;
|
||||
@@ -1128,21 +1190,25 @@ void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char*
|
||||
rc_url_builder_append_encoded_str(builder, value);
|
||||
}
|
||||
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request) {
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request, const rc_api_host_t* host) {
|
||||
#define DOREQUEST_ENDPOINT "/dorequest.php"
|
||||
rc_buffer_init(&request->buffer);
|
||||
|
||||
if (!g_host) {
|
||||
if (!host || !host->host) {
|
||||
request->url = RETROACHIEVEMENTS_HOST DOREQUEST_ENDPOINT;
|
||||
}
|
||||
else {
|
||||
const size_t endpoint_len = sizeof(DOREQUEST_ENDPOINT);
|
||||
const size_t host_len = strlen(g_host);
|
||||
const size_t url_len = host_len + endpoint_len;
|
||||
const size_t host_len = strlen(host->host);
|
||||
const size_t protocol_len = (strstr(host->host, "://")) ? 0 : 7;
|
||||
const size_t url_len = protocol_len + host_len + endpoint_len;
|
||||
uint8_t* url = rc_buffer_reserve(&request->buffer, url_len);
|
||||
|
||||
memcpy(url, g_host, host_len);
|
||||
memcpy(url + host_len, DOREQUEST_ENDPOINT, endpoint_len);
|
||||
if (protocol_len)
|
||||
memcpy(url, "http://", protocol_len);
|
||||
|
||||
memcpy(url + protocol_len, host->host, host_len);
|
||||
memcpy(url + protocol_len + host_len, DOREQUEST_ENDPOINT, endpoint_len);
|
||||
rc_buffer_consume(&request->buffer, url, url + url_len);
|
||||
|
||||
request->url = (char*)url;
|
||||
@@ -1165,9 +1231,9 @@ int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, c
|
||||
|
||||
/* --- Set Host --- */
|
||||
|
||||
static void rc_api_update_host(char** host, const char* hostname) {
|
||||
static void rc_api_update_host(const char** host, const char* hostname) {
|
||||
if (*host != NULL)
|
||||
free(*host);
|
||||
free((void*)*host);
|
||||
|
||||
if (hostname != NULL) {
|
||||
if (strstr(hostname, "://")) {
|
||||
@@ -1196,11 +1262,15 @@ static void rc_api_update_host(char** host, const char* hostname) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* rc_api_default_host(void) {
|
||||
return RETROACHIEVEMENTS_HOST;
|
||||
}
|
||||
|
||||
void rc_api_set_host(const char* hostname) {
|
||||
if (hostname && strcmp(hostname, RETROACHIEVEMENTS_HOST) == 0)
|
||||
hostname = NULL;
|
||||
|
||||
rc_api_update_host(&g_host, hostname);
|
||||
rc_api_update_host(&g_host.host, hostname);
|
||||
|
||||
if (!hostname) {
|
||||
/* also clear out the image hostname */
|
||||
@@ -1214,24 +1284,45 @@ void rc_api_set_host(const char* hostname) {
|
||||
}
|
||||
|
||||
void rc_api_set_image_host(const char* hostname) {
|
||||
rc_api_update_host(&g_imagehost, hostname);
|
||||
rc_api_update_host(&g_host.media_host, hostname);
|
||||
}
|
||||
|
||||
/* --- Fetch Image --- */
|
||||
|
||||
int rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params) {
|
||||
return rc_api_init_fetch_image_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_fetch_image_request_hosted(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params, const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_buffer_init(&request->buffer);
|
||||
rc_url_builder_init(&builder, &request->buffer, 64);
|
||||
|
||||
if (g_imagehost) {
|
||||
rc_url_builder_append(&builder, g_imagehost, strlen(g_imagehost));
|
||||
if (host && host->media_host) {
|
||||
/* custom media host provided */
|
||||
if (!strstr(host->host, "://"))
|
||||
rc_url_builder_append(&builder, "http://", 7);
|
||||
rc_url_builder_append(&builder, host->media_host, strlen(host->media_host));
|
||||
}
|
||||
else if (g_host) {
|
||||
rc_url_builder_append(&builder, g_host, strlen(g_host));
|
||||
else if (host && host->host) {
|
||||
if (strcmp(host->host, RETROACHIEVEMENTS_HOST_NONSSL) == 0) {
|
||||
/* if host specifically set to non-ssl host, and no media host provided, use non-ssl media host */
|
||||
rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST_NONSSL, sizeof(RETROACHIEVEMENTS_IMAGE_HOST_NONSSL) - 1);
|
||||
}
|
||||
else if (strcmp(host->host, RETROACHIEVEMENTS_HOST) == 0) {
|
||||
/* if host specifically set to ssl host, and no media host provided, use media host */
|
||||
rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST, sizeof(RETROACHIEVEMENTS_IMAGE_HOST) - 1);
|
||||
}
|
||||
else {
|
||||
/* custom host and no media host provided. assume custom host is also media host */
|
||||
if (!strstr(host->host, "://"))
|
||||
rc_url_builder_append(&builder, "http://", 7);
|
||||
rc_url_builder_append(&builder, host->host, strlen(host->host));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* no custom host provided */
|
||||
rc_url_builder_append(&builder, RETROACHIEVEMENTS_IMAGE_HOST, sizeof(RETROACHIEVEMENTS_IMAGE_HOST) - 1);
|
||||
}
|
||||
|
||||
@@ -1270,3 +1361,19 @@ int rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetc
|
||||
|
||||
return builder.result;
|
||||
}
|
||||
|
||||
const char* rc_api_build_avatar_url(rc_buffer_t* buffer, uint32_t image_type, const char* image_name) {
|
||||
rc_api_fetch_image_request_t image_request;
|
||||
rc_api_request_t request;
|
||||
int result;
|
||||
|
||||
memset(&image_request, 0, sizeof(image_request));
|
||||
image_request.image_type = image_type;
|
||||
image_request.image_name = image_name;
|
||||
|
||||
result = rc_api_init_fetch_image_request(&request, &image_request);
|
||||
if (result == RC_OK)
|
||||
return rc_buffer_strcpy(buffer, request.url);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+7
-1
@@ -24,6 +24,8 @@ void rc_url_builder_init(rc_api_url_builder_t* builder, rc_buffer_t* buffer, siz
|
||||
void rc_url_builder_append(rc_api_url_builder_t* builder, const char* data, size_t len);
|
||||
const char* rc_url_builder_finalize(rc_api_url_builder_t* builder);
|
||||
|
||||
extern rc_api_host_t g_host;
|
||||
|
||||
#define RC_JSON_NEW_FIELD(n) {NULL,NULL,n,sizeof(n)-1,0}
|
||||
|
||||
typedef struct rc_json_field_t {
|
||||
@@ -66,6 +68,7 @@ int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_fie
|
||||
int rc_json_get_array_entry_object(rc_json_field_t* fields, size_t field_count, rc_json_iterator_t* iterator);
|
||||
int rc_json_get_next_object_field(rc_json_iterator_t* iterator, rc_json_field_t* field);
|
||||
int rc_json_get_object_string_length(const char* json);
|
||||
int rc_json_field_string_matches(const rc_json_field_t* field, const char* text);
|
||||
|
||||
void rc_json_extract_filename(rc_json_field_t* field);
|
||||
|
||||
@@ -74,9 +77,12 @@ void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char*
|
||||
void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, uint32_t value);
|
||||
void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char* param, const char* value);
|
||||
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request);
|
||||
const char* rc_api_default_host(void);
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request, const rc_api_host_t* host);
|
||||
int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, const char* username, const char* api_token);
|
||||
|
||||
const char* rc_api_build_avatar_url(rc_buffer_t* buffer, uint32_t image_type, const char* image_name);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
#endif /* RC_API_COMMON_H */
|
||||
|
||||
+50
-8
@@ -11,9 +11,15 @@
|
||||
/* --- Fetch Code Notes --- */
|
||||
|
||||
int rc_api_init_fetch_code_notes_request(rc_api_request_t* request, const rc_api_fetch_code_notes_request_t* api_params) {
|
||||
return rc_api_init_fetch_code_notes_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_fetch_code_notes_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_fetch_code_notes_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->game_id == 0)
|
||||
return RC_INVALID_STATE;
|
||||
@@ -106,8 +112,14 @@ int rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_resp
|
||||
if (!rc_json_get_required_string(¬e->author, &response->response, ¬e_fields[1], "User"))
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
last_author = note->author;
|
||||
last_author_len = len;
|
||||
if (note->author == NULL) {
|
||||
/* ensure we don't pass NULL out to client */
|
||||
last_author = note->author = "";
|
||||
last_author_len = 0;
|
||||
} else {
|
||||
last_author = note->author;
|
||||
last_author_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
++note;
|
||||
@@ -124,9 +136,15 @@ void rc_api_destroy_fetch_code_notes_response(rc_api_fetch_code_notes_response_t
|
||||
/* --- Update Code Note --- */
|
||||
|
||||
int rc_api_init_update_code_note_request(rc_api_request_t* request, const rc_api_update_code_note_request_t* api_params) {
|
||||
return rc_api_init_update_code_note_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_update_code_note_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_update_code_note_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->game_id == 0)
|
||||
return RC_INVALID_STATE;
|
||||
@@ -196,12 +214,18 @@ static const char* rc_type_string(uint32_t type) {
|
||||
}
|
||||
|
||||
int rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params) {
|
||||
return rc_api_init_update_achievement_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_update_achievement_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_update_achievement_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
char buffer[33];
|
||||
md5_state_t md5;
|
||||
md5_byte_t hash[16];
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->game_id == 0 || api_params->category == 0)
|
||||
return RC_INVALID_STATE;
|
||||
@@ -290,12 +314,18 @@ void rc_api_destroy_update_achievement_response(rc_api_update_achievement_respon
|
||||
/* --- Update Leaderboard --- */
|
||||
|
||||
int rc_api_init_update_leaderboard_request(rc_api_request_t* request, const rc_api_update_leaderboard_request_t* api_params) {
|
||||
return rc_api_init_update_leaderboard_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_update_leaderboard_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_update_leaderboard_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
char buffer[33];
|
||||
md5_state_t md5;
|
||||
md5_byte_t hash[16];
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->game_id == 0)
|
||||
return RC_INVALID_STATE;
|
||||
@@ -392,9 +422,15 @@ void rc_api_destroy_update_leaderboard_response(rc_api_update_leaderboard_respon
|
||||
/* --- Fetch Badge Range --- */
|
||||
|
||||
int rc_api_init_fetch_badge_range_request(rc_api_request_t* request, const rc_api_fetch_badge_range_request_t* api_params) {
|
||||
return rc_api_init_fetch_badge_range_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_fetch_badge_range_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_fetch_badge_range_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
rc_url_builder_init(&builder, &request->buffer, 48);
|
||||
rc_url_builder_append_str_param(&builder, "r", "badgeiter");
|
||||
@@ -449,9 +485,15 @@ void rc_api_destroy_fetch_badge_range_response(rc_api_fetch_badge_range_response
|
||||
/* --- Add Game Hash --- */
|
||||
|
||||
int rc_api_init_add_game_hash_request(rc_api_request_t* request, const rc_api_add_game_hash_request_t* api_params) {
|
||||
return rc_api_init_add_game_hash_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_add_game_hash_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_add_game_hash_request_t* api_params,
|
||||
const rc_api_host_t* host) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_api_url_build_dorequest_url(request);
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->console_id == 0)
|
||||
return RC_INVALID_STATE;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user