From 3d84a9960e52ae7febba2bd52b04cc1d10c50afd Mon Sep 17 00:00:00 2001 From: Jamiras <32680403+Jamiras@users.noreply.github.com> Date: Tue, 21 Dec 2021 07:58:42 -0700 Subject: [PATCH] (cheevos) check netplay status when unlocking achievements (#13379) * check netplay status when unlocking achievements instead of permanently disabling them in spectate mode * fix c89 build * add RARCH_NETPLAY_CTL_IS_SPECTATING --- cheevos/cheevos.c | 114 +++++++++++++++-------------- cheevos/cheevos.h | 1 - network/netplay/netplay.h | 2 + network/netplay/netplay_frontend.c | 38 +++------- 4 files changed, 72 insertions(+), 83 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index bf1c049a07..b3f8ef3a41 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -285,6 +286,16 @@ static rcheevos_racheevo_t* rcheevos_find_cheevo(unsigned id) return NULL; } +static bool rcheevos_is_player_active() +{ + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SPECTATING, NULL)) + return false; + + /* TODO: disallow player slots other than player one unless it's a [Multi] set */ + + return true; +} + void rcheevos_award_achievement(rcheevos_locals_t* locals, rcheevos_racheevo_t* cheevo, bool widgets_ready) { @@ -293,9 +304,6 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals, if (!cheevo) return; - CHEEVOS_LOG(RCHEEVOS_TAG "Awarding achievement %u: %s (%s)\n", - cheevo->id, cheevo->title, cheevo->description); - /* Deactivates the acheivement. */ rc_runtime_deactivate_achievement(&locals->runtime, cheevo->id); @@ -305,6 +313,16 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals, cheevo->unlock_time = cpu_features_get_time_usec(); + if (!rcheevos_is_player_active()) + { + CHEEVOS_LOG(RCHEEVOS_TAG "Not awarding achievement %u, player not active\n", + cheevo->id); + return; + } + + CHEEVOS_LOG(RCHEEVOS_TAG "Awarding achievement %u: %s (%s)\n", + cheevo->id, cheevo->title, cheevo->description); + /* Show the on screen message. */ #if defined(HAVE_GFX_WIDGETS) if (widgets_ready) @@ -387,9 +405,23 @@ static void rcheevos_lboard_submit(rcheevos_locals_t* locals, char buffer[256]; char formatted_value[16]; +#if defined(HAVE_GFX_WIDGETS) + /* Hide the tracker */ + if (gfx_widgets_ready()) + gfx_widgets_set_leaderboard_display(lboard->id, NULL); +#endif + rc_runtime_format_lboard_value(formatted_value, sizeof(formatted_value), value, lboard->format); + + if (!rcheevos_is_player_active()) + { + CHEEVOS_LOG(RCHEEVOS_TAG "Not submitting %s for leaderboard %u, player not active\n", + formatted_value, lboard->id); + return; + } + CHEEVOS_LOG(RCHEEVOS_TAG "Submitting %s for leaderboard %u\n", formatted_value, lboard->id); @@ -399,12 +431,6 @@ static void rcheevos_lboard_submit(rcheevos_locals_t* locals, runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); -#if defined(HAVE_GFX_WIDGETS) - /* Hide the tracker */ - if (gfx_widgets_ready()) - gfx_widgets_set_leaderboard_display(lboard->id, NULL); -#endif - /* Start the submit task */ rcheevos_client_submit_lboard_entry(lboard->id, value); } @@ -444,6 +470,9 @@ static void rcheevos_lboard_started( CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard %u started: %s\n", lboard->id, lboard->title); + if (!rcheevos_is_player_active()) + return; + #if defined(HAVE_GFX_WIDGETS) if (widgets_ready && rcheevos_locals.leaderboard_trackers) { @@ -482,7 +511,8 @@ static void rcheevos_lboard_updated( char buffer[32]; rc_runtime_format_lboard_value(buffer, sizeof(buffer), value, lboard->format); - gfx_widgets_set_leaderboard_display(lboard->id, buffer); + gfx_widgets_set_leaderboard_display(lboard->id, + rcheevos_is_player_active() ? buffer : NULL); } } @@ -493,7 +523,8 @@ static void rcheevos_challenge_started( settings_t* settings = config_get_ptr(); if ( cheevo && widgets_ready - && settings->bools.cheevos_challenge_indicators) + && settings->bools.cheevos_challenge_indicators + && rcheevos_is_player_active()) gfx_widgets_set_challenge_display(cheevo->id, cheevo->badge); } @@ -509,13 +540,23 @@ static void rcheevos_challenge_ended( int rcheevos_get_richpresence(char buffer[], int buffer_size) { - int ret = rc_runtime_get_richpresence( - &rcheevos_locals.runtime, buffer, buffer_size, - &rcheevos_peek, NULL, NULL); + if (rcheevos_is_player_active()) + { + int ret = rc_runtime_get_richpresence( + &rcheevos_locals.runtime, buffer, buffer_size, + &rcheevos_peek, NULL, NULL); - if (ret <= 0 && rcheevos_locals.game.title) - return snprintf(buffer, buffer_size, "Playing %s", rcheevos_locals.game.title); - return ret; + if (ret <= 0 && rcheevos_locals.game.title) + return snprintf(buffer, buffer_size, "Playing %s", rcheevos_locals.game.title); + return ret; + } + else + { + if (rcheevos_locals.game.title) + return snprintf(buffer, buffer_size, "Spectating %s", rcheevos_locals.game.title); + + return 0; + } } void rcheevos_reset_game(bool widgets_ready) @@ -1971,42 +2012,3 @@ void rcheevos_change_disc(const char* new_disc_path, bool initial_disc) initial_disc ? rcheevos_identify_initial_disc_callback : rcheevos_identify_game_disc_callback, hash_entry); } - -void rcheevos_validate_netplay(int player_num) -{ - const char* msg = NULL; - - if (rcheevos_locals.load_info.state == RCHEEVOS_LOAD_STATE_NONE) - { - /* already disabled or game doesn't have achievements, nothing to do */ - return; - } - - if (player_num == 1) - { - /* always allow player 1 */ - return; - } - else if (player_num == 0) - { - /* spectating, never allow achievements */ - msg = "Disabling achievements for netplay spectator mode."; - } - else - { - /* non-primary player, only allow for multi sets (TODO) */ - return; - } - - /* if there are active achievements, inform the user about the deactivation */ - if (rcheevos_locals.loaded && rcheevos_locals.game.achievement_count > 0) - { - runloop_msg_queue_push(msg, 0, 3 * 60, false, NULL, - MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - } - - /* disable the achievement runtime */ - CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", msg); - rcheevos_unload(); -} - diff --git a/cheevos/cheevos.h b/cheevos/cheevos.h index b677fa2876..53b0aaa93e 100644 --- a/cheevos/cheevos.h +++ b/cheevos/cheevos.h @@ -44,7 +44,6 @@ void rcheevos_toggle_hardcore_paused(void); bool rcheevos_hardcore_active(void); void rcheevos_validate_config_settings(void); -void rcheevos_validate_netplay(int player_number); void rcheevos_leaderboards_enabled_changed(void); diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 9c3f97b311..50ca948f4d 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -62,6 +62,8 @@ enum rarch_netplay_ctl_state RARCH_NETPLAY_CTL_IS_REPLAYING, RARCH_NETPLAY_CTL_IS_SERVER, RARCH_NETPLAY_CTL_IS_CONNECTED, + RARCH_NETPLAY_CTL_IS_PLAYING, + RARCH_NETPLAY_CTL_IS_SPECTATING, RARCH_NETPLAY_CTL_IS_DATA_INITED, RARCH_NETPLAY_CTL_ALLOW_PAUSE, RARCH_NETPLAY_CTL_PAUSE, diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 2dbc450911..d39769d63f 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -79,10 +79,6 @@ #include "../discord.h" #endif -#ifdef HAVE_CHEEVOS -#include "../cheevos/cheevos.h" -#endif - #include "netplay.h" #include "netplay_private.h" @@ -1925,10 +1921,6 @@ static bool netplay_handshake_pre_sync(netplay_t *netplay, settings_t *settings = config_get_ptr(); if (!settings->bools.netplay_start_as_spectator) return netplay_cmd_mode(netplay, NETPLAY_CONNECTION_PLAYING); -#ifdef HAVE_CHEEVOS - else /* staying in SPECTATING mode, disable achievements */ - rcheevos_validate_netplay(0); -#endif } return true; @@ -4407,10 +4399,6 @@ static void announce_play_spectate(netplay_t *netplay, else { dmsg = msg_hash_to_str(MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME); - -#ifdef HAVE_CHEEVOS - rcheevos_validate_netplay(0); -#endif } break; @@ -4449,10 +4437,6 @@ static void announce_play_spectate(netplay_t *netplay, msg_hash_to_str( MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N), one_device + 1); - -#ifdef HAVE_CHEEVOS - rcheevos_validate_netplay(one_device + 1); -#endif } else { @@ -4469,10 +4453,6 @@ static void announce_play_spectate(netplay_t *netplay, (pdevice_str - device_str), "%u, ", (unsigned) (device+1)); - -#ifdef HAVE_CHEEVOS - rcheevos_validate_netplay(device + 1); -#endif } } @@ -5570,12 +5550,6 @@ static bool netplay_get_cmd(netplay_t *netplay, RARCH_LOG("[Netplay] %s\n", dmsg); runloop_msg_queue_push(dmsg, 1, 180, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - -#ifdef HAVE_CHEEVOS - /* unable to switch to PLAY mode, disable achievements while spectating */ - if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) - rcheevos_validate_netplay(0); -#endif } break; @@ -8405,6 +8379,11 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) ret = false; goto done; + case RARCH_NETPLAY_CTL_IS_SPECTATING: + case RARCH_NETPLAY_CTL_IS_PLAYING: + ret = false; + goto done; + default: goto done; } @@ -8431,6 +8410,13 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_IS_CONNECTED: ret = netplay->is_connected; goto done; + case RARCH_NETPLAY_CTL_IS_SPECTATING: + ret = netplay->self_mode == NETPLAY_CONNECTION_SPECTATING; + break; + case RARCH_NETPLAY_CTL_IS_PLAYING: + ret = netplay->self_mode == NETPLAY_CONNECTION_PLAYING || + netplay->self_mode == NETPLAY_CONNECTION_SLAVE; + break; case RARCH_NETPLAY_CTL_POST_FRAME: netplay_post_frame(netplay); /* If we're disconnected, deinitialize */