From 224bd2df1dd2138438c539ed88293be7ed685d39 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Tue, 21 Apr 2026 04:57:41 -0600 Subject: [PATCH] clean up RA variables (#789) * clean up RA variables * more * more * more * more * more * more * more * more * more * more * more * more * more --- build.rs | 1 - retroachievements/retroachievements.c | 112 ++++++++---------------- retroachievements/retroachievements.h | 1 - src/main.rs | 19 ++-- src/retroachievements.rs | 31 +++---- src/ui/gui.rs | 4 +- src/ui/gui/appwindow.slint | 6 +- src/ui/gui/retroachievements_page.slint | 4 +- src/ui/retroachievements.rs | 14 +-- 9 files changed, 77 insertions(+), 115 deletions(-) diff --git a/build.rs b/build.rs index 8d6e099..557a371 100644 --- a/build.rs +++ b/build.rs @@ -182,7 +182,6 @@ fn main() { if cfg!(feature = "gui") { retroachievements_builder = retroachievements_builder .allowlist_function("ra_logout_user") - .allowlist_function("ra_is_user_logged_in") .allowlist_function("ra_get_username") .allowlist_function("ra_get_token"); } diff --git a/retroachievements/retroachievements.c b/retroachievements/retroachievements.c index b8ff96e..1588629 100644 --- a/retroachievements/retroachievements.c +++ b/retroachievements/retroachievements.c @@ -18,13 +18,8 @@ void notify_load_game(void *userdata); static rc_client_t *g_client = NULL; static const uint8_t *g_dmem = NULL; static size_t g_dmem_size = 0; -static bool g_game_loaded = false; -static bool g_user_logged_in = false; static bool g_challenge = false; static bool g_leaderboard = false; -static const char *g_username = NULL; -static const char *g_token = NULL; -static char load_game_error_message[512]; static rc_client_leaderboard_list_t *g_leaderboard_list = NULL; static uint32_t read_memory(uint32_t address, uint8_t *buffer, @@ -73,42 +68,31 @@ static void login_callback(int result, const char *error_message, rc_client_t *client, void *userdata) { // If not successful, just report the error and bail. if (result != RC_OK) { - snprintf(load_game_error_message, sizeof(load_game_error_message), - "RA login failed: %s", error_message); store_retroachievements_credentials(NULL, NULL, userdata); return; - } else { - memset(load_game_error_message, 0, sizeof(load_game_error_message)); } // Login was successful. Capture the token for future logins so we don't have // to store the password anywhere. const rc_client_user_t *user = rc_client_get_user_info(client); store_retroachievements_credentials(user->username, user->token, userdata); - - g_username = user->username; - g_token = user->token; - g_user_logged_in = true; } -bool ra_is_user_logged_in() { return g_user_logged_in; } - -const char *ra_get_username() { return g_username; } -const char *ra_get_token() { return g_token; } - -void ra_logout_user() { - g_user_logged_in = false; - g_game_loaded = false; - g_username = NULL; - g_token = NULL; - rc_client_logout(g_client); +const char *ra_get_username() { + const rc_client_user_t *user = rc_client_get_user_info(g_client); + return user ? user->username : NULL; } +const char *ra_get_token() { + const rc_client_user_t *user = rc_client_get_user_info(g_client); + return user ? user->token : NULL; +} + +void ra_logout_user() { rc_client_logout(g_client); } void ra_login_user(const char *username, const char *password, void *userdata) { // This will generate an HTTP payload and call the server_call chain above. // Eventually, login_callback will be called to let us know if the login was // successful. - g_user_logged_in = false; rc_client_begin_login_with_password(g_client, username, password, login_callback, userdata); } @@ -118,7 +102,6 @@ void ra_login_token_user(const char *username, const char *token, // This is exactly the same functionality as // rc_client_begin_login_with_password, but uses the token captured from the // first login instead of a password. Note that it uses the same callback. - g_user_logged_in = false; rc_client_begin_login_with_token(g_client, username, token, login_callback, userdata); } @@ -127,12 +110,8 @@ static void load_game_callback(int result, const char *error_message, rc_client_t *client, void *userdata) { if (result != RC_OK) { rc_client_set_hardcore_enabled(client, false); - snprintf(load_game_error_message, sizeof(load_game_error_message), - "RA load failed: %s", error_message); notify_load_game(userdata); return; - } else { - memset(load_game_error_message, 0, sizeof(load_game_error_message)); } if (!rc_client_is_processing_required(client)) { @@ -142,20 +121,29 @@ static void load_game_callback(int result, const char *error_message, g_leaderboard_list = rc_client_create_leaderboard_list( client, RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE); - g_game_loaded = true; notify_load_game(userdata); } void ra_welcome() { - if (strlen(load_game_error_message) > 0) { - rdp_onscreen_message(load_game_error_message, true); - } - if (!g_game_loaded) + if (!g_client) return; char buffer[512]; + if (!rc_client_get_user_info(g_client)) { + snprintf(buffer, sizeof(buffer), "RA login failed"); + rdp_onscreen_message(buffer, true); + return; + } + const rc_client_game_t *game = rc_client_get_game_info(g_client); + + if (!game) { + snprintf(buffer, sizeof(buffer), "RA load failed"); + rdp_onscreen_message(buffer, true); + return; + } + rc_client_user_game_summary_t summary; rc_client_get_user_game_summary(g_client, &summary); @@ -175,22 +163,17 @@ void ra_welcome() { } void ra_load_game(const uint8_t *rom, size_t rom_size, void *userdata) { - if (!g_user_logged_in) { - notify_load_game(userdata); - return; - } - rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_NINTENDO_64, NULL, rom, rom_size, load_game_callback, userdata); } void ra_unload_game() { - if (!g_game_loaded) - return; - + if (g_leaderboard_list) { + rc_client_destroy_leaderboard_list(g_leaderboard_list); + g_leaderboard_list = NULL; + } rc_client_unload_game(g_client); - g_game_loaded = false; } void ra_set_dmem(const uint8_t *dmem, size_t dmem_size) { @@ -332,8 +315,6 @@ void ra_init_client(bool hardcore, bool challenge, bool leaderboard) { // Create the client instance (using a global variable simplifies this // example) g_client = rc_client_create(read_memory, server_call); - g_game_loaded = false; - g_user_logged_in = false; g_dmem = NULL; g_dmem_size = 0; @@ -348,17 +329,9 @@ void ra_init_client(bool hardcore, bool challenge, bool leaderboard) { g_leaderboard = leaderboard; } -bool ra_get_hardcore() { - if (!g_user_logged_in) - return false; - return rc_client_get_hardcore_enabled(g_client); -} +bool ra_get_hardcore() { return rc_client_get_hardcore_enabled(g_client); } void ra_shutdown_client() { - if (g_leaderboard_list) { - rc_client_destroy_leaderboard_list(g_leaderboard_list); - g_leaderboard_list = NULL; - } if (g_client) { // Release resources associated to the client instance rc_client_destroy(g_client); @@ -366,30 +339,16 @@ void ra_shutdown_client() { } } -void ra_do_frame() { - if (!g_game_loaded) - return; +void ra_do_frame() { rc_client_do_frame(g_client); } - rc_client_do_frame(g_client); -} +void ra_do_idle() { rc_client_idle(g_client); } -void ra_do_idle() { - if (!g_game_loaded) - return; - - rc_client_idle(g_client); -} - -size_t ra_state_size() { - if (!g_game_loaded) - return 0; - - return rc_client_progress_size(g_client); -} +size_t ra_state_size() { return rc_client_progress_size(g_client); } void ra_save_state(uint8_t *state, size_t state_size) { - if (!g_game_loaded) + if (!rc_client_is_game_loaded(g_client)) return; + if (rc_client_serialize_progress_sized(g_client, state, state_size) != RC_OK) { printf("RetroAchievements: Failed to serialize progress\n"); @@ -397,8 +356,9 @@ void ra_save_state(uint8_t *state, size_t state_size) { } void ra_load_state(const uint8_t *state, size_t state_size) { - if (!g_game_loaded) + if (!rc_client_is_game_loaded(g_client)) return; + if (rc_client_deserialize_progress_sized(g_client, state, state_size) != RC_OK) { printf("RetroAchievements: Failed to deserialize progress\n"); @@ -406,7 +366,7 @@ void ra_load_state(const uint8_t *state, size_t state_size) { } void ra_display_inprogress_achievements(void *userdata) { - if (!g_game_loaded) + if (!rc_client_is_game_loaded(g_client)) return; rc_client_achievement_list_t *list = rc_client_create_achievement_list( diff --git a/retroachievements/retroachievements.h b/retroachievements/retroachievements.h index 5b28287..4d4fe40 100644 --- a/retroachievements/retroachievements.h +++ b/retroachievements/retroachievements.h @@ -17,7 +17,6 @@ void ra_logout_user(); void ra_login_user(const char *username, const char *password, void *userdata); void ra_login_token_user(const char *username, const char *token, void *userdata); -bool ra_is_user_logged_in(); const char *ra_get_username(); const char *ra_get_token(); size_t ra_state_size(); diff --git a/src/main.rs b/src/main.rs index 6de811d..a9b327c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -168,15 +168,6 @@ async fn main() -> std::io::Result<()> { .unwrap_or_default() }; - if cfg!(ra_hardcore_enabled) { - retroachievements::init_client( - args.ra_hardcore, - args.ra_challenge, - args.ra_leaderboard, - ); - } else { - retroachievements::init_client(false, args.ra_challenge, args.ra_leaderboard); - } let mut shutdown_tx = None; if let Some(peer_addr) = args.netplay_peer_addr @@ -201,6 +192,16 @@ async fn main() -> std::io::Result<()> { } if let Some(username) = args.ra_username { + retroachievements::init_client( + if cfg!(ra_hardcore_enabled) { + args.ra_hardcore + } else { + false + }, + args.ra_challenge, + args.ra_leaderboard, + ); + let (tx, rx) = tokio::sync::oneshot::channel::(); if let Some(password) = args.ra_password { retroachievements::login_user(username, password, tx); diff --git a/src/retroachievements.rs b/src/retroachievements.rs index b65bc30..154a542 100644 --- a/src/retroachievements.rs +++ b/src/retroachievements.rs @@ -208,31 +208,32 @@ pub fn login_token_user(username: String, token: String, tx: tokio::sync::onesho } #[cfg(feature = "gui")] -pub fn is_user_logged_in() -> bool { - unsafe { ra_is_user_logged_in() } -} - -#[cfg(feature = "gui")] -pub fn get_username() -> &'static str { +pub fn get_username() -> Option { let c_username = unsafe { ra_get_username() }; if c_username.is_null() { - "unknown" + None } else { - unsafe { std::ffi::CStr::from_ptr(c_username) } - .to_str() - .unwrap() + Some( + unsafe { std::ffi::CStr::from_ptr(c_username) } + .to_str() + .unwrap() + .to_string(), + ) } } #[cfg(feature = "gui")] -pub fn get_token() -> &'static str { +pub fn get_token() -> Option { let c_token = unsafe { ra_get_token() }; if c_token.is_null() { - "unknown" + None } else { - unsafe { std::ffi::CStr::from_ptr(c_token) } - .to_str() - .unwrap() + Some( + unsafe { std::ffi::CStr::from_ptr(c_token) } + .to_str() + .unwrap() + .to_string(), + ) } } diff --git a/src/ui/gui.rs b/src/ui/gui.rs index 0bca1c6..607a9ae 100644 --- a/src/ui/gui.rs +++ b/src/ui/gui.rs @@ -509,9 +509,9 @@ pub fn run_rom( if ra_settings.enabled { command.args([ "--ra-username", - retroachievements::get_username(), + &retroachievements::get_username().unwrap_or("unknown".into()), "--ra-token", - retroachievements::get_token(), + &retroachievements::get_token().unwrap_or("unknown".into()), ]); if ra_settings.hardcore { command.args(["--ra-hardcore"]); diff --git a/src/ui/gui/appwindow.slint b/src/ui/gui/appwindow.slint index d49ec45..422d523 100644 --- a/src/ui/gui/appwindow.slint +++ b/src/ui/gui/appwindow.slint @@ -39,7 +39,7 @@ export component AppWindow inherits Window { callback cheat_toggled(string, string, string, bool); callback ra_button_clicked(string); callback ra_games_clicked; - callback ra_show_profile_clicked(string); + callback ra_show_profile_clicked; callback ra_toggled(bool,bool,bool,bool); in property version <=> AboutData.version; in property has_update <=> AboutData.has_update; @@ -154,8 +154,8 @@ export component AppWindow inherits Window { ra_games_clicked => { ra_games_clicked(); } - ra_show_profile_clicked(username) => { - ra_show_profile_clicked(username); + ra_show_profile_clicked => { + ra_show_profile_clicked(); } } if(side-bar.current-item == 5): Settings { } diff --git a/src/ui/gui/retroachievements_page.slint b/src/ui/gui/retroachievements_page.slint index 498f323..a73f7b8 100644 --- a/src/ui/gui/retroachievements_page.slint +++ b/src/ui/gui/retroachievements_page.slint @@ -20,7 +20,7 @@ export component RetroAchievements inherits Page { callback ra_button_clicked(string); callback ra_toggled(bool,bool,bool,bool); callback ra_games_clicked; - callback ra_show_profile_clicked(string); + callback ra_show_profile_clicked; title: @tr("RetroAchievements"); VerticalBox { @@ -89,7 +89,7 @@ export component RetroAchievements inherits Page { enabled: RAData.enabled; text: @tr("View Profile"); clicked => { - ra_show_profile_clicked(RAData.ra_username); + ra_show_profile_clicked(); } } } diff --git a/src/ui/retroachievements.rs b/src/ui/retroachievements.rs index f888038..2645131 100644 --- a/src/ui/retroachievements.rs +++ b/src/ui/retroachievements.rs @@ -86,8 +86,12 @@ pub fn ra_window(app: &ui::gui::AppWindow) { open::that_detached("https://retroachievements.org/system/2-nintendo-64/games").unwrap(); }); - app.on_ra_show_profile_clicked(move |username| { - open::that_detached(format!("https://retroachievements.org/user/{}", username)).unwrap(); + app.on_ra_show_profile_clicked(move || { + open::that_detached(format!( + "https://retroachievements.org/user/{}", + retroachievements::get_username().unwrap_or_default() + )) + .unwrap(); }); } @@ -98,10 +102,8 @@ fn set_current_user_message(app: &ui::gui::AppWindow, rx: tokio::sync::oneshot:: rx.await.unwrap(); weak_app .upgrade_in_event_loop(move |handle| { - if retroachievements::is_user_logged_in() { - handle.set_ra_current_user_message( - format!("Logged in as {}", handle.get_ra_username()).into(), - ); + if let Some(username) = retroachievements::get_username() { + handle.set_ra_current_user_message(format!("Logged in as {}", username).into()); handle.set_ra_show_profile(true); } else { handle.set_ra_current_user_message("Login failed".into());