diff --git a/Makefile b/Makefile index f7070a40..9da5fadc 100644 --- a/Makefile +++ b/Makefile @@ -48,9 +48,7 @@ EXT_OPTIONS_MENU ?= 1 TEXTSAVES ?= 0 # Load resources from external files EXTERNAL_DATA ?= 0 -# Enable Discord Rich Presence (outdated, no longer supported) -DISCORDRPC ?= 0 -# Enable Discord Game SDK (used for Discord server hosting) +# Enable Discord Game SDK (used for Discord invites) DISCORD_SDK ?= 1 # Enable CoopNet SDK (used for CoopNet server hosting) COOPNET ?= 1 @@ -530,12 +528,8 @@ BIN_DIRS := bin bin/$(VERSION) # PC files SRC_DIRS += src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/mods src/pc/network src/pc/network/packets src/pc/network/socket src/pc/network/coopnet src/pc/utils src/pc/utils/miniz src/pc/djui src/pc/lua src/pc/lua/utils -#ifeq ($(DISCORDRPC),1) -# SRC_DIRS += src/pc/discord -#endif - ifeq ($(DISCORD_SDK),1) - SRC_DIRS += src/pc/network/discord + SRC_DIRS += src/pc/discord endif ULTRA_SRC_DIRS := lib/src lib/src/math lib/asm lib/data @@ -607,18 +601,8 @@ ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \ GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) RPC_LIBS := -#ifeq ($(DISCORDRPC),1) -# ifeq ($(WINDOWS_BUILD),1) -# RPC_LIBS := lib/discord/libdiscord-rpc.dll -# else ifeq ($(OSX_BUILD),1) -# # needs testing -# RPC_LIBS := lib/discord/libdiscord-rpc.dylib -# else -# RPC_LIBS := lib/discord/libdiscord-rpc.so -# endif -#endif - DISCORD_SDK_LIBS := + ifeq ($(DISCORD_SDK), 1) ifeq ($(WINDOWS_BUILD),1) ifeq ($(TARGET_BITS), 32) @@ -758,7 +742,6 @@ else CP := cp endif -#ifeq ($(DISCORDRPC),1) ifeq ($(DISCORD_SDK),1) LD := $(CXX) else ifeq ($(WINDOWS_BUILD),1) @@ -923,9 +906,6 @@ else ifeq ($(OSX_BUILD),1) LDFLAGS := -lm $(BACKEND_LDFLAGS) -lpthread else LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread -# ifeq ($(DISCORDRPC),1) -# LDFLAGS += -ldl -Wl,-rpath . -# endif endif # icon @@ -1080,12 +1060,6 @@ endif CFLAGS += -DNODRAWINGDISTANCE #endif -# Check for Discord Rich Presence option -#ifeq ($(DISCORDRPC),1) -# CC_CHECK_CFLAGS += -DDISCORDRPC -# CFLAGS += -DDISCORDRPC -#endif - # Check for Discord SDK option ifeq ($(DISCORD_SDK),1) CC_CHECK_CFLAGS += -DDISCORD_SDK diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index 0a932250..1f4486e1 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -47,6 +47,7 @@ in_files = [ "src/pc/lua/utils/smlua_text_utils.h", "src/pc/lua/utils/smlua_audio_utils.h", "src/pc/lua/utils/smlua_level_utils.h", + "src/pc/lua/utils/smlua_deprecated.h", "src/game/object_helpers.c", "src/game/obj_behaviors.c", "src/game/obj_behaviors_2.c", @@ -106,6 +107,10 @@ override_disallowed_functions = { "src/pc/network/lag_compensation.h": [ "lag_compensation_clear", "lag_compensation_store" ], } +override_hide_functions = { + "smlua_deprecated.h" : [ ".*" ], +} + lua_function_params = { "src/pc/lua/utils/smlua_obj_utils.h::spawn_object_sync::objSetupFunction": [ "struct Object*" ] } @@ -763,6 +768,16 @@ def process_files(): ############################################################################ +def doc_should_document(fname, identifier): + if fname in override_hide_functions: + found_match = False + for pattern in override_hide_functions[fname]: + if re.search(pattern, identifier) != None: + found_match = True + break + return not found_match + return True + def doc_page_link(page_num): if page_num == 1: return 'functions.md' @@ -779,6 +794,9 @@ def doc_function_index(processed_files): for function in processed_file['functions']: if not function['implemented']: continue + if not doc_should_document(processed_file['filename'], function['identifier']): + continue + s += ' - [%s](%s#%s)\n' % (function['identifier'], doc_page_link(page_num), function['identifier']) s += '\n
\n\n' @@ -805,10 +823,13 @@ def doc_lua_func_param(param): s += ')' return s -def doc_function(function): +def doc_function(fname, function): if not function['implemented']: return '' + if not doc_should_document(fname, function['identifier']): + return '' + fid = function['identifier'] s = '\n## [%s](#%s)\n' % (fid, fid) @@ -860,10 +881,10 @@ def doc_function(function): return s -def doc_functions(functions): +def doc_functions(fname, functions): s = '' for function in functions: - s += doc_function(function) + s += doc_function(fname, function) return s def doc_files(processed_files): @@ -879,7 +900,7 @@ def doc_files(processed_files): for processed_file in processed_files: s_file = '\n---' s_file += '\n# functions from %s\n\n
\n\n' % processed_file['filename'] - s_file += doc_functions(processed_file['functions']) + s_file += doc_functions(processed_file['filename'], processed_file['functions']) if len(s) + len(s_file) + extra_space > page_len_limit: s += '---\n\n$[FUNCTION_NAV_HERE]\n\n' diff --git a/autogen/lua_definitions/constants.lua b/autogen/lua_definitions/constants.lua index d1d6d242..18c43586 100644 --- a/autogen/lua_definitions/constants.lua +++ b/autogen/lua_definitions/constants.lua @@ -4727,7 +4727,10 @@ SYNC_DISTANCE_INFINITE = 0 NS_SOCKET = 0 --- @type NetworkSystemType -NS_DISCORD = 1 +NS_COOPNET = 1 + +--- @type NetworkSystemType +NS_MAX = 2 --- @class PlayerInteractions @@ -11522,13 +11525,13 @@ MAX_LOCAL_VERSION_LENGTH = 12 MAX_VERSION_LENGTH = 10 --- @type integer -MINOR_VERSION_NUMBER = 1 +MINOR_VERSION_NUMBER = 0 --- @type integer PATCH_VERSION_NUMBER = 0 --- @type integer -VERSION_NUMBER = 33 +VERSION_NUMBER = 34 --- @type string VERSION_TEXT = "beta" diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index 502423d0..363df1ff 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -5639,12 +5639,6 @@ function network_player_set_description(np, description, r, g, b, a) -- ... end ---- @param localIndex integer ---- @return string -function network_discord_id_from_local_index(localIndex) - -- ... -end - --- @param localIndex integer --- @return string function network_get_player_text_color_string(localIndex) @@ -8015,6 +8009,12 @@ function smlua_collision_util_get(name) -- ... end +--- @param localIndex integer +--- @return string +function network_discord_id_from_local_index(localIndex) + -- ... +end + --- @param scriptEntryName string --- @param courseNum integer --- @param fullName string diff --git a/autogen/lua_definitions/structs.lua b/autogen/lua_definitions/structs.lua index 694dbd5f..ba54ac50 100644 --- a/autogen/lua_definitions/structs.lua +++ b/autogen/lua_definitions/structs.lua @@ -1721,6 +1721,7 @@ --- @field public enablePlayerList integer --- @field public enablePlayersInLevelDisplay integer --- @field public headlessServer integer +--- @field public maxPlayers integer --- @field public playerInteractions PlayerInteractions --- @field public playerKnockbackStrength integer --- @field public shareLives integer diff --git a/docs/lua/constants.md b/docs/lua/constants.md index 839127cf..a7b85f2a 100644 --- a/docs/lua/constants.md +++ b/docs/lua/constants.md @@ -1690,7 +1690,8 @@ | Identifier | Value | | :--------- | :---- | | NS_SOCKET | 0 | -| NS_DISCORD | 1 | +| NS_COOPNET | 1 | +| NS_MAX | 2 | ### [enum PlayerInteractions](#PlayerInteractions) | Identifier | Value | diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 8d664456..1051bd4e 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -8265,26 +8265,6 @@
-## [network_discord_id_from_local_index](#network_discord_id_from_local_index) - -### Lua Example -`local stringValue = network_discord_id_from_local_index(localIndex)` - -### Parameters -| Field | Type | -| ----- | ---- | -| localIndex | `integer` | - -### Returns -- `string` - -### C Prototype -`char* network_discord_id_from_local_index(u8 localIndex);` - -[:arrow_up_small:](#) - -
- ## [network_get_player_text_color_string](#network_get_player_text_color_string) ### Lua Example diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md index ac54f492..522f0eff 100644 --- a/docs/lua/functions-4.md +++ b/docs/lua/functions-4.md @@ -7251,6 +7251,12 @@
+--- +# functions from smlua_deprecated.h + +
+ + --- # functions from smlua_level_utils.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index 2094608b..29c6b88c 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -1096,7 +1096,6 @@
- network_utils.h - - [network_discord_id_from_local_index](functions-3.md#network_discord_id_from_local_index) - [network_get_player_text_color_string](functions-3.md#network_get_player_text_color_string) - [network_global_index_from_local](functions-3.md#network_global_index_from_local) - [network_is_moderator](functions-3.md#network_is_moderator) @@ -1490,6 +1489,10 @@
+- smlua_deprecated.h + +
+ - smlua_level_utils.h - [level_register](functions-4.md#level_register) - [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info) diff --git a/docs/lua/structs.md b/docs/lua/structs.md index 6f77e822..c09b5406 100644 --- a/docs/lua/structs.md +++ b/docs/lua/structs.md @@ -2181,6 +2181,7 @@ | enablePlayerList | `integer` | | | enablePlayersInLevelDisplay | `integer` | | | headlessServer | `integer` | | +| maxPlayers | `integer` | | | playerInteractions | [enum PlayerInteractions](constants.md#enum-PlayerInteractions) | | | playerKnockbackStrength | `integer` | | | shareLives | `integer` | | diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index 77cf8409..3b8fec98 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -85,9 +85,6 @@ void parse_cli_opts(int argc, char* argv[]) { else if (strcmp(argv[i], "--savepath") == 0 && (i + 1) < argc) arg_string("--savepath", argv[++i], gCLIOpts.SavePath, SYS_MAX_PATH); - else if (strcmp(argv[i], "--discord") == 0 && (i + 1) < argc) - arg_uint("--discord", argv[++i], &gCLIOpts.Discord); - // Print help else if (strcmp(argv[i], "--help") == 0) { print_help(); diff --git a/src/pc/cliopts.h b/src/pc/cliopts.h index ea360450..916e19b1 100644 --- a/src/pc/cliopts.h +++ b/src/pc/cliopts.h @@ -22,7 +22,6 @@ struct PCCLIOptions { char ConfigFile[SYS_MAX_PATH]; char SavePath[SYS_MAX_PATH]; char GameDir[SYS_MAX_PATH]; - unsigned int Discord; }; extern struct PCCLIOptions gCLIOpts; diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 8eb1d000..abdd34db 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -120,9 +120,6 @@ bool configEnableCheats = 0; bool configBubbleDeath = true; unsigned int configAmountofPlayers = 16; bool configHUD = true; -#ifdef DISCORDRPC -bool configDiscordRPC = true; -#endif // coop-specific char configJoinIp[MAX_CONFIG_STRING] = ""; unsigned int configJoinPort = DEFAULT_PORT; @@ -213,9 +210,6 @@ static const struct ConfigOption options[] = { #endif {.name = "skip_intro", .type = CONFIG_TYPE_BOOL, .boolValue = &configSkipIntro}, {.name = "enable_cheats", .type = CONFIG_TYPE_BOOL, .boolValue = &configEnableCheats}, - #ifdef DISCORDRPC - {.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC}, - #endif // debug {.name = "debug_offset", .type = CONFIG_TYPE_U64 , .u64Value = &gPcDebug.bhvOffset}, {.name = "debug_tags", .type = CONFIG_TYPE_U64 , .u64Value = gPcDebug.tags}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index df2bbb66..5ca01793 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -80,9 +80,6 @@ extern bool configShareLives; extern bool configEnableCheats; extern bool configBubbleDeath; extern unsigned int configAmountofPlayers; -#ifdef DISCORDRPC -extern bool configDiscordRPC; -#endif extern char configJoinIp[]; extern unsigned int configJoinPort; extern unsigned int configHostPort; diff --git a/src/pc/discord/discord.c b/src/pc/discord/discord.c new file mode 100644 index 00000000..1dbef237 --- /dev/null +++ b/src/pc/discord/discord.c @@ -0,0 +1,159 @@ +#include "discord.h" +#include "pc/djui/djui.h" +#include "pc/debuglog.h" + +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#else +#include +#define MAX_PATH 1024 +#endif + +#define MAX_LAUNCH_CMD (MAX_PATH + 12) + +static int64_t applicationId = 752700005210390568; +struct DiscordApplication app = { 0 }; +static bool sFatalShown = false; +static bool sDiscordInitialized = false; + +static void discord_sdk_log_callback(UNUSED void* hook_data, enum EDiscordLogLevel level, const char* message) { + LOG_INFO("callback (%d): %s", level, message); +} + +void discord_fatal_message(int rc) { // Discord usually does this because of loss of connection to Discord + char errorMessage[132] = { 0 }; + snprintf(errorMessage, 132, "%s\nRC: %d", DLANG(NOTIF, DISCORD_ERROR), rc); + djui_popup_create(errorMessage, 6); +} + +void discord_fatal(int rc) { + if (!sFatalShown) { + discord_fatal_message(rc); + sFatalShown = true; + } + + if (rc != DiscordResult_Ok) { + LOG_ERROR("Discord threw an error. RC: %d", rc); + } +} + +static void get_oauth2_token_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordOAuth2Token* token) { + LOG_INFO("> get_oauth2_token_callback returned %d", result); + if (result != DiscordResult_Ok) { return; } + LOG_INFO("OAuth2 token: %s", token->access_token); +} + +static void register_launch_command(void) { + char cmd[MAX_LAUNCH_CMD] = { 0 }; + int rc; +#if defined(_WIN32) || defined(_WIN64) + HMODULE hModule = GetModuleHandle(NULL); + if (hModule == NULL) { + LOG_ERROR("unable to retrieve absolute path!"); + return; + } + GetModuleFileName(hModule, cmd, sizeof(cmd)); +#else + char path[MAX_LAUNCH_CMD] = { 0 }; + snprintf(path, MAX_LAUNCH_CMD - 1, "/proc/%d/exe", getpid()); + rc = readlink(path, cmd, MAX_LAUNCH_CMD - 1); + if (rc <= 0) { + LOG_ERROR("unable to retrieve absolute path! rc = %d", rc); + return; + } +#endif + strncat(cmd, " --discord 1", MAX_LAUNCH_CMD - 1); + rc = app.activities->register_command(app.activities, cmd); + if (rc != DiscordResult_Ok) { + LOG_ERROR("register command failed %d", rc); + return; + } + LOG_INFO("cmd: %s", cmd); +} + +static void on_current_user_update(UNUSED void* data) { + LOG_INFO("> on_current_user_update"); + struct DiscordUser user = { 0 }; + app.users->get_current_user(app.users, &user); + + // remember user id + app.userId = user.id; + + // copy over discord username if we haven't set one yet + if (configPlayerName[0] == '\0' && strlen(user.username) > 0) { + char* cname = configPlayerName; + char* dname = user.username; + for (int i = 0; i < MAX_PLAYER_STRING - 1; i++) { + if (*dname >= '!' && *dname <= '~') { + *cname = *dname; + cname++; + } + dname++; + } + } +} + +struct IDiscordUserEvents* discord_user_initialize(void) { + LOG_INFO("> discord_user_intitialize"); + static struct IDiscordUserEvents events = { 0 }; + events.on_current_user_update = on_current_user_update; + return &events; +} + +static void discord_initialize(void) { + if (sDiscordInitialized) { return; } + sDiscordInitialized = true; + + if (app.core != NULL) { + app.core->set_log_hook(app.core, DiscordLogLevel_Debug, NULL, discord_sdk_log_callback); + } + + // set up discord params + struct DiscordCreateParams params = { 0 }; + DiscordCreateParamsSetDefault(¶ms); + params.client_id = applicationId; + params.flags = DiscordCreateFlags_NoRequireDiscord; + params.event_data = &app; + params.user_events = discord_user_initialize(); + params.activity_events = discord_activity_initialize(); + + int rc = DiscordCreate(DISCORD_VERSION, ¶ms, &app.core); + if (app.core != NULL) { + app.core->set_log_hook(app.core, DiscordLogLevel_Debug, NULL, discord_sdk_log_callback); + } + + if (rc) { + LOG_ERROR("DiscordCreate failed: %d", rc); + djui_popup_create(DLANG(NOTIF, DISCORD_DETECT), 3); + return; + } + + // set up manager pointers + if (app.core != NULL) { + app.users = app.core->get_user_manager(app.core); + app.achievements = app.core->get_achievement_manager(app.core); + app.activities = app.core->get_activity_manager(app.core); + app.application = app.core->get_application_manager(app.core); + } + + // register launch params + register_launch_command(); + + // get oath2 token + app.application->get_oauth2_token(app.application, NULL, get_oauth2_token_callback); + + // set activity + discord_activity_update(); + + LOG_INFO("initialized"); +} + +void discord_update(void) { + if (!sDiscordInitialized) { + discord_initialize(); + } + + discord_activity_update_check(); + DISCORD_REQUIRE(app.core->run_callbacks(app.core)); +} diff --git a/src/pc/network/discord/discord.h b/src/pc/discord/discord.h similarity index 70% rename from src/pc/network/discord/discord.h rename to src/pc/discord/discord.h index 25a86cc5..eb26fb69 100644 --- a/src/pc/network/discord/discord.h +++ b/src/pc/discord/discord.h @@ -1,22 +1,14 @@ -#ifndef DISCORD_H -#define DISCORD_H -#include -#include -#include -#pragma pack(push, 8) +#pragma once + +#include "PR/ultratypes.h" #include "discord_game_sdk.h" -#pragma pack(pop) + #ifdef _WIN32 #define DISCORD_ID_FORMAT "%lld" #include #else #define DISCORD_ID_FORMAT "%ld" -#include -#include #endif -#include "../network.h" - -void discord_fatal(int rc); // disgusting but descriptive #define DISCORD_REQUIRE(x) { \ @@ -26,10 +18,6 @@ void discord_fatal(int rc); } \ } -extern struct NetworkSystem gNetworkSystemDiscord; -extern bool gDiscordInitialized; -extern bool gDiscordFailed; - struct DiscordApplication { struct IDiscordCore* core; struct IDiscordUserManager* users; @@ -41,6 +29,8 @@ struct DiscordApplication { DiscordUserId userId; }; -extern struct DiscordApplication app; - -#endif \ No newline at end of file +void discord_update(void); +void discord_fatal(int rc); +void discord_activity_update_check(void); +void discord_activity_update(void); +struct IDiscordActivityEvents* discord_activity_initialize(void); diff --git a/src/pc/discord/discord_activity.c b/src/pc/discord/discord_activity.c new file mode 100644 index 00000000..36a8393e --- /dev/null +++ b/src/pc/discord/discord_activity.c @@ -0,0 +1,152 @@ +#include "discord.h" +#include "pc/djui/djui.h" +#include "pc/mods/mods.h" +#include "pc/debuglog.h" + +extern struct DiscordApplication app; +struct DiscordActivity sCurActivity = { 0 }; + +static void on_activity_update_callback(UNUSED void* data, enum EDiscordResult result) { + LOG_INFO("> on_activity_update_callback returned %d", result); + DISCORD_REQUIRE(result); +} + +static void on_activity_join_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordLobby* lobby) { + LOG_INFO("> on_activity_join_callback returned %d", result); + DISCORD_REQUIRE(result); + + LOG_INFO("Discord join callback: %u, %lu, %d, %lu %s, %d", + lobby->capacity, + lobby->id, + lobby->locked, + lobby->owner_id, + lobby->secret, + lobby->type + ); + /*sCurActivity.type = DiscordActivityType_Playing; + sCurActivity.party.size.current_size = 2; + sCurActivity.party.size.max_size = 16; // TODO: wrong + */ + discord_activity_update(); +} + +static void on_activity_join(UNUSED void* data, const char* secret) { + LOG_INFO("> on_activity_join, secret: %s", secret); + //djui_connect_menu_open(); + app.lobbies->connect_lobby_with_activity_secret(app.lobbies, (char*)secret, NULL, on_activity_join_callback); +} + +static void on_activity_join_request_callback(UNUSED void* data, enum EDiscordResult result) { + LOG_INFO("> on_activity_join_request_callback returned %d", (int)result); + DISCORD_REQUIRE(result); +} + +static void on_activity_join_request(UNUSED void* data, struct DiscordUser* user) { + LOG_INFO("> on_activity_join_request from " DISCORD_ID_FORMAT, user->id); +} + +static void strncat_len(char* destination, char* source, size_t destinationLength, size_t sourceLength) { + char altered[128] = { 0 }; + snprintf(altered, (sourceLength < 127) ? sourceLength : 127, "%s", source); + strncat(destination, altered, destinationLength); +} + +static bool discord_populate_details(char* details, bool shorten) { + snprintf(details, 127, "%s", get_version()); + + bool displayDash = true; + bool displayComma = false; + size_t catLength = shorten ? 14 : 64; + + // add mods to activity + if (gActiveMods.entryCount > 0) { + for (int i = 0; i < gActiveMods.entryCount; i++) { + struct Mod* mod = gActiveMods.entries[i]; + if (displayDash) { strncat_len(details, " - ", 127, catLength); } + if (displayComma) { strncat_len(details, ", ", 127, catLength); } + + strncat_len(details, mod->name, 127, catLength); + + displayDash = false; + displayComma = true; + } + } + + return (strlen(details) >= 125); +} + +void discord_activity_update(void) { + sCurActivity.type = DiscordActivityType_Playing; + + if (gNetworkType != NT_NONE && gNetworkSystem) { + gNetworkSystem->get_lobby_id(sCurActivity.party.id, 128); + gNetworkSystem->get_lobby_secret(sCurActivity.secrets.join, 128); + sCurActivity.party.size.current_size = network_player_connected_count(); + sCurActivity.party.size.max_size = gServerSettings.maxPlayers; + } else { + sCurActivity.party.size.current_size = 1; + sCurActivity.party.size.max_size = 1; + } + + if (sCurActivity.party.size.current_size > 1) { + strcpy(sCurActivity.state, "Playing!"); + } else if (gNetworkType == NT_SERVER) { + strcpy(sCurActivity.state, "Waiting for players..."); + } else { + strcpy(sCurActivity.state, "In-game."); + sCurActivity.party.size.current_size = 1; + if (sCurActivity.party.size.max_size < 1) { sCurActivity.party.size.max_size = 1; } + } + + char details[256] = { 0 }; + bool overrun = discord_populate_details(details, false); + if (overrun) { + discord_populate_details(details, true); + } + + if (snprintf(sCurActivity.details, 125, "%s", details) < 0) { + LOG_INFO("truncating details"); + } + + if (!app.activities) { + LOG_INFO("no activities"); + return; + } + + if (!app.activities->update_activity) { + LOG_INFO("no update_activity"); + return; + } + + app.activities->update_activity(app.activities, &sCurActivity, NULL, on_activity_update_callback); + LOG_INFO("set activity"); +} + +void discord_activity_update_check(void) { + if (gNetworkType == NT_NONE) { return; } + bool shouldUpdate = false; + u8 connectedCount = network_player_connected_count(); + + if (connectedCount > 0) { + if (connectedCount != sCurActivity.party.size.current_size) { + shouldUpdate = true; + } + } + + static int updateTimer = 30 * 60; + if (--updateTimer <= 0) { + updateTimer = 30 * 60; + shouldUpdate = true; + } + + if (shouldUpdate) { + discord_activity_update(); + } +} + +struct IDiscordActivityEvents* discord_activity_initialize(void) { + static struct IDiscordActivityEvents events = { 0 }; + events.on_activity_join = on_activity_join; + events.on_activity_join_request = on_activity_join_request; + return &events; +} \ No newline at end of file diff --git a/src/pc/network/discord/discord_game_sdk.h b/src/pc/discord/discord_game_sdk.h similarity index 100% rename from src/pc/network/discord/discord_game_sdk.h rename to src/pc/discord/discord_game_sdk.h diff --git a/src/pc/discord/discordrpc.c b/src/pc/discord/discordrpc.c deleted file mode 100644 index 25d5373e..00000000 --- a/src/pc/discord/discordrpc.c +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include -#include -#include - -#include "macros.h" -#include "PR/ultratypes.h" -#include "game/memory.h" -#include "game/save_file.h" -#include "pc/configfile.h" -#include "discordrpc.h" - -#define DISCORDLIBFILE "libdiscord-rpc" - -// Thanks Microsoft for being non posix compliant -#if defined(_WIN32) -# include -# define DISCORDLIBEXT ".dll" -# define dlopen(lib, flag) LoadLibrary(TEXT(lib)) -# define dlerror() "" -# define dlsym(handle, func) (void *)GetProcAddress(handle, func) -# define dlclose(handle) FreeLibrary(handle) -#elif defined(__APPLE__) -# include -# define DISCORDLIBEXT ".dylib" -#elif defined(__linux__) || defined(__FreeBSD__) // lets make the bold assumption for FreeBSD -# include -# define DISCORDLIBEXT ".so" -#else -# error Unknown System -#endif - -#define DISCORDLIB DISCORDLIBFILE DISCORDLIBEXT -#define DISCORD_APP_ID "709083908708237342" -#define DISCORD_UPDATE_RATE 5 - -extern s16 gCurrCourseNum; -extern s16 gCurrActNum; -extern u8* seg2_course_name_table[]; -extern u8* seg2_act_name_table[]; - -static time_t lastUpdatedTime; - -static DiscordRichPresence discordRichPresence; -static bool initd = false; - -static void* handle; - -void (*Discord_Initialize)(const char *, DiscordEventHandlers *, int, const char *); -void (*Discord_Shutdown)(void); -void (*Discord_ClearPresence)(void); -void (*Discord_UpdatePresence)(DiscordRichPresence *); - -static s16 lastCourseNum = -1; -static s16 lastActNum = -1; - -#ifdef VERSION_EU -#include "eu_translation.h" -extern s32 gInGameLanguage; -#endif - -static char stage[188]; -static char act[188]; - -static char smallImageKey[5]; -static char largeImageKey[5]; - -static const char charset[0xFF+1] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7 - ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15 - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23 - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31 - 'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55 - ' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239 - ' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255 -}; - -static void convertstring(const u8 *str, char* output) { - s32 strPos = 0; - bool capitalizeChar = true; - - while (str[strPos] != 0xFF) { - if (str[strPos] < 0xFF) { - output[strPos] = charset[str[strPos]]; - - // if the char is a letter we can capatalize it - if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23) { - output[strPos] -= ('a' - 'A'); - capitalizeChar = false; - } - - } else { - output[strPos] = ' '; - } - - // decide if the next character should be capitalized - switch (output[strPos]) { - case ' ': - if (str[strPos] != 158) - fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found - case '-': - capitalizeChar = true; - break; - default: - capitalizeChar = false; - break; - } - - strPos++; - } - - output[strPos] = '\0'; -} - -static void on_ready(UNUSED const DiscordUser* user) { - discord_reset(); -} - -static void init_discord(void) { - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - handlers.ready = on_ready; - - Discord_Initialize(DISCORD_APP_ID, &handlers, false, ""); - - initd = true; -} - -static void set_details(void) { - if (lastCourseNum != gCurrCourseNum) { - // If we are in in Course 0 we are in the castle which doesn't have a string - if (gCurrCourseNum) { - void **courseNameTbl; - -#ifndef VERSION_EU - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#else - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif - u8 *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]); - - convertstring(&courseName[3], stage); - } else { - strcpy(stage, "Peach's Castle"); - } - - lastCourseNum = gCurrCourseNum; - } -} - -static void set_state(void) { - if (lastActNum != gCurrActNum || lastCourseNum != gCurrCourseNum) { - // when exiting a stage the act doesn't get reset - if (gCurrActNum && gCurrCourseNum) { - // any stage over 19 is a special stage without acts - if (gCurrCourseNum < 19) { - void **actNameTbl; -#ifndef VERSION_EU - actNameTbl = segmented_to_virtual(seg2_act_name_table); -#else - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - break; - } -#endif - u8 *actName = actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1]); - - convertstring(actName, act); - } else { - act[0] = '\0'; - gCurrActNum = 0; - } - } else { - act[0] = '\0'; - } - - lastActNum = gCurrActNum; - } -} - -void set_logo(void) { - if (lastCourseNum) - snprintf(largeImageKey, sizeof(largeImageKey), "%d", lastCourseNum); - else - strcpy(largeImageKey, "0"); - - /* - if (lastActNum) - snprintf(smallImageKey, sizeof(largeImageKey), "%d", lastActNum); - else - smallImageKey[0] = '\0'; - */ - - discordRichPresence.largeImageKey = largeImageKey; - //discordRichPresence.largeImageText = ""; - //discordRichPresence.smallImageKey = smallImageKey; - //discordRichPresence.smallImageText = ""; -} - -void discord_update_rich_presence(void) { - if (!configDiscordRPC || !initd) return; - if (time(NULL) < lastUpdatedTime + DISCORD_UPDATE_RATE) return; - - lastUpdatedTime = time(NULL); - - set_state(); - set_details(); - set_logo(); - Discord_UpdatePresence(&discordRichPresence); -} - -void discord_shutdown(void) { - if (handle) { - Discord_ClearPresence(); - Discord_Shutdown(); - dlclose(handle); - } -} - -void discord_init(void) { - if (configDiscordRPC) { - handle = dlopen(DISCORDLIB, RTLD_LAZY); - if (!handle) { - fprintf(stderr, "Unable to load Discord\n%s\n", dlerror()); - return; - } - - Discord_Initialize = dlsym(handle, "Discord_Initialize"); - Discord_Shutdown = dlsym(handle, "Discord_Shutdown"); - Discord_ClearPresence = dlsym(handle, "Discord_ClearPresence"); - Discord_UpdatePresence = dlsym(handle, "Discord_UpdatePresence"); - - init_discord(); - - discordRichPresence.details = stage; - discordRichPresence.state = act; - - lastUpdatedTime = 0; - } -} - -void discord_reset(void) { - memset( &discordRichPresence, 0, sizeof( discordRichPresence ) ); - - set_state(); - set_details(); - set_logo(); - Discord_UpdatePresence(&discordRichPresence); -} diff --git a/src/pc/discord/discordrpc.h b/src/pc/discord/discordrpc.h deleted file mode 100644 index 6d8bc6db..00000000 --- a/src/pc/discord/discordrpc.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef DISCORDRPC_H -#define DISCORDRPC_H - -#include - -typedef struct DiscordRichPresence { - const char* state; /* max 128 bytes */ - const char* details; /* max 128 bytes */ - int64_t startTimestamp; - int64_t endTimestamp; - const char* largeImageKey; /* max 32 bytes */ - const char* largeImageText; /* max 128 bytes */ - const char* smallImageKey; /* max 32 bytes */ - const char* smallImageText; /* max 128 bytes */ - const char* partyId; /* max 128 bytes */ - int partySize; - int partyMax; - const char* matchSecret; /* max 128 bytes */ - const char* joinSecret; /* max 128 bytes */ - const char* spectateSecret; /* max 128 bytes */ - int8_t instance; -} DiscordRichPresence; - -typedef struct DiscordUser { - const char* userId; - const char* username; - const char* discriminator; - const char* avatar; -} DiscordUser; - -typedef struct DiscordEventHandlers { - void (*ready)(const DiscordUser* request); - void (*disconnected)(int errorCode, const char* message); - void (*errored)(int errorCode, const char* message); - void (*joinGame)(const char* joinSecret); - void (*spectateGame)(const char* spectateSecret); - void (*joinRequest)(const DiscordUser* request); -} DiscordEventHandlers; - -#define DISCORD_REPLY_NO 0 -#define DISCORD_REPLY_YES 1 -#define DISCORD_REPLY_IGNORE 2 - -void discord_update_rich_presence(void); -void discord_shutdown(void); -void discord_init(void); -void discord_reset(void); - -#endif // DISCORDRPC_H diff --git a/src/pc/djui/djui_panel_host.c b/src/pc/djui/djui_panel_host.c index 8c53ed2f..69309cf2 100644 --- a/src/pc/djui/djui_panel_host.c +++ b/src/pc/djui/djui_panel_host.c @@ -18,14 +18,6 @@ struct DjuiInputbox* sInputboxPort = NULL; struct DjuiInputbox* sInputboxPassword = NULL; static void djui_panel_host_network_system_change(UNUSED struct DjuiBase* base) { -#ifndef DISCORD_SDK - { - struct DjuiSelectionbox* selectionbox = (struct DjuiSelectionbox*) base; - if (*selectionbox->value == NS_DISCORD) { - selectionbox->value = NS_SOCKET; - } - } -#endif #ifndef COOPNET { struct DjuiSelectionbox* selectionbox = (struct DjuiSelectionbox*) base; @@ -101,8 +93,8 @@ void djui_panel_host_create(struct DjuiBase* caller) { : DLANG(HOST, HOST_TITLE)); struct DjuiBase* body = djui_three_panel_get_body(panel); { - char* nChoices[] = { DLANG(HOST, DIRECT_CONNECTION), DLANG(HOST, DISCORD), DLANG(HOST, COOPNET) }; - struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(body, DLANG(HOST, NETWORK_SYSTEM), nChoices, 3, &configNetworkSystem, djui_panel_host_network_system_change); + char* nChoices[] = { DLANG(HOST, DIRECT_CONNECTION), DLANG(HOST, COOPNET) }; + struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(body, DLANG(HOST, NETWORK_SYSTEM), nChoices, 2, &configNetworkSystem, djui_panel_host_network_system_change); if (gNetworkType == NT_SERVER) { djui_base_set_enabled(&selectionbox1->base, false); } diff --git a/src/pc/djui/djui_panel_host_message.c b/src/pc/djui/djui_panel_host_message.c index 32c7c60e..bf515587 100644 --- a/src/pc/djui/djui_panel_host_message.c +++ b/src/pc/djui/djui_panel_host_message.c @@ -4,7 +4,6 @@ #include "djui_panel_menu.h" #include "djui_panel_modlist.h" #include "src/pc/network/network.h" -#include "src/pc/network/discord/discord.h" #include "src/pc/utils/misc.h" #include "src/pc/configfile.h" #include "pc/utils/misc.h" @@ -21,9 +20,6 @@ void djui_panel_do_host(bool reconnecting) { gCurrSaveFileNum = configHostSaveSlot; update_all_mario_stars(); -#ifndef DISCORD_SDK - if (configNetworkSystem == NS_DISCORD) { configNetworkSystem = NS_COOPNET; } -#endif #ifndef COOPNET if (configNetworkSystem == NS_COOPNET) { configNetworkSystem = NS_SOCKET; } #endif @@ -54,15 +50,9 @@ void djui_panel_host_message_create(struct DjuiBase* caller) { char* warningMessage = NULL; bool hideHostButton = false; - if (configNetworkSystem == NS_DISCORD) { - warningLines = gDiscordFailed ? 5 : 13; - warningMessage = gDiscordFailed ? DLANG(HOST_MESSAGE, WARN_DISCORD2) : DLANG(HOST_MESSAGE, WARN_DISCORD); - hideHostButton = gDiscordFailed; - } else { - warningLines = 5; - warningMessage = calloc(256, sizeof(char)); - sprintf(warningMessage, DLANG(HOST_MESSAGE, WARN_SOCKET), configHostPort); - } + warningLines = 5; + warningMessage = calloc(256, sizeof(char)); + snprintf(warningMessage, 256, DLANG(HOST_MESSAGE, WARN_SOCKET), configHostPort); f32 textHeight = 32 * 0.8125f * warningLines + 8; @@ -88,7 +78,5 @@ void djui_panel_host_message_create(struct DjuiBase* caller) { } djui_panel_add(caller, panel, NULL); - if (configNetworkSystem != NS_DISCORD) { - free(warningMessage); - } + free(warningMessage); } diff --git a/src/pc/djui/djui_panel_host_settings.c b/src/pc/djui/djui_panel_host_settings.c index afe0e480..a2ff3116 100644 --- a/src/pc/djui/djui_panel_host_settings.c +++ b/src/pc/djui/djui_panel_host_settings.c @@ -7,7 +7,6 @@ #include "pc/utils/misc.h" #include "pc/configfile.h" #include "pc/cheats.h" -#include "pc/network/discord/lobby.h" #include "djui_inputbox.h" static unsigned int sKnockbackIndex = 0; diff --git a/src/pc/djui/djui_panel_join_lobbies.c b/src/pc/djui/djui_panel_join_lobbies.c index 8256b729..09cd43ed 100644 --- a/src/pc/djui/djui_panel_join_lobbies.c +++ b/src/pc/djui/djui_panel_join_lobbies.c @@ -20,6 +20,7 @@ static char* sPassword = NULL; void djui_panel_join_lobby(struct DjuiBase* caller) { gCoopNetDesiredLobby = (uint64_t)caller->tag; + snprintf(gCoopNetPassword, 64, "%s", sPassword); network_reset_reconnect_and_rehost(); network_set_system(NS_COOPNET); network_init(NT_CLIENT, false); diff --git a/src/pc/lua/smlua_cobject_autogen.c b/src/pc/lua/smlua_cobject_autogen.c index bc121b77..dbff5144 100644 --- a/src/pc/lua/smlua_cobject_autogen.c +++ b/src/pc/lua/smlua_cobject_autogen.c @@ -1887,13 +1887,14 @@ static struct LuaObjectField sRayIntersectionInfoFields[LUA_RAY_INTERSECTION_INF { "surface", LVT_COBJECT_P, offsetof(struct RayIntersectionInfo, surface), false, LOT_SURFACE }, }; -#define LUA_SERVER_SETTINGS_FIELD_COUNT 10 +#define LUA_SERVER_SETTINGS_FIELD_COUNT 11 static struct LuaObjectField sServerSettingsFields[LUA_SERVER_SETTINGS_FIELD_COUNT] = { { "bubbleDeath", LVT_U8, offsetof(struct ServerSettings, bubbleDeath), false, LOT_NONE }, { "enableCheats", LVT_U8, offsetof(struct ServerSettings, enableCheats), false, LOT_NONE }, { "enablePlayerList", LVT_U8, offsetof(struct ServerSettings, enablePlayerList), false, LOT_NONE }, { "enablePlayersInLevelDisplay", LVT_U8, offsetof(struct ServerSettings, enablePlayersInLevelDisplay), false, LOT_NONE }, { "headlessServer", LVT_U8, offsetof(struct ServerSettings, headlessServer), false, LOT_NONE }, + { "maxPlayers", LVT_U8, offsetof(struct ServerSettings, maxPlayers), false, LOT_NONE }, { "playerInteractions", LVT_S32, offsetof(struct ServerSettings, playerInteractions), false, LOT_NONE }, { "playerKnockbackStrength", LVT_U8, offsetof(struct ServerSettings, playerKnockbackStrength), false, LOT_NONE }, { "shareLives", LVT_U8, offsetof(struct ServerSettings, shareLives), false, LOT_NONE }, diff --git a/src/pc/lua/smlua_constants_autogen.c b/src/pc/lua/smlua_constants_autogen.c index 422513fe..7343f989 100644 --- a/src/pc/lua/smlua_constants_autogen.c +++ b/src/pc/lua/smlua_constants_autogen.c @@ -1759,7 +1759,8 @@ char gSmluaConstants[] = "" "SYNC_DISTANCE_INFINITE = 0\n" "PACKET_LENGTH = 3000\n" "NS_SOCKET = 0\n" -"NS_DISCORD = 1\n" +"NS_COOPNET = 1\n" +"NS_MAX = 2\n" "PLAYER_INTERACTIONS_NONE = 0\n" "PLAYER_INTERACTIONS_SOLID = 1\n" "PLAYER_INTERACTIONS_PVP = 2\n" @@ -4015,8 +4016,8 @@ char gSmluaConstants[] = "" "COOP_OBJ_FLAG_NON_SYNC = (1 << 2)\n" "COOP_OBJ_FLAG_INITIALIZED = (1 << 3)\n" "VERSION_TEXT = 'beta'\n" -"VERSION_NUMBER = 33\n" -"MINOR_VERSION_NUMBER = 1\n" +"VERSION_NUMBER = 34\n" +"MINOR_VERSION_NUMBER = 0\n" "PATCH_VERSION_NUMBER = 0\n" "MAX_VERSION_LENGTH = 10\n" "MAX_LOCAL_VERSION_LENGTH = 12\n" diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index 8b63200c..926a7fa2 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -30,6 +30,7 @@ #include "src/pc/lua/utils/smlua_text_utils.h" #include "src/pc/lua/utils/smlua_audio_utils.h" #include "src/pc/lua/utils/smlua_level_utils.h" +#include "src/pc/lua/utils/smlua_deprecated.h" #include "src/game/object_list_processor.h" #include "src/game/behavior_actions.h" #include "src/game/mario_misc.h" @@ -18741,23 +18742,6 @@ int smlua_func_network_player_set_description(lua_State* L) { // network_utils.h // ///////////////////// -int smlua_func_network_discord_id_from_local_index(lua_State* L) { - if (L == NULL) { return 0; } - - int top = lua_gettop(L); - if (top != 1) { - LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "network_discord_id_from_local_index", 1, top); - return 0; - } - - u8 localIndex = smlua_to_integer(L, 1); - if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "network_discord_id_from_local_index"); return 0; } - - lua_pushstring(L, network_discord_id_from_local_index(localIndex)); - - return 1; -} - int smlua_func_network_get_player_text_color_string(lua_State* L) { if (L == NULL) { return 0; } @@ -26273,6 +26257,27 @@ int smlua_func_smlua_collision_util_get(lua_State* L) { return 1; } + //////////////////////// + // smlua_deprecated.h // +//////////////////////// + +int smlua_func_network_discord_id_from_local_index(lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 1) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "network_discord_id_from_local_index", 1, top); + return 0; + } + + u8 localIndex = smlua_to_integer(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "network_discord_id_from_local_index"); return 0; } + + lua_pushstring(L, network_discord_id_from_local_index(localIndex)); + + return 1; +} + ///////////////////////// // smlua_level_utils.h // ///////////////////////// @@ -30186,7 +30191,6 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "network_player_set_description", smlua_func_network_player_set_description); // network_utils.h - smlua_bind_function(L, "network_discord_id_from_local_index", smlua_func_network_discord_id_from_local_index); smlua_bind_function(L, "network_get_player_text_color_string", smlua_func_network_get_player_text_color_string); smlua_bind_function(L, "network_global_index_from_local", smlua_func_network_global_index_from_local); smlua_bind_function(L, "network_is_moderator", smlua_func_network_is_moderator); @@ -30571,6 +30575,9 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "get_water_surface_pseudo_floor", smlua_func_get_water_surface_pseudo_floor); smlua_bind_function(L, "smlua_collision_util_get", smlua_func_smlua_collision_util_get); + // smlua_deprecated.h + smlua_bind_function(L, "network_discord_id_from_local_index", smlua_func_network_discord_id_from_local_index); + // smlua_level_utils.h smlua_bind_function(L, "level_register", smlua_func_level_register); smlua_bind_function(L, "smlua_level_util_get_info", smlua_func_smlua_level_util_get_info); diff --git a/src/pc/lua/utils/smlua_deprecated.c b/src/pc/lua/utils/smlua_deprecated.c new file mode 100644 index 00000000..6bf111d7 --- /dev/null +++ b/src/pc/lua/utils/smlua_deprecated.c @@ -0,0 +1,5 @@ +#include "types.h" + +char* network_discord_id_from_local_index(UNUSED u8 localIndex) { + return NULL; +} diff --git a/src/pc/lua/utils/smlua_deprecated.h b/src/pc/lua/utils/smlua_deprecated.h new file mode 100644 index 00000000..09622d33 --- /dev/null +++ b/src/pc/lua/utils/smlua_deprecated.h @@ -0,0 +1,3 @@ +#pragma once + +char* network_discord_id_from_local_index(u8 localIndex); diff --git a/src/pc/network/coopnet/coopnet.c b/src/pc/network/coopnet/coopnet.c index 82936b61..65f32d43 100644 --- a/src/pc/network/coopnet/coopnet.c +++ b/src/pc/network/coopnet/coopnet.c @@ -7,17 +7,21 @@ #include "pc/djui/djui_popup.h" #include "pc/mods/mods.h" #include "pc/debuglog.h" +#ifdef DISCORD_SDK +#include "pc/discord/discord.h" +#endif #ifdef COOPNET #define CN_GAME_STR "sm64ex-coop" uint64_t gCoopNetDesiredLobby = 0; +char gCoopNetPassword[64] = ""; static uint64_t sLocalLobbyId = 0; static uint64_t sLocalLobbyOwnerId = 0; static enum NetworkType sNetworkType; -static bool sReconecting = false; +static bool sReconnecting = false; static CoopNetRc coopnet_initialize(void); @@ -69,6 +73,9 @@ static void coopnet_on_lobby_joined(uint64_t lobbyId, uint64_t userId, uint64_t if (userId == coopnet_get_local_user_id() && gNetworkType == NT_CLIENT) { network_send_mod_list_request(); } +#ifdef DISCORD_SDK + discord_activity_update(); +#endif } static void coopnet_on_lobby_left(uint64_t lobbyId, uint64_t userId) { @@ -81,7 +88,7 @@ static void coopnet_on_lobby_left(uint64_t lobbyId, uint64_t userId) { static bool ns_coopnet_initialize(enum NetworkType networkType, bool reconnecting) { sNetworkType = networkType; - sReconecting = reconnecting; + sReconnecting = reconnecting; if (reconnecting) { return true; } return coopnet_is_connected() ? true @@ -114,8 +121,8 @@ void ns_coopnet_update(void) { coopnet_update(); if (gNetworkType != NT_NONE && sNetworkType != NT_NONE) { if (sNetworkType == NT_SERVER) { - if (sReconecting) { - + if (sReconnecting) { + // TODO: send lobby update packet } else { LOG_INFO("Create lobby"); char mode[64] = ""; @@ -124,7 +131,7 @@ void ns_coopnet_update(void) { } } else if (sNetworkType == NT_CLIENT) { LOG_INFO("Join lobby"); - coopnet_lobby_join(gCoopNetDesiredLobby, ""); + coopnet_lobby_join(gCoopNetDesiredLobby, gCoopNetPassword); } sNetworkType = NT_NONE; } @@ -140,12 +147,31 @@ static int ns_coopnet_network_send(u8 localIndex, void* address, u8* data, u16 d return 0; } +static void ns_coopnet_get_lobby_id(UNUSED char* destination, UNUSED u32 destLength) { + if (sLocalLobbyId == 0) { + snprintf(destination, destLength, "%s", ""); + } else { + snprintf(destination, destLength, "coopnet-id:%" PRIu64 "", sLocalLobbyId); + } +} + +static void ns_coopnet_get_lobby_secret(UNUSED char* destination, UNUSED u32 destLength) { + if (sLocalLobbyId == 0) { + snprintf(destination, destLength, "%s", ""); + } else { + snprintf(destination, destLength, "coopnet-pw:%s", gCoopNetPassword); + } +} + static void ns_coopnet_shutdown(bool reconnecting) { if (reconnecting) { return; } LOG_INFO("Coopnet shutdown!"); coopnet_shutdown(); gCoopNetCallbacks.OnLobbyListGot = NULL; gCoopNetCallbacks.OnLobbyListFinish = NULL; + + sLocalLobbyId = 0; + sLocalLobbyOwnerId = 0; } static CoopNetRc coopnet_initialize(void) { @@ -167,18 +193,20 @@ static CoopNetRc coopnet_initialize(void) { } struct NetworkSystem gNetworkSystemCoopNet = { - .initialize = ns_coopnet_initialize, - .get_id = ns_coopnet_get_id, - .get_id_str = ns_coopnet_get_id_str, - .save_id = ns_coopnet_save_id, - .clear_id = ns_coopnet_clear_id, - .dup_addr = ns_coopnet_dup_addr, - .match_addr = ns_coopnet_match_addr, - .update = ns_coopnet_update, - .send = ns_coopnet_network_send, - .shutdown = ns_coopnet_shutdown, + .initialize = ns_coopnet_initialize, + .get_id = ns_coopnet_get_id, + .get_id_str = ns_coopnet_get_id_str, + .save_id = ns_coopnet_save_id, + .clear_id = ns_coopnet_clear_id, + .dup_addr = ns_coopnet_dup_addr, + .match_addr = ns_coopnet_match_addr, + .update = ns_coopnet_update, + .send = ns_coopnet_network_send, + .get_lobby_id = ns_coopnet_get_lobby_id, + .get_lobby_secret = ns_coopnet_get_lobby_secret, + .shutdown = ns_coopnet_shutdown, .requireServerBroadcast = false, - .name = "CoopNet", + .name = "CoopNet", }; #endif diff --git a/src/pc/network/coopnet/coopnet.h b/src/pc/network/coopnet/coopnet.h index a9667280..49987e34 100644 --- a/src/pc/network/coopnet/coopnet.h +++ b/src/pc/network/coopnet/coopnet.h @@ -7,6 +7,7 @@ typedef void (*QueryFinishCallbackPtr)(void); extern struct NetworkSystem gNetworkSystemCoopNet; extern uint64_t gCoopNetDesiredLobby; +extern char gCoopNetPassword[]; bool ns_coopnet_query(QueryCallbackPtr callback, QueryFinishCallbackPtr finishCallback, const char* password); bool ns_coopnet_is_connected(void); diff --git a/src/pc/network/discord/activity.c b/src/pc/network/discord/activity.c deleted file mode 100644 index 6a7100e5..00000000 --- a/src/pc/network/discord/activity.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "activity.h" -#include "lobby.h" -#include "discord_network.h" -#include "pc/network/network.h" -#include "pc/network/version.h" -#include "pc/djui/djui.h" -#include "pc/mods/mods.h" -#include "pc/logfile.h" - -#define HASH_LENGTH 8 -struct DiscordActivity gCurActivity = { 0 }; -bool gActivityLock = false; - -static void on_activity_update_callback(UNUSED void* data, enum EDiscordResult result) { - LOGFILE_INFO(LFT_DISCORD, "> on_activity_update_callback returned %d", result); - DISCORD_REQUIRE(result); -} - -static void on_activity_join_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordLobby* lobby) { - gActivityLock = false; - LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_callback returned %d, lobby " DISCORD_ID_FORMAT ", owner " DISCORD_ID_FORMAT, result, lobby->id, lobby->owner_id); - DISCORD_REQUIRE(result); - if (gNetworkType != NT_NONE) { - LOGFILE_ERROR(LFT_DISCORD, "Joined lobby when already connected somewhere!"); - return; - } - network_reset_reconnect_and_rehost(); - network_init(NT_CLIENT, false); - - gCurActivity.type = DiscordActivityType_Playing; - if (snprintf(gCurActivity.party.id, 128, DISCORD_ID_FORMAT, lobby->id) < 0) { - LOGFILE_ERROR(LFT_DISCORD, "Truncating party id"); - } - gCurActivity.party.size.current_size = 2; - gCurActivity.party.size.max_size = lobby->capacity; - - gCurLobbyId = lobby->id; - - discord_network_init(lobby->id); - discord_activity_update(false); - - if (gNetworkPlayerServer == NULL) { - network_player_connected(NPT_SERVER, 0, 0, &DEFAULT_MARIO_PALETTE, "Player"); - } - ns_discord_save_id(gNetworkPlayerServer->localIndex, lobby->owner_id); - network_send_mod_list_request(); - - gNetworkUserIds[0] = lobby->owner_id; -} - -static void on_activity_join(UNUSED void* data, const char* secret) { - LOGFILE_INFO(LFT_DISCORD, "> on_activity_join, secret: %s", secret); - if (gActivityLock) { return; } - gActivityLock = true; - djui_connect_menu_open(); - app.lobbies->connect_lobby_with_activity_secret(app.lobbies, (char*)secret, NULL, on_activity_join_callback); -} - -static void on_activity_join_request_callback(UNUSED void* data, enum EDiscordResult result) { - LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_request_callback returned %d", (int)result); - DISCORD_REQUIRE(result); -} - -static void on_activity_join_request(UNUSED void* data, struct DiscordUser* user) { - LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_request from " DISCORD_ID_FORMAT, user->id); - //app.activities->send_request_reply(app.activities, user->id, DiscordActivityJoinRequestReply_Yes, NULL, on_activity_join_request_callback); -} - -static void strncat_len(char* destination, char* source, size_t destinationLength, size_t sourceLength) { - char altered[128] = { 0 }; - snprintf(altered, (sourceLength < 127) ? sourceLength : 127, "%s", source); - strncat(destination, altered, destinationLength); -} - -static bool discord_populate_details(char* details, bool shorten) { - snprintf(details, 127, "%s", get_version()); - - bool displayDash = true; - bool displayComma = false; - size_t catLength = shorten ? 14 : 64; - - if (gRegisteredMods.string != NULL) { - strncat_len(details, " - ", 127, catLength); - displayDash = false; - - // add patches to activity - struct StringLinkedList* node = &gRegisteredMods; - while (node != NULL && node->string != NULL) { - if (displayComma) { strncat_len(details, ", ", 127, catLength); } - strncat_len(details, node->string, 127, catLength); - displayComma = true; - node = node->next; - } - } - - if (gActiveMods.entryCount > 0) { - // add mods to activity - for (int i = 0; i < gActiveMods.entryCount; i++) { - struct Mod* mod = gActiveMods.entries[i]; - if (displayDash) { strncat_len(details, " - ", 127, catLength); } - if (displayComma) { strncat_len(details, ", ", 127, catLength); } - - strncat_len(details, mod->name, 127, catLength); - - displayDash = false; - displayComma = true; - } - } - - return (strlen(details) >= 125); -} - -void discord_activity_update(bool hosting) { - gCurActivity.type = DiscordActivityType_Playing; - if (gCurActivity.party.size.current_size > 1) { - strcpy(gCurActivity.state, "Playing!"); - } else if (hosting) { - strcpy(gCurActivity.state, "Waiting for players..."); - } else { - strcpy(gCurActivity.state, "In-game."); - gCurActivity.party.size.current_size = 1; - if (gCurActivity.party.size.max_size < 1) { gCurActivity.party.size.max_size = 1; } - } - - char details[256] = { 0 }; - bool overrun = discord_populate_details(details, false); - if (overrun) { - discord_populate_details(details, true); - } - - if (snprintf(gCurActivity.details, 125, "%s", details) < 0) { - LOGFILE_INFO(LFT_DISCORD, "truncating details"); - } - - if (!app.activities) { - LOGFILE_INFO(LFT_DISCORD, "no activities"); - return; - } - - if (!app.activities->update_activity) { - LOGFILE_INFO(LFT_DISCORD, "no update_activity"); - return; - } - - app.activities->update_activity(app.activities, &gCurActivity, NULL, on_activity_update_callback); - LOGFILE_INFO(LFT_DISCORD, "set activity"); -} - -void discord_activity_update_check(void) { - if (gNetworkType == NT_NONE) { return; } - bool shouldUpdate = false; - u8 connectedCount = network_player_connected_count(); - - if (connectedCount > 0) { - if (connectedCount != gCurActivity.party.size.current_size) { - gCurActivity.party.size.current_size = connectedCount; - shouldUpdate = true; - } - } - - if (shouldUpdate) { - discord_activity_update(gNetworkType == NT_SERVER); - } -} - -struct IDiscordActivityEvents* discord_activity_initialize(void) { - static struct IDiscordActivityEvents events = { 0 }; - events.on_activity_join = on_activity_join; - events.on_activity_join_request = on_activity_join_request; - return &events; -} \ No newline at end of file diff --git a/src/pc/network/discord/activity.h b/src/pc/network/discord/activity.h deleted file mode 100644 index 43eb25a1..00000000 --- a/src/pc/network/discord/activity.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef DISCORD_ACTIVITY_H -#define DISCORD_ACTIVITY_H -#include "discord.h" - -extern struct DiscordActivity gCurActivity; - -void discord_activity_update(bool hosting); -void discord_activity_update_check(void); -struct IDiscordActivityEvents* discord_activity_initialize(void); -extern bool gActivityLock; - -#endif \ No newline at end of file diff --git a/src/pc/network/discord/discord.c b/src/pc/network/discord/discord.c deleted file mode 100644 index 58457725..00000000 --- a/src/pc/network/discord/discord.c +++ /dev/null @@ -1,203 +0,0 @@ -#include "discord.h" -#include "user.h" -#include "activity.h" -#include "lobby.h" -#include "discord_network.h" -#include "pc/network/version.h" -#include "pc/djui/djui.h" -#include "pc/logfile.h" - -#if defined(_WIN32) || defined(_WIN64) -#include -#include -#else -#include -#define MAX_PATH 1024 -#endif - -#define MAX_LAUNCH_CMD (MAX_PATH + 12) - -static int64_t applicationId = 752700005210390568; -struct DiscordApplication app = { 0 }; -bool gDiscordInitialized = false; -bool gDiscordFailed = false; -bool alreadyRun = false; - -static void discord_sdk_log_callback(UNUSED void* hook_data, enum EDiscordLogLevel level, const char* message) { - LOGFILE_INFO(LFT_DISCORD, "callback (%d): %s", level, message); -} - -void discord_fatal_message(int rc) { // Discord usually does this because of loss of connection to Discord - char errorMessage[132] = { 0 }; - snprintf(errorMessage, 132, "%s\nRC: %d", DLANG(NOTIF, DISCORD_ERROR), rc); - djui_popup_create(errorMessage, 6); -} - -void discord_fatal(int rc) { - if (!alreadyRun) { - discord_fatal_message(rc); - alreadyRun = true; - } - - if (rc != DiscordResult_Ok) { - LOG_ERROR("Discord threw an error. RC: %d", rc); - } -} - -static void set_instance_env_variable(void) { - // set local instance id - char environmentVariables[128] = { 0 }; - int instance = (gCLIOpts.Discord == 0) ? 0 : (gCLIOpts.Discord - 1); - snprintf(environmentVariables, 128, "DISCORD_INSTANCE_ID=%d", instance); - putenv(environmentVariables); - LOGFILE_INFO(LFT_DISCORD, "set environment variables: %s", environmentVariables); -} - -static void get_oauth2_token_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordOAuth2Token* token) { - LOGFILE_INFO(LFT_DISCORD, "> get_oauth2_token_callback returned %d", result); - if (result != DiscordResult_Ok) { return; } - LOGFILE_INFO(LFT_DISCORD, "OAuth2 token: %s", token->access_token); -} - -static void register_launch_command(void) { - char cmd[MAX_LAUNCH_CMD] = { 0 }; - int rc; -#if defined(_WIN32) || defined(_WIN64) - HMODULE hModule = GetModuleHandle(NULL); - if (hModule == NULL) { - LOGFILE_ERROR(LFT_DISCORD, "unable to retrieve absolute path!"); - return; - } - GetModuleFileName(hModule, cmd, sizeof(cmd)); -#else - char path[MAX_LAUNCH_CMD] = { 0 }; - snprintf(path, MAX_LAUNCH_CMD - 1, "/proc/%d/exe", getpid()); - rc = readlink(path, cmd, MAX_LAUNCH_CMD - 1); - if (rc <= 0) { - LOGFILE_ERROR(LFT_DISCORD, "unable to retrieve absolute path! rc = %d", rc); - return; - } -#endif - strncat(cmd, " --discord 1", MAX_LAUNCH_CMD - 1); - rc = app.activities->register_command(app.activities, cmd); - if (rc != DiscordResult_Ok) { - LOGFILE_ERROR(LFT_DISCORD, "register command failed %d", rc); - return; - } - LOGFILE_INFO(LFT_DISCORD, "cmd: %s", cmd); -} - -static void* ns_discord_dup_addr(u8 localIndex) { - void* address = malloc(sizeof(DiscordUserId)); - memcpy(address, &gNetworkUserIds[localIndex], sizeof(DiscordUserId)); - return address; -} - -static bool ns_discord_match_addr(void* addr1, void* addr2) { - return !memcmp(addr1, addr2, sizeof(u64)); -} - -static void ns_discord_update(void) { - if (!gDiscordInitialized) { return; } - - discord_activity_update_check(); - discord_lobby_update(); - DISCORD_REQUIRE(app.core->run_callbacks(app.core)); - discord_network_flush(); -} - -static bool ns_discord_initialize(enum NetworkType networkType, bool reconnecting) { - if (reconnecting) { return true; } -#ifdef DEBUG - set_instance_env_variable(); -#endif - - if (app.core != NULL) { - app.core->set_log_hook(app.core, DiscordLogLevel_Debug, NULL, discord_sdk_log_callback); - } - - if (!gDiscordInitialized) { - // set up discord params - struct DiscordCreateParams params = { 0 }; - DiscordCreateParamsSetDefault(¶ms); - params.client_id = applicationId; - params.flags = DiscordCreateFlags_NoRequireDiscord; - params.event_data = &app; - params.user_events = discord_user_initialize(); - params.activity_events = discord_activity_initialize(); - params.lobby_events = discord_lobby_initialize(); - - gCurLobbyId = 0; - gLobbyCreateRetry = false; - gLobbyCreateAttempts = 0; - gLobbyCreateAttemptElapsed = 0; - - int rc = DiscordCreate(DISCORD_VERSION, ¶ms, &app.core); - if (app.core != NULL) { - app.core->set_log_hook(app.core, DiscordLogLevel_Debug, NULL, discord_sdk_log_callback); - } - gDiscordFailed = false; - if (networkType != NT_NONE) { - DISCORD_REQUIRE(rc); - } else if (rc) { - LOGFILE_ERROR(LFT_DISCORD, "DiscordCreate failed: %d", rc); - djui_popup_create(DLANG(NOTIF, DISCORD_DETECT), 3); - gDiscordFailed = true; - return false; - } - - // set up manager pointers - if (app.core != NULL) { - app.users = app.core->get_user_manager(app.core); - app.achievements = app.core->get_achievement_manager(app.core); - app.activities = app.core->get_activity_manager(app.core); - app.application = app.core->get_application_manager(app.core); - app.lobbies = app.core->get_lobby_manager(app.core); - } - - // register launch params - register_launch_command(); - - // get oath2 token - app.application->get_oauth2_token(app.application, NULL, get_oauth2_token_callback); - - // set activity - discord_activity_update(false); - } - - // create lobby - if (networkType == NT_SERVER) { - discord_lobby_create(); - gActivityLock = true; - } else { - gActivityLock = false; - } - - gDiscordInitialized = true; - LOGFILE_INFO(LFT_DISCORD, "initialized"); - - return true; -} - -static void ns_discord_shutdown(bool reconnecting) { - if (reconnecting) { return; } - if (!gDiscordInitialized) { return; } - discord_lobby_leave(); - gActivityLock = false; - LOGFILE_INFO(LFT_DISCORD, "shutdown"); -} - -struct NetworkSystem gNetworkSystemDiscord = { - .initialize = ns_discord_initialize, - .get_id = ns_discord_get_id, - .get_id_str = ns_discord_get_id_str, - .save_id = ns_discord_save_id, - .clear_id = ns_discord_clear_id, - .dup_addr = ns_discord_dup_addr, - .match_addr = ns_discord_match_addr, - .update = ns_discord_update, - .send = ns_discord_network_send, - .shutdown = ns_discord_shutdown, - .requireServerBroadcast = false, - .name = "Discord", -}; diff --git a/src/pc/network/discord/discord_network.c b/src/pc/network/discord/discord_network.c deleted file mode 100644 index 381b3950..00000000 --- a/src/pc/network/discord/discord_network.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "discord_network.h" -#include "lobby.h" -#include "pc/logfile.h" - -int64_t gNetworkUserIds[MAX_PLAYERS] = { 0 }; - -u8 discord_user_id_to_local_index(int64_t userId) { - for (int i = 1; i < MAX_PLAYERS; i++) { - if (gNetworkPlayers[i].connected && gNetworkUserIds[i] == userId) { - return i; - } - } - return UNKNOWN_LOCAL_INDEX; -} - -int ns_discord_network_send(u8 localIndex, void* address, u8* data, u16 dataLength) { - if (!gDiscordInitialized) { return 1; } - if (gCurLobbyId == 0) { return 2; } - DiscordUserId userId = gNetworkUserIds[localIndex]; - if (localIndex == 0 && address != NULL) { userId = *(DiscordUserId*)address; } - DISCORD_REQUIRE(app.lobbies->send_network_message(app.lobbies, gCurLobbyId, userId, 0, data, dataLength)); - return 0; -} - -void discord_network_on_message(UNUSED void* eventData, UNUSED int64_t lobbyId, int64_t userId, UNUSED uint8_t channelId, uint8_t* data, uint32_t dataLength) { - gNetworkUserIds[0] = userId; - - u8 localIndex = UNKNOWN_LOCAL_INDEX; - for (int i = 1; i < MAX_PLAYERS; i++) { - if (gNetworkUserIds[i] == userId) { - localIndex = i; - break; - } - } - - network_receive(localIndex, &userId, (u8*)data, (u16)dataLength); -} - -void discord_network_flush(void) { - app.lobbies->flush_network(app.lobbies); -} - -s64 ns_discord_get_id(u8 localId) { - if (localId == 0) { return app.userId; } - return gNetworkUserIds[localId]; -} - -char* ns_discord_get_id_str(u8 localId) { - static char id_str[22] = { 0 }; - if (localId == UNKNOWN_LOCAL_INDEX) { - snprintf(id_str, 22, "???"); - } else { - snprintf(id_str, 22, "%lld", (long long int)ns_discord_get_id(localId)); - } - return id_str; -} - -void ns_discord_save_id(u8 localId, s64 networkId) { - SOFT_ASSERT(localId > 0); - SOFT_ASSERT(localId < MAX_PLAYERS); - gNetworkUserIds[localId] = (networkId == 0) ? gNetworkUserIds[0] : networkId; - LOGFILE_INFO(LFT_DISCORD, "saved user id %d == " DISCORD_ID_FORMAT, localId, gNetworkUserIds[localId]); -} - -void ns_discord_clear_id(u8 localId) { - if (localId == 0) { return; } - SOFT_ASSERT(localId < MAX_PLAYERS); - gNetworkUserIds[localId] = 0; - LOGFILE_INFO(LFT_DISCORD, "cleared user id %d == " DISCORD_ID_FORMAT, localId, gNetworkUserIds[localId]); -} - -void discord_network_init(int64_t lobbyId) { - DISCORD_REQUIRE(app.lobbies->connect_network(app.lobbies, lobbyId)); - DISCORD_REQUIRE(app.lobbies->open_network_channel(app.lobbies, lobbyId, 0, false)); - LOGFILE_INFO(LFT_DISCORD, "network initialized"); -} - -void discord_network_shutdown(void) { - if (gCurLobbyId == 0) { return; } - app.lobbies->flush_network(app.lobbies); - app.lobbies->disconnect_network(app.lobbies, gCurLobbyId); - app.lobbies->flush_network(app.lobbies); - LOGFILE_INFO(LFT_DISCORD, "shutdown network, lobby = " DISCORD_ID_FORMAT, gCurLobbyId); -} \ No newline at end of file diff --git a/src/pc/network/discord/discord_network.h b/src/pc/network/discord/discord_network.h deleted file mode 100644 index a4acb13b..00000000 --- a/src/pc/network/discord/discord_network.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DISCORD_NETWORK_H -#define DISCORD_NETWORK_H -#include "discord.h" - -extern int64_t gNetworkUserIds[MAX_PLAYERS]; - -u8 discord_user_id_to_local_index(int64_t userId); -int ns_discord_network_send(u8 localIndex, void* addr, u8* data, u16 dataLength); -void discord_network_on_message(UNUSED void* eventData, int64_t lobbyId, int64_t userId, uint8_t channelId, uint8_t* data, uint32_t dataLength); -void discord_network_flush(void); -s64 ns_discord_get_id(u8 localId); -char* ns_discord_get_id_str(u8 localId); -void ns_discord_save_id(u8 localId, s64 networkId); -void ns_discord_clear_id(u8 localId); -void discord_network_init(int64_t lobbyId); -void discord_network_shutdown(void); - -#endif \ No newline at end of file diff --git a/src/pc/network/discord/lobby.c b/src/pc/network/discord/lobby.c deleted file mode 100644 index f99cf533..00000000 --- a/src/pc/network/discord/lobby.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "lobby.h" -#include "activity.h" -#include "discord_network.h" -#include "pc/logfile.h" -#include "pc/utils/misc.h" -#include "pc/configfile.h" - -#define MAX_LOBBY_RETRY 5 -#define MAX_LOBBY_RETRY_WAIT_TIME 6 - -static bool isHosting = false; -DiscordLobbyId gCurLobbyId = 0; - -bool gLobbyCreateRetry = false; -u8 gLobbyCreateAttempts = 0; -f32 gLobbyCreateAttemptElapsed = 0; - -void discord_lobby_update(void) { - if (gCurLobbyId != 0) { return; } - if (!gLobbyCreateRetry) { return; } - f32 timeUntilRetry = (clock_elapsed() - gLobbyCreateAttemptElapsed); - if (timeUntilRetry < MAX_LOBBY_RETRY_WAIT_TIME) { return; } - gLobbyCreateRetry = false; - discord_lobby_create(); -} - -static void on_lobby_create_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordLobby* lobby) { - LOGFILE_INFO(LFT_DISCORD, "> on_lobby_create returned %d", (int)result); - - if (result != DiscordResult_Ok && gLobbyCreateAttempts < MAX_LOBBY_RETRY) { - LOGFILE_INFO(LFT_DISCORD, "rescheduling lobby creation"); - gLobbyCreateRetry = true; - gLobbyCreateAttempts++; - gLobbyCreateAttemptElapsed = clock_elapsed(); - return; - } - - DISCORD_REQUIRE(result); - LOGFILE_INFO(LFT_DISCORD, "Lobby id: " DISCORD_ID_FORMAT, lobby->id); - LOGFILE_INFO(LFT_DISCORD, "Lobby type: %u", lobby->type); - LOGFILE_INFO(LFT_DISCORD, "Lobby owner id: " DISCORD_ID_FORMAT, lobby->owner_id); - LOGFILE_INFO(LFT_DISCORD, "Lobby secret: %s", lobby->secret); - LOGFILE_INFO(LFT_DISCORD, "Lobby capacity: %u", lobby->capacity); - LOGFILE_INFO(LFT_DISCORD, "Lobby locked: %d", lobby->locked); - - gCurActivity.type = DiscordActivityType_Playing; - if (snprintf(gCurActivity.party.id, 128, DISCORD_ID_FORMAT, lobby->id) < 0) { - LOGFILE_ERROR(LFT_DISCORD, "truncating party id"); - } - gCurActivity.party.size.current_size = 1; - gCurActivity.party.size.max_size = configAmountofPlayers; - - char secretJoin[128] = ""; - if (snprintf(secretJoin, 128, DISCORD_ID_FORMAT ":%s", lobby->id, lobby->secret) < 0) { - LOGFILE_ERROR(LFT_DISCORD, "truncating secret"); - } - strcpy(gCurActivity.secrets.join, secretJoin); - - isHosting = true; - gCurLobbyId = lobby->id; - - discord_network_init(lobby->id); - discord_activity_update(true); -} - -static void on_lobby_update(UNUSED void* data, int64_t lobbyId) { - LOGFILE_INFO(LFT_DISCORD, "> on_lobby_update id: " DISCORD_ID_FORMAT, lobbyId); -} - -static void on_member_connect(UNUSED void* data, int64_t lobbyId, int64_t userId) { - LOGFILE_INFO(LFT_DISCORD, "> on_member_connect lobby: " DISCORD_ID_FORMAT ", user: " DISCORD_ID_FORMAT, lobbyId, userId); - gCurActivity.party.size.current_size++; - discord_activity_update(true); -} - -static void on_member_update(UNUSED void* data, int64_t lobbyId, int64_t userId) { - LOGFILE_INFO(LFT_DISCORD, "> on_member_update lobby: " DISCORD_ID_FORMAT ", user: " DISCORD_ID_FORMAT, lobbyId, userId); -} - -static void on_member_disconnect(UNUSED void* data, int64_t lobbyId, int64_t userId) { - LOGFILE_INFO(LFT_DISCORD, "> on_member_disconnect lobby: " DISCORD_ID_FORMAT ", user: " DISCORD_ID_FORMAT, lobbyId, userId); - u8 localIndex = discord_user_id_to_local_index(userId); - if (localIndex != UNKNOWN_LOCAL_INDEX && gNetworkPlayers[localIndex].connected) { - network_player_disconnected(gNetworkPlayers[localIndex].globalIndex); - } - gCurActivity.party.size.current_size--; - discord_activity_update(isHosting); -} - -void discord_lobby_create(void) { - struct IDiscordLobbyTransaction* txn = { 0 }; - - DISCORD_REQUIRE(app.lobbies->get_lobby_create_transaction(app.lobbies, &txn)); - txn->set_capacity(txn, MAX_PLAYERS); - txn->set_type(txn, DiscordLobbyType_Public); - //txn->set_metadata(txn, "a", "123"); - - app.lobbies->create_lobby(app.lobbies, txn, NULL, on_lobby_create_callback); -} - -static void on_lobby_leave_callback(UNUSED void* data, enum EDiscordResult result) { - LOGFILE_INFO(LFT_DISCORD, "> on_lobby_leave returned %d", result); - DISCORD_REQUIRE(result); -} - -void discord_lobby_leave(void) { - if (gCurLobbyId == 0) { return; } - - discord_network_shutdown(); - if (isHosting) { - app.lobbies->delete_lobby(app.lobbies, gCurLobbyId, NULL, on_lobby_leave_callback); - } else { - app.lobbies->disconnect_lobby(app.lobbies, gCurLobbyId, NULL, on_lobby_leave_callback); - } - - LOGFILE_INFO(LFT_DISCORD, "left lobby " DISCORD_ID_FORMAT, gCurLobbyId); - - if (snprintf(gCurActivity.party.id, 128, "%s", "none") < 0) { - LOGFILE_ERROR(LFT_DISCORD, "Truncating party id"); - } - gCurActivity.party.size.current_size = 1; - gCurActivity.party.size.max_size = 1; - discord_activity_update(gNetworkType == NT_SERVER); - - isHosting = false; - gCurLobbyId = 0; -} - -struct IDiscordLobbyEvents* discord_lobby_initialize(void) { - static struct IDiscordLobbyEvents events = { 0 }; - events.on_lobby_update = on_lobby_update; - events.on_member_connect = on_member_connect; - events.on_member_update = on_member_update; - events.on_member_disconnect = on_member_disconnect; - events.on_network_message = discord_network_on_message; - return &events; -} diff --git a/src/pc/network/discord/lobby.h b/src/pc/network/discord/lobby.h deleted file mode 100644 index 4e0d32d2..00000000 --- a/src/pc/network/discord/lobby.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DISCORD_LOBBY_H -#define DISCORD_LOBBY_H -#include "discord.h" - -extern DiscordLobbyId gCurLobbyId; - -extern bool gLobbyCreateRetry; -extern u8 gLobbyCreateAttempts; -extern f32 gLobbyCreateAttemptElapsed; - -void discord_lobby_update(void); -void discord_lobby_create(void); -void discord_lobby_leave(void); -struct IDiscordLobbyEvents* discord_lobby_initialize(void); - -#endif \ No newline at end of file diff --git a/src/pc/network/discord/user.c b/src/pc/network/discord/user.c deleted file mode 100644 index bd49c427..00000000 --- a/src/pc/network/discord/user.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "user.h" -#include "pc/configfile.h" -#include "pc/logfile.h" -#include "pc/crash_handler.h" - -static void on_current_user_update(UNUSED void* data) { - LOGFILE_INFO(LFT_DISCORD, "> on_current_user_update"); - struct DiscordUser user = { 0 }; - app.users->get_current_user(app.users, &user); - - // remember user id - app.userId = user.id; - gPcDebug.id = user.id; - - // copy over discord username if we haven't set one yet - if (configPlayerName[0] == '\0' && strlen(user.username) > 0) { - char* cname = configPlayerName; - char* dname = user.username; - for (int i = 0; i < MAX_PLAYER_STRING - 1; i++) { - if (*dname >= '!' && *dname <= '~') { - *cname = *dname; - cname++; - } - dname++; - } - } -} - -struct IDiscordUserEvents* discord_user_initialize(void) { - LOGFILE_INFO(LFT_DISCORD, "> discord_user_intitialize"); - static struct IDiscordUserEvents events = { 0 }; - events.on_current_user_update = on_current_user_update; - return &events; -} \ No newline at end of file diff --git a/src/pc/network/discord/user.h b/src/pc/network/discord/user.h deleted file mode 100644 index a3089192..00000000 --- a/src/pc/network/discord/user.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef DISCORD_USER_H -#define DISCORD_USER_H -#include "discord.h" - -struct IDiscordUserEvents* discord_user_initialize(void); - -#endif \ No newline at end of file diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 52c8b6e8..b55fec96 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -7,10 +7,6 @@ #include "behavior_table.h" #include "src/game/hardcoded.h" #include "src/game/scroll_targets.h" -#ifdef DISCORD_SDK -#include "discord/discord.h" -#include "discord/activity.h" -#endif #include "pc/configfile.h" #include "pc/cheats.h" #include "pc/djui/djui.h" @@ -31,6 +27,10 @@ #include "game/level_geo.h" #include "menu/intro_geo.h" +#ifdef DISCORD_SDK +#include "pc/discord/discord.h" +#endif + // fix warnings when including rendering_graph_node #undef near #undef far @@ -41,11 +41,7 @@ extern s16 sCurrPlayMode; extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; enum NetworkType gNetworkType = NT_NONE; -#ifdef DISCORD_SDK -struct NetworkSystem* gNetworkSystem = &gNetworkSystemDiscord; -#else struct NetworkSystem* gNetworkSystem = &gNetworkSystemSocket; -#endif #define LOADING_LEVEL_THRESHOLD 10 #define MAX_PACKETS_PER_SECOND_PER_PLAYER ((u16)100) @@ -80,6 +76,7 @@ struct ServerSettings gServerSettings = { .enablePlayersInLevelDisplay = 1, .enablePlayerList = 1, .headlessServer = 0, + .maxPlayers = MAX_PLAYERS, }; void network_set_system(enum NetworkSystemType nsType) { @@ -87,15 +84,9 @@ void network_set_system(enum NetworkSystemType nsType) { switch (nsType) { case NS_SOCKET: gNetworkSystem = &gNetworkSystemSocket; break; - -#ifdef DISCORD_SDK - case NS_DISCORD: gNetworkSystem = &gNetworkSystemDiscord; break; -#endif - #ifdef COOPNET case NS_COOPNET: gNetworkSystem = &gNetworkSystemCoopNet; break; #endif - default: gNetworkSystem = &gNetworkSystemSocket; LOG_ERROR("Unknown network system: %d", nsType); break; } } @@ -123,6 +114,7 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) { gServerSettings.shareLives = configShareLives; gServerSettings.enableCheats = configEnableCheats; gServerSettings.bubbleDeath = configBubbleDeath; + gServerSettings.maxPlayers = configAmountofPlayers; #if defined(RAPI_DUMMY) || defined(WAPI_DUMMY) gServerSettings.headlessServer = (inNetworkType == NT_SERVER); #else @@ -162,17 +154,15 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) { gChangeLevelTransition = gLevelValues.entryLevel; } -#ifdef DISCORD_SDK - if (gNetworkSystem == &gNetworkSystemDiscord) { - discord_activity_update(true); - } -#endif - djui_chat_box_create(); } configfile_save(configfile_name()); +#ifdef DISCORD_SDK + discord_activity_update(); +#endif + LOG_INFO("initialized"); return true; @@ -623,11 +613,6 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect gNetworkType = NT_NONE; } - -#ifdef DISCORD_SDK - network_set_system(NS_DISCORD); -#endif - if (exiting) { return; } // reset other stuff @@ -689,4 +674,8 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect gDjuiInMainMenu = true; djui_panel_main_create(NULL); } + +#ifdef DISCORD_SDK + discord_activity_update(); +#endif } diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 0d16e7e4..7f12e95e 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -36,7 +36,6 @@ extern struct MarioState gMarioStates[]; enum NetworkSystemType { NS_SOCKET, - NS_DISCORD, NS_COOPNET, NS_MAX, }; @@ -51,6 +50,8 @@ struct NetworkSystem { bool (*match_addr)(void* addr1, void* addr2); void (*update)(void); int (*send)(u8 localIndex, void* addr, u8* data, u16 dataLength); + void (*get_lobby_id)(char* destination, u32 destLength); + void (*get_lobby_secret)(char* destination, u32 destLength); void (*shutdown)(bool reconnecting); bool requireServerBroadcast; char* name; @@ -73,6 +74,7 @@ struct ServerSettings { u8 enablePlayersInLevelDisplay; u8 enablePlayerList; u8 headlessServer; + u8 maxPlayers; }; // Networking-specific externs diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 0bc501c3..ac1b4ed3 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -11,6 +11,9 @@ #include "game/object_helpers.h" #include "pc/lua/smlua_hooks.h" #include "lag_compensation.h" +#ifdef DISCORD_SDK +#include "pc/discord/discord.h" +#endif struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 }; struct NetworkPlayer *gNetworkPlayerLocal = NULL; @@ -311,6 +314,9 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode smlua_call_event_hooks_mario_param(HOOK_ON_PLAYER_CONNECTED, &gMarioStates[localIndex]); +#ifdef DISCORD_SDK + discord_activity_update(); +#endif return localIndex; } @@ -360,6 +366,10 @@ u8 network_player_disconnected(u8 globalIndex) { memset(np, 0, sizeof(struct NetworkPlayer)); +#ifdef DISCORD_SDK + discord_activity_update(); +#endif + return i; } return UNKNOWN_GLOBAL_INDEX; @@ -428,7 +438,7 @@ void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, } // If this machine's player changed to a different location, then all of the other np locations are no longer valid - for (u32 i = 1; i < configAmountofPlayers; i++) { + for (u32 i = 1; i < MAX_PLAYERS; i++) { struct NetworkPlayer* npi = &gNetworkPlayers[i]; if ((!npi->connected) || npi == gNetworkPlayerLocal) { continue; } npi->currPositionValid = false; diff --git a/src/pc/network/network_utils.c b/src/pc/network/network_utils.c index 7be8fbc1..18b6b1ff 100644 --- a/src/pc/network/network_utils.c +++ b/src/pc/network/network_utils.c @@ -1,6 +1,5 @@ #include #include "network_utils.h" -#include "discord/discord.h" #include "game/mario_misc.h" u8 network_global_index_from_local(u8 localIndex) { @@ -23,15 +22,6 @@ u8 network_local_index_from_global(u8 globalIndex) { return globalIndex + ((globalIndex < gNetworkPlayerLocal->globalIndex) ? 1 : 0); } -#ifdef DISCORD_SDK -char* network_discord_id_from_local_index(u8 localIndex) { - if (gNetworkSystem == &gNetworkSystemDiscord) { return gNetworkSystem->get_id_str(localIndex); } -#else -char* network_discord_id_from_local_index(UNUSED u8 localIndex) { -#endif - return NULL; -} - bool network_is_server(void) { return gNetworkType == NT_SERVER; } diff --git a/src/pc/network/network_utils.h b/src/pc/network/network_utils.h index f1eabed9..de7de04d 100644 --- a/src/pc/network/network_utils.h +++ b/src/pc/network/network_utils.h @@ -7,8 +7,6 @@ u8 network_global_index_from_local(u8 localIndex); u8 network_local_index_from_global(u8 globalIndex); -char* network_discord_id_from_local_index(u8 localIndex); - bool network_is_server(void); bool network_is_moderator(void); diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 2a9cc1af..c2065250 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -80,7 +80,7 @@ void network_send_join(struct Packet* joinRequestPacket) { // figure out id u8 globalIndex = joinRequestPacket->localIndex; if (globalIndex == UNKNOWN_LOCAL_INDEX) { - for (u32 i = 1; i < configAmountofPlayers; i++) { + for (u32 i = 1; i < MAX_PLAYERS; i++) { if (!gNetworkPlayers[i].connected) { globalIndex = i; break; @@ -119,6 +119,7 @@ void network_send_join(struct Packet* joinRequestPacket) { packet_write(&p, &gServerSettings.enableCheats, sizeof(u8)); packet_write(&p, &gServerSettings.bubbleDeath, sizeof(u8)); packet_write(&p, &gServerSettings.headlessServer, sizeof(u8)); + packet_write(&p, &gServerSettings.maxPlayers, sizeof(u8)); packet_write(&p, eeprom, sizeof(u8) * 512); u8 modCount = string_linked_list_count(&gRegisteredMods); @@ -183,6 +184,7 @@ void network_receive_join(struct Packet* p) { packet_read(p, &gServerSettings.enableCheats, sizeof(u8)); packet_read(p, &gServerSettings.bubbleDeath, sizeof(u8)); packet_read(p, &gServerSettings.headlessServer, sizeof(u8)); + packet_read(p, &gServerSettings.maxPlayers, sizeof(u8)); packet_read(p, eeprom, sizeof(u8) * 512); packet_read(p, &modCount, sizeof(u8)); diff --git a/src/pc/network/socket/socket.c b/src/pc/network/socket/socket.c index f1b0a552..3fc16460 100644 --- a/src/pc/network/socket/socket.c +++ b/src/pc/network/socket/socket.c @@ -180,6 +180,14 @@ static int ns_socket_send(u8 localIndex, void* address, u8* data, u16 dataLength return rc; } +static void ns_socket_get_lobby_id(char* destination, u32 destLength) { + snprintf(destination, destLength, "%s", ""); // TODO: we can probably hook this up +} + +static void ns_socket_get_lobby_secret(char* destination, u32 destLength) { + snprintf(destination, destLength, "%s", ""); // TODO: we can probably hook this up +} + static void ns_socket_shutdown(UNUSED bool reconnecting) { socket_shutdown(sCurSocket); sCurSocket = INVALID_SOCKET; @@ -190,16 +198,18 @@ static void ns_socket_shutdown(UNUSED bool reconnecting) { } struct NetworkSystem gNetworkSystemSocket = { - .initialize = ns_socket_initialize, - .get_id = ns_socket_get_id, - .get_id_str = ns_socket_get_id_str, - .save_id = ns_socket_save_id, - .clear_id = ns_socket_clear_id, - .dup_addr = ns_socket_dup_addr, - .match_addr = ns_socket_match_addr, - .update = ns_socket_update, - .send = ns_socket_send, - .shutdown = ns_socket_shutdown, + .initialize = ns_socket_initialize, + .get_id = ns_socket_get_id, + .get_id_str = ns_socket_get_id_str, + .save_id = ns_socket_save_id, + .clear_id = ns_socket_clear_id, + .dup_addr = ns_socket_dup_addr, + .match_addr = ns_socket_match_addr, + .update = ns_socket_update, + .send = ns_socket_send, + .get_lobby_id = ns_socket_get_lobby_id, + .get_lobby_secret = ns_socket_get_lobby_secret, + .shutdown = ns_socket_shutdown, .requireServerBroadcast = true, - .name = "Socket", + .name = "Socket", }; diff --git a/src/pc/network/version.h b/src/pc/network/version.h index 72842593..9fd68d58 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -2,8 +2,8 @@ #define VERSION_H #define VERSION_TEXT "beta" -#define VERSION_NUMBER 33 -#define MINOR_VERSION_NUMBER 1 +#define VERSION_NUMBER 34 +#define MINOR_VERSION_NUMBER 0 #define PATCH_VERSION_NUMBER 0 #define MAX_VERSION_LENGTH 10 diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index a70363b2..0f2bb4de 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -43,9 +43,6 @@ #include "src/bass_audio/bass_audio_helpers.h" #include "pc/lua/utils/smlua_audio_utils.h" -#ifdef DISCORDRPC -#include "pc/discord/discordrpc.h" -#endif #include "pc/network/version.h" #include "pc/network/socket/domain_res.h" #include "pc/network/network_player.h" @@ -60,6 +57,10 @@ #include "menu/intro_geo.h" +#ifdef DISCORD_SDK +#include "pc/discord/discord.h" +#endif + OSMesg D_80339BEC; OSMesgQueue gSIEventMesgQueue; @@ -246,9 +247,6 @@ void audio_shutdown(void) { } void game_deinit(void) { -#ifdef DISCORDRPC - discord_shutdown(); -#endif configfile_save(configfile_name()); controller_shutdown(); audio_custom_shutdown(); @@ -396,14 +394,10 @@ void main_func(void) { } #endif -#ifdef DISCORDRPC - discord_init(); -#endif - while (true) { wm_api->main_loop(produce_one_frame); -#ifdef DISCORDRPC - discord_update_rich_presence(); +#ifdef DISCORD_SDK + discord_update(); #endif #ifdef DEBUG fflush(stdout);