diff --git a/.vscode/settings.json b/.vscode/settings.json index 345f8a0f8e..3b105d2389 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,6 +14,11 @@ "*.in": "c", "*.rh": "c", "array": "c", + "file_stream.h": "c", + "driver.h": "c", + "iosfwd": "c", + "xlocbuf": "c", + "xmemory0": "c" }, "C_Cpp.dimInactiveRegions": false, } \ No newline at end of file diff --git a/command.c b/command.c index 40f6310c3e..bce0de04c3 100644 --- a/command.c +++ b/command.c @@ -98,6 +98,8 @@ #define DEFAULT_NETWORK_CMD_PORT 55355 #define STDIN_BUF_SIZE 4096 +extern bool discord_is_inited; + enum cmd_source_t { CMD_NONE = 0, @@ -1980,6 +1982,15 @@ bool command_event(enum event_command cmd, void *data) core_unload_game(); if (!rarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL)) core_unload(); +#ifdef HAVE_DISCORD + if (discord_is_inited) + { + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_MENU; + + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); + } +#endif } break; case CMD_EVENT_QUIT: diff --git a/discord/discord.c b/discord/discord.c index 8e1ba00e70..0a33824fa5 100644 --- a/discord/discord.c +++ b/discord/discord.c @@ -25,21 +25,33 @@ #include "../msg_hash.h" +#ifdef HAVE_NETWORKING +#include "../../network/netplay/netplay.h" +#include "../../network/netplay/netplay_discovery.h" +#include "../../tasks/tasks_internal.h" +#endif + +#ifdef HAVE_CHEEVOS +#include "../cheevos/cheevos.h" +#endif + static const char* APPLICATION_ID = "475456035851599874"; static int FrustrationLevel = 0; static int64_t start_time = 0; static int64_t pause_time = 0; +static int64_t ellapsed_time = 0; static bool discord_ready = false; -static bool in_menu = false; static unsigned discord_status = 0; +struct netplay_room *room; + DiscordRichPresence discord_presence; static void handle_discord_ready(const DiscordUser* connectedUser) { - RARCH_LOG("[Discord] connected to user %s#%s - %s\n", + RARCH_LOG("[Discord] connected to user: %s#%s - avatar id: %s\n", connectedUser->username, connectedUser->discriminator, connectedUser->userId); @@ -58,6 +70,21 @@ static void handle_discord_error(int errcode, const char* message) static void handle_discord_join(const char* secret) { RARCH_LOG("[Discord] join (%s)\n", secret); + static struct string_list *list = NULL; + list = string_split(secret, "|"); + + char tmp_hostname[32]; + snprintf(tmp_hostname, + sizeof(tmp_hostname), + "%s|%s", list->elems[0].data, list->elems[1].data); + + if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) + deinit_netplay(); + netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL); + + task_push_netplay_crc_scan(atoi(list->elems[3].data), + list->elems[2].data, + tmp_hostname, list->elems[4].data); } static void handle_discord_spectate(const char* secret) @@ -78,19 +105,17 @@ static void handle_discord_join_request(const DiscordUser* request) void discord_update(enum discord_presence presence) { core_info_t *core_info = NULL; - bool skip = false; core_info_get_current_core(&core_info); if (!discord_ready) return; - if ( - (discord_status != DISCORD_PRESENCE_MENU) && - (discord_status == presence)) + if (presence == discord_status) return; - memset(&discord_presence, 0, sizeof(discord_presence)); + if (presence == DISCORD_PRESENCE_NONE || presence == DISCORD_PRESENCE_MENU) + memset(&discord_presence, 0, sizeof(discord_presence)); switch (presence) { @@ -99,19 +124,15 @@ void discord_update(enum discord_presence presence) discord_presence.largeImageKey = "base"; discord_presence.largeImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE); discord_presence.instance = 0; - - in_menu = true; break; case DISCORD_PRESENCE_GAME_PAUSED: discord_presence.smallImageKey = "paused"; discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED); discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED); - pause_time = time(0); - skip = true; - - if (in_menu) - break; + ellapsed_time = difftime(time(0), start_time); + discord_presence.startTimestamp = pause_time; + break; case DISCORD_PRESENCE_GAME: if (core_info) { @@ -126,7 +147,7 @@ void discord_update(enum discord_presence presence) if (!label) label = (char *)path_basename(path_get(RARCH_PATH_BASENAME)); -#if 1 +#if 0 RARCH_LOG("[Discord] current core: %s\n", system_id); RARCH_LOG("[Discord] current content: %s\n", label); #endif @@ -135,39 +156,57 @@ void discord_update(enum discord_presence presence) if (core_info->display_name) discord_presence.largeImageText = core_info->display_name; - if (in_menu) - start_time = time(0); - else - start_time = start_time + difftime(time(0), pause_time); + start_time = time(0); + if (pause_time != 0) + start_time = time(0) - ellapsed_time; - if (!skip) - { - discord_presence.smallImageKey = "playing"; - discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING); - discord_presence.startTimestamp = start_time; - discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME); - } + pause_time = 0; + ellapsed_time = 0; + + discord_presence.smallImageKey = "playing"; + discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING); + discord_presence.startTimestamp = start_time; + discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME); discord_presence.state = label; discord_presence.instance = 0; } - - in_menu = false; break; case DISCORD_PRESENCE_NETPLAY_HOSTING: + room = netplay_get_host_room(); + if (room->id == 0) + return; + + RARCH_LOG("[Discord] netplay room details: id=%d, nick=%s IP=%s port=%d\n", + room->id, room->nickname, + room->host_method == NETPLAY_HOST_METHOD_MITM ? room->mitm_address : room->address, + room->host_method == NETPLAY_HOST_METHOD_MITM ? room->mitm_port : room->port); + + char party_id[128]; + snprintf(party_id, sizeof(party_id), "%d|%s", room->id, room->nickname); + char join_secret[128]; + snprintf(join_secret, sizeof(join_secret), "%s|%d|%s|%u|%s", + room->host_method == NETPLAY_HOST_METHOD_MITM ? room->mitm_address : room->address, + room->host_method == NETPLAY_HOST_METHOD_MITM ? room->mitm_port : room->port, + room->gamename, room->gamecrc, room->corename); + RARCH_LOG("%s\n", join_secret); + discord_presence.joinSecret = strdup(join_secret); + discord_presence.spectateSecret = "SPECSPECSPEC"; + discord_presence.partyId = party_id; + discord_presence.partyMax = 0; + discord_presence.partySize = 0; + break; + case DISCORD_PRESENCE_NETPLAY_HOSTING_STOPPED: case DISCORD_PRESENCE_NETPLAY_CLIENT: - case DISCORD_PRESENCE_CHEEVO_UNLOCKED: - /* TODO/FIXME */ + default: + discord_presence.joinSecret = NULL; break; } - if (in_menu && skip) - return; - RARCH_LOG("[Discord] updating (%d)\n", presence); Discord_UpdatePresence(&discord_presence); - discord_status = presence; + discord_status = presence; } void discord_init(void) @@ -197,3 +236,8 @@ void discord_shutdown(void) Discord_Shutdown(); discord_ready = false; } + +void discord_run_callbacks() +{ + Discord_RunCallbacks(); +} \ No newline at end of file diff --git a/discord/discord.h b/discord/discord.h index 84aa87f8ad..8148482d54 100644 --- a/discord/discord.h +++ b/discord/discord.h @@ -32,11 +32,13 @@ enum discord_presence { - DISCORD_PRESENCE_MENU = 0, + DISCORD_PRESENCE_NONE = 0, + DISCORD_PRESENCE_MENU, DISCORD_PRESENCE_GAME, DISCORD_PRESENCE_GAME_PAUSED, DISCORD_PRESENCE_CHEEVO_UNLOCKED, DISCORD_PRESENCE_NETPLAY_HOSTING, + DISCORD_PRESENCE_NETPLAY_HOSTING_STOPPED, DISCORD_PRESENCE_NETPLAY_CLIENT }; @@ -51,4 +53,6 @@ void discord_shutdown(void); void discord_update(enum discord_presence presence); +void discord_run_callbacks(); + #endif /* __RARCH_DISCORD_H */ diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 0ae873fc26..0ad73495ef 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -471,16 +471,17 @@ bool menu_display_libretro(bool is_idle, return true; } -#ifdef HAVE_DISCORD - discord_userdata_t userdata; - userdata.status = DISCORD_PRESENCE_GAME_PAUSED; - - command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); -#endif - if (is_idle) + { +#ifdef HAVE_DISCORD + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_GAME_PAUSED; + + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); +#endif return true; /* Maybe return false here for indication of idleness? */ + } return video_driver_cached_frame(); } diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 19775f5f0e..c0981d7067 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -26,6 +26,10 @@ #include #include +#ifdef HAVE_DISCORD +#include +#endif + #include #include "netplay_discovery.h" @@ -60,6 +64,10 @@ static bool is_mitm = false; static bool netplay_disconnect(netplay_t *netplay); +#ifdef HAVE_DISCORD +extern bool discord_is_inited; +#endif + /** * netplay_is_alive: * @netplay : pointer to netplay object @@ -632,6 +640,15 @@ static void netplay_announce_cb(void *task_data, void *user_data, const char *er { RARCH_LOG("[netplay] announcing netplay game... \n"); +#ifdef HAVE_DISCORD + if (discord_is_inited) + { + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_NETPLAY_HOSTING; + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); + } +#endif + if (task_data) { unsigned i, ip_len, port_len; @@ -1499,6 +1516,14 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_DISABLE: netplay_enabled = false; +#ifdef HAVE_DISCORD + if (discord_is_inited) + { + discord_userdata_t userdata; + userdata.status = DISCORD_PRESENCE_NETPLAY_HOSTING_STOPPED; + command_event(CMD_EVENT_DISCORD_UPDATE, &userdata); + } +#endif goto done; case RARCH_NETPLAY_CTL_IS_ENABLED: @@ -1517,6 +1542,7 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_IS_CONNECTED: ret = false; goto done; + default: goto done; } diff --git a/retroarch.c b/retroarch.c index 6b49f0e41c..3573b206ed 100644 --- a/retroarch.c +++ b/retroarch.c @@ -204,7 +204,7 @@ static retro_bits_t has_set_libretro_device; static bool has_set_core = false; static bool has_set_username = false; #ifdef HAVE_DISCORD -static bool discord_is_inited = false; +bool discord_is_inited = false; #endif static bool rarch_is_inited = false; static bool rarch_error_on_init = false; @@ -3357,6 +3357,13 @@ int runloop_iterate(unsigned *sleep_ms) settings_t *settings = config_get_ptr(); unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + if (discord_is_inited) + { +#ifdef HAVE_DISCORD + discord_run_callbacks(); +#endif + } + if (runloop_frame_time.callback) { /* Updates frame timing if frame timing callback is in use by the core. @@ -3452,7 +3459,6 @@ int runloop_iterate(unsigned *sleep_ms) if (runloop_check_cheevos()) cheevos_test(); #endif - cheat_manager_apply_retro_cheats() ; #ifdef HAVE_DISCORD