(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
This commit is contained in:
Jamiras 2021-12-21 07:58:42 -07:00 committed by GitHub
parent 966335e367
commit 3d84a9960e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 83 deletions

View File

@ -28,6 +28,7 @@
#include <retro_math.h>
#include <retro_timers.h>
#include <net/net_http.h>
#include <network/netplay/netplay.h>
#include <libretro.h>
#include <lrc_hash.h>
@ -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();
}

View File

@ -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);

View File

@ -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,

View File

@ -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 */