mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
Ripped out discord network system, started re-adding invites
This commit is contained in:
parent
8e2cd25617
commit
4566b7ee14
49 changed files with 525 additions and 1248 deletions
32
Makefile
32
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
|
||||
|
|
|
@ -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<br />\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<br />\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'
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1690,7 +1690,8 @@
|
|||
| Identifier | Value |
|
||||
| :--------- | :---- |
|
||||
| NS_SOCKET | 0 |
|
||||
| NS_DISCORD | 1 |
|
||||
| NS_COOPNET | 1 |
|
||||
| NS_MAX | 2 |
|
||||
|
||||
### [enum PlayerInteractions](#PlayerInteractions)
|
||||
| Identifier | Value |
|
||||
|
|
|
@ -8265,26 +8265,6 @@
|
|||
<br />
|
||||
|
||||
|
||||
## [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:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [network_get_player_text_color_string](#network_get_player_text_color_string)
|
||||
|
||||
### Lua Example
|
||||
|
|
|
@ -7251,6 +7251,12 @@
|
|||
|
||||
<br />
|
||||
|
||||
---
|
||||
# functions from smlua_deprecated.h
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
---
|
||||
# functions from smlua_level_utils.h
|
||||
|
||||
|
|
|
@ -1096,7 +1096,6 @@
|
|||
<br />
|
||||
|
||||
- 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 @@
|
|||
|
||||
<br />
|
||||
|
||||
- smlua_deprecated.h
|
||||
|
||||
<br />
|
||||
|
||||
- smlua_level_utils.h
|
||||
- [level_register](functions-4.md#level_register)
|
||||
- [smlua_level_util_get_info](functions-4.md#smlua_level_util_get_info)
|
||||
|
|
|
@ -2181,6 +2181,7 @@
|
|||
| enablePlayerList | `integer` | |
|
||||
| enablePlayersInLevelDisplay | `integer` | |
|
||||
| headlessServer | `integer` | |
|
||||
| maxPlayers | `integer` | |
|
||||
| playerInteractions | [enum PlayerInteractions](constants.md#enum-PlayerInteractions) | |
|
||||
| playerKnockbackStrength | `integer` | |
|
||||
| shareLives | `integer` | |
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
|
|
159
src/pc/discord/discord.c
Normal file
159
src/pc/discord/discord.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include "discord.h"
|
||||
#include "pc/djui/djui.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#include <winuser.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#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));
|
||||
}
|
|
@ -1,22 +1,14 @@
|
|||
#ifndef DISCORD_H
|
||||
#define DISCORD_H
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#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 <Windows.h>
|
||||
#else
|
||||
#define DISCORD_ID_FORMAT "%ld"
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
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);
|
152
src/pc/discord/discord_activity.c
Normal file
152
src/pc/discord/discord_activity.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#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 <windows.h>
|
||||
# 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 <dlfcn.h>
|
||||
# define DISCORDLIBEXT ".dylib"
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) // lets make the bold assumption for FreeBSD
|
||||
# include <dlfcn.h>
|
||||
# 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);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#ifndef DISCORDRPC_H
|
||||
#define DISCORDRPC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
5
src/pc/lua/utils/smlua_deprecated.c
Normal file
5
src/pc/lua/utils/smlua_deprecated.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "types.h"
|
||||
|
||||
char* network_discord_id_from_local_index(UNUSED u8 localIndex) {
|
||||
return NULL;
|
||||
}
|
3
src/pc/lua/utils/smlua_deprecated.h
Normal file
3
src/pc/lua/utils/smlua_deprecated.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
char* network_discord_id_from_local_index(u8 localIndex);
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 <windows.h>
|
||||
#include <winuser.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#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",
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef DISCORD_USER_H
|
||||
#define DISCORD_USER_H
|
||||
#include "discord.h"
|
||||
|
||||
struct IDiscordUserEvents* discord_user_initialize(void);
|
||||
|
||||
#endif
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue