diff --git a/Minecraft.Client/CMakeLists.txt b/Minecraft.Client/CMakeLists.txt index d4ac93aa..eaccec85 100644 --- a/Minecraft.Client/CMakeLists.txt +++ b/Minecraft.Client/CMakeLists.txt @@ -35,6 +35,7 @@ target_include_directories(Minecraft.Client "${CMAKE_BINARY_DIR}/generated/" # This is for the generated BuildVer.h "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/Iggy/include" + "${CMAKE_CURRENT_SOURCE_DIR}/Windows64/Discord/inc" "${CMAKE_SOURCE_DIR}/include/" ) target_compile_definitions(Minecraft.Client PRIVATE @@ -58,15 +59,23 @@ target_link_libraries(Minecraft.Client XInput9_1_0 wsock32 legacy_stdio_definitions - $<$: # Debug 4J libraries + $<$: + # Debug 4J libraries "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Input_d.lib" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Storage_d.lib" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC_d.lib" + # Debug Discord libraries + "${CMAKE_CURRENT_SOURCE_DIR}/Windows64/Discord/libs/discord-rpc_d.lib" > - $<$>: # Release 4J libraries + $<$>: + # Release 4J libraries "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Input.lib" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Storage.lib" "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC.lib" + "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC.lib" + "${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC.lib" + # Release Discord libraries + "${CMAKE_CURRENT_SOURCE_DIR}/Windows64/Discord/libs/discord-rpc.lib" > ) diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index c1b3eb03..d6bdca65 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -73,6 +73,10 @@ #include "..\..\..\Minecraft.World\StringHelpers.h" +#ifdef _WINDOWS64 +#include "..\Windows64\Windows64_DiscordPresence.h" +#endif + //CMinecraftApp app; unsigned int CMinecraftApp::m_uiLastSignInData = 0; @@ -3146,11 +3150,19 @@ void CMinecraftApp::HandleXuiActions(void) { if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif } } } @@ -3163,11 +3175,19 @@ void CMinecraftApp::HandleXuiActions(void) { if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #endif } } } @@ -3228,11 +3248,19 @@ void CMinecraftApp::HandleXuiActions(void) { if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif } } } @@ -3245,11 +3273,19 @@ void CMinecraftApp::HandleXuiActions(void) { if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(iPlayer,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #endif } } } @@ -3376,12 +3412,20 @@ void CMinecraftApp::HandleXuiActions(void) if(g_NetworkManager.IsLocalGame()) { app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); - ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif } else { app.SetRichPresenceContext(j,CONTEXT_GAME_STATE_BLANK); - ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(j,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif } TelemetryManager->RecordLevelExit(j, eSen_LevelExitStatus_Exited); } @@ -3392,11 +3436,19 @@ void CMinecraftApp::HandleXuiActions(void) app.SetRichPresenceContext(i,CONTEXT_GAME_STATE_BLANK); if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #endif } TelemetryManager->RecordLevelExit(i, eSen_LevelExitStatus_Exited); } diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index edd4b2fb..70828d7b 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -44,6 +44,7 @@ #ifdef _WINDOWS64 #include "..\..\Windows64\Network\WinsockNetLayer.h" #include "..\..\Windows64\Windows64_Xuid.h" +#include "..\..\Windows64\Windows64_DiscordPresence.h" #endif // Global instance @@ -457,13 +458,41 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame app.SetRichPresenceContext(primaryPad,CONTEXT_GAME_STATE_BLANK); if (GetPlayerCount() > 1) // Are we offline or online, and how many players are there { - if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); - else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER,false); + if (IsLocalGame()) + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif + } + else + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif + } } else { - if(IsLocalGame()) ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); - else ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + if(IsLocalGame()) + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #endif + } + else + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(primaryPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #endif + } } @@ -537,8 +566,22 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame if( ProfileManager.IsSignedIn(idx) && !connection->isClosed() ) { app.SetRichPresenceContext(idx,CONTEXT_GAME_STATE_BLANK); - if (IsLocalGame()) ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); - else ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYER,false); + if (IsLocalGame()) + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif + } + else + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(idx,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif + } } else { @@ -1624,13 +1667,41 @@ void CGameNetworkManager::PlayerJoining( INetworkPlayer *pNetworkPlayer ) app.SetRichPresenceContext(iPad,CONTEXT_GAME_STATE_BLANK); if (multiplayer) { - if (localgame) ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYEROFFLINE, false); - else ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER, false); + if (localgame) + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYEROFFLINE, false); + #endif + } + else + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER, false); + #endif + } } else { - if (localgame) ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE, false); - else ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER_1P, false); + if (localgame) + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE, false); + #endif + } + else + { + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MULTIPLAYER_1P, false); + #endif + } } } } @@ -1660,7 +1731,11 @@ void CGameNetworkManager::PlayerLeaving( INetworkPlayer *pNetworkPlayer ) { if( pNetworkPlayer->IsLocal() ) { - ProfileManager.SetCurrentGameActivity(pNetworkPlayer->GetUserIndex(),CONTEXT_PRESENCE_IDLE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_IDLE); + #else + ProfileManager.SetCurrentGameActivity(pNetworkPlayer->GetUserIndex(),CONTEXT_PRESENCE_IDLE,false); + #endif TelemetryManager->RecordPlayerSessionExit(pNetworkPlayer->GetUserIndex(), app.GetDisconnectReason()); } diff --git a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp index db388829..b95ae7da 100644 --- a/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_MainMenu.cpp @@ -10,6 +10,10 @@ #include #endif +#ifdef _WINDOWS64 +#include "..\..\Windows64\Windows64_DiscordPresence.h" +#endif + Random *UIScene_MainMenu::random = new Random(); EUIScene UIScene_MainMenu::eNavigateWhenReady = static_cast(-1); @@ -166,7 +170,11 @@ void UIScene_MainMenu::handleGainFocus(bool navBack) // For returning to menus after exiting a game. if (ProfileManager.IsSignedIn(iPad) ) { - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif } } } @@ -540,7 +548,11 @@ int UIScene_MainMenu::MustSignInReturned(void *pParam, int iPad, C4JStorage::EMe // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #endif } } } @@ -648,8 +660,11 @@ int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue, if(bContinue) { // 4J-JEV: Don't we only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); - + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif #if TO_BE_IMPLEMENTED if(app.GetTMSDLCInfoRead()) #endif @@ -690,7 +705,11 @@ int UIScene_MainMenu::HelpAndOptions_SignInReturned(void *pParam,bool bContinue, // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #endif } } } @@ -719,7 +738,12 @@ int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, in if(bContinue) { // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif UINT uiIDA[1] = { IDS_OK }; @@ -902,7 +926,11 @@ int UIScene_MainMenu::CreateLoad_SignInReturned(void *pParam, bool bContinue, in // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #endif } } @@ -921,7 +949,11 @@ int UIScene_MainMenu::Leaderboards_SignInReturned(void *pParam,bool bContinue,in if(bContinue) { // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif UINT uiIDA[1] = { IDS_OK }; @@ -972,7 +1004,11 @@ int UIScene_MainMenu::Leaderboards_SignInReturned(void *pParam,bool bContinue,in // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #endif } } @@ -992,7 +1028,11 @@ int UIScene_MainMenu::Achievements_SignInReturned(void *pParam,bool bContinue,in { pClass->m_bIgnorePress=false; // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif XShowAchievementsUI( ProfileManager.GetPrimaryPad() ); } @@ -1006,7 +1046,11 @@ int UIScene_MainMenu::Achievements_SignInReturned(void *pParam,bool bContinue,in // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #endif } } @@ -1025,7 +1069,11 @@ int UIScene_MainMenu::UnlockFullGame_SignInReturned(void *pParam,bool bContinue, if (bContinue) { // 4J-JEV: We only need to update rich-presence if the sign-in status changes. - ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(iPad, CONTEXT_PRESENCE_MENUS, false); + #endif pClass->RunUnlockOrDLC(iPad); } @@ -1039,7 +1087,11 @@ int UIScene_MainMenu::UnlockFullGame_SignInReturned(void *pParam,bool bContinue, // if the user is valid, we should set the presence if(ProfileManager.IsSignedIn(i)) { - ProfileManager.SetCurrentGameActivity(i,CONTEXT_PRESENCE_MENUS,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MENUS); + #else + ProfileManager.SetCurrentGameActivity(i, CONTEXT_PRESENCE_MENUS, false); + #endif } } diff --git a/Minecraft.Client/LocalPlayer.cpp b/Minecraft.Client/LocalPlayer.cpp index 00b1761b..bb897754 100644 --- a/Minecraft.Client/LocalPlayer.cpp +++ b/Minecraft.Client/LocalPlayer.cpp @@ -56,6 +56,10 @@ #ifndef _DURANGO #include "..\Minecraft.World\CommonStats.h" #endif + +#ifdef _WINDOWS64 +#include "Windows64\Windows64_DiscordPresence.h" +#endif extern ConsoleUIController ui; @@ -507,7 +511,11 @@ void LocalPlayer::aiStep() // Check if the player is idle and the rich presence needs updated if( !m_bIsIdle && InputManager.GetIdleSeconds( m_iPad ) > PLAYER_IDLE_TIME ) { - ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_IDLE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_IDLE); + #else + ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_IDLE,false); + #endif m_bIsIdle = true; } else if ( m_bIsIdle && InputManager.GetIdleSeconds( m_iPad ) < PLAYER_IDLE_TIME ) @@ -518,22 +526,38 @@ void LocalPlayer::aiStep() // only do it for this player here - each player will run this code if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYEROFFLINE); + #else + ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYEROFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER); + #else + ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER,false); + #endif } } else { if(g_NetworkManager.IsLocalGame()) { - ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE); + #else + ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE,false); + #endif } else { - ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #ifdef _WINDOWS64 + g_DiscordPresence.SetCurrentGameActivity(CONTEXT_PRESENCE_MULTIPLAYER_1P); + #else + ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER_1P,false); + #endif } } updateRichPresence(); diff --git a/Minecraft.Client/Windows64/Discord/inc/discord_register.h b/Minecraft.Client/Windows64/Discord/inc/discord_register.h new file mode 100644 index 00000000..16fb42f3 --- /dev/null +++ b/Minecraft.Client/Windows64/Discord/inc/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/Minecraft.Client/Windows64/Discord/inc/discord_rpc.h b/Minecraft.Client/Windows64/Discord/inc/discord_rpc.h new file mode 100644 index 00000000..3e1441e0 --- /dev/null +++ b/Minecraft.Client/Windows64/Discord/inc/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +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 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/Minecraft.Client/Windows64/Discord/libs/discord-rpc.lib b/Minecraft.Client/Windows64/Discord/libs/discord-rpc.lib new file mode 100644 index 00000000..f772371f Binary files /dev/null and b/Minecraft.Client/Windows64/Discord/libs/discord-rpc.lib differ diff --git a/Minecraft.Client/Windows64/Discord/libs/discord-rpc_d.lib b/Minecraft.Client/Windows64/Discord/libs/discord-rpc_d.lib new file mode 100644 index 00000000..06227e8d Binary files /dev/null and b/Minecraft.Client/Windows64/Discord/libs/discord-rpc_d.lib differ diff --git a/Minecraft.Client/Windows64/Discord/res/minecraft.png b/Minecraft.Client/Windows64/Discord/res/minecraft.png new file mode 100644 index 00000000..f97b7bdf Binary files /dev/null and b/Minecraft.Client/Windows64/Discord/res/minecraft.png differ diff --git a/Minecraft.Client/Windows64/GameConfig/Minecraft.spa.h b/Minecraft.Client/Windows64/GameConfig/Minecraft.spa.h index a7c262c8..59f2274b 100644 --- a/Minecraft.Client/Windows64/GameConfig/Minecraft.spa.h +++ b/Minecraft.Client/Windows64/GameConfig/Minecraft.spa.h @@ -1,13 +1,3 @@ -//////////////////////////////////////////////////////////////////// -// -// C:\Work\4J\Mojang\Minecraft\Minecraft360-dev\Minecraft.Client\Xbox\GameConfig\Minecraft.spa.h -// -// Auto-generated on Thursday, 10 May 2012 at 21:23:22 -// Xbox LIVE Game Config project version 1.0.173.0 -// SPA Compiler version 1.0.0.0 -// -//////////////////////////////////////////////////////////////////// - #ifndef __MINECRAFT_SPA_H__ #define __MINECRAFT_SPA_H__ @@ -21,20 +11,10 @@ extern "C" { #define TITLEID_MINECRAFT 0x584111F7 -// // Context ids -// -// These values are passed as the dwContextId to XUserSetContext. -// #define CONTEXT_GAME_STATE 0 -// -// Context values -// -// These values are passed as the dwContextValue to XUserSetContext. -// - // Values for CONTEXT_GAME_STATE #define CONTEXT_GAME_STATE_BLANK 0 @@ -47,10 +27,10 @@ extern "C" { #define CONTEXT_GAME_STATE_NETHER 7 #define CONTEXT_GAME_STATE_CD 8 #define CONTEXT_GAME_STATE_MAP 9 -#define CONTEXT_GAME_STATE_ENCHANTING 5 //TODO 10 -#define CONTEXT_GAME_STATE_BREWING 5 //TODO 11 -#define CONTEXT_GAME_STATE_ANVIL 6 //TODO 12 -#define CONTEXT_GAME_STATE_TRADING 0 //TODO 13 +#define CONTEXT_GAME_STATE_ENCHANTING 10 +#define CONTEXT_GAME_STATE_BREWING 11 +#define CONTEXT_GAME_STATE_ANVIL 12 +#define CONTEXT_GAME_STATE_TRADING 13 // Values for X_CONTEXT_PRESENCE @@ -69,9 +49,6 @@ extern "C" { // // Property ids // -// These values are passed as the dwPropertyId value to XUserSetProperty -// and as the dwPropertyId value in the XUSER_PROPERTY structure. -// #define PROPERTY_LOCALE 0x10000008 #define PROPERTY_KILLS_ZOMBIE 0x1000000A @@ -117,10 +94,6 @@ extern "C" { // // Achievement ids // -// These values are used in the dwAchievementId member of the -// XUSER_ACHIEVEMENT structure that is used with -// XUserWriteAchievements and XUserCreateAchievementEnumerator. -// #define ACHIEVEMENT_01 1 #define ACHIEVEMENT_02 2 @@ -154,9 +127,6 @@ extern "C" { // // Stats view ids // -// These are used in the dwViewId member of the XUSER_STATS_SPEC structure -// passed to the XUserReadStats* and XUserCreateStatsEnumerator* functions. -// // Skill leaderboards for ranked game modes diff --git a/Minecraft.Client/Windows64/Windows64_App.cpp b/Minecraft.Client/Windows64/Windows64_App.cpp index 369e2909..b2c9fc1e 100644 --- a/Minecraft.Client/Windows64/Windows64_App.cpp +++ b/Minecraft.Client/Windows64/Windows64_App.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Windows64_DiscordPresence.h" #include "..\Common\Consoles_App.h" #include "..\User.h" #include "..\..\Minecraft.Client\Minecraft.h" @@ -19,7 +20,7 @@ CConsoleMinecraftApp::CConsoleMinecraftApp() : CMinecraftApp() void CConsoleMinecraftApp::SetRichPresenceContext(int iPad, int contextId) { - ProfileManager.SetRichPresenceContextValue(iPad,CONTEXT_GAME_STATE,contextId); + g_DiscordPresence.SetPresenceContext(contextId); } void CConsoleMinecraftApp::StoreLaunchData() diff --git a/Minecraft.Client/Windows64/Windows64_DiscordPresence.cpp b/Minecraft.Client/Windows64/Windows64_DiscordPresence.cpp new file mode 100644 index 00000000..cb139f7c --- /dev/null +++ b/Minecraft.Client/Windows64/Windows64_DiscordPresence.cpp @@ -0,0 +1,163 @@ +#include "stdafx.h" + +#include +#include +#include "Windows64_DiscordPresence.h" + +#include "../../Minecraft.World/StringHelpers.h" +#include "MultiPlayerLevel.h" +#include "../Minecraft.World/LevelData.h" + +DiscordPresence g_DiscordPresence; +static DiscordRichPresence presence; + +void DiscordPresence::Initialise() +{ + app.DebugPrintf("Initialising Discord Presence...\n"); + + DiscordEventHandlers handlers; + memset(&handlers, 0, sizeof(handlers)); + memset(&presence, 0, sizeof(presence)); + + handlers.ready = [](const DiscordUser* request) + { + app.DebugPrintf("Discord Ready!\n"); + }; + + handlers.errored = [](int errorCode, const char* message) + { + app.DebugPrintf("Discord Errored (%d): %s\n", errorCode, convStringToWstring(message).c_str()); + }; + + handlers.disconnected = [](int errorCode, const char* message) + { + app.DebugPrintf("Discord Disconnected (%d): %s\n", errorCode, convStringToWstring(message).c_str()); + }; + + Discord_Initialize("784487734748119067", &handlers, 1, nullptr); + + app.DebugPrintf("Initialised Discord Presence...\n"); +} + +void DiscordPresence::Shutdown() +{ + app.DebugPrintf("Shutting down Discord Presence...\n"); + + memset(&presence, 0, sizeof(presence)); + Discord_Shutdown(); +} + +void DiscordPresence::Tick() +{ + Discord_RunCallbacks(); +} + +void DiscordPresence::SetPresenceContext(int state) +{ + const char* stateStr = ""; + + switch(state) + { + case CONTEXT_GAME_STATE_BLANK: + stateStr = "Enjoying the view!"; + break; + case CONTEXT_GAME_STATE_RIDING_PIG: + stateStr = "Riding a pig"; + break; + case CONTEXT_GAME_STATE_RIDING_MINECART: + stateStr = "Riding a minecart"; + break; + case CONTEXT_GAME_STATE_BOATING: + stateStr = "In a boat"; + break; + case CONTEXT_GAME_STATE_FISHING: + stateStr = "Fishing"; + break; + case CONTEXT_GAME_STATE_CRAFTING: + stateStr = "Crafting"; + break; + case CONTEXT_GAME_STATE_FORGING: + stateStr = "Forging"; + break; + case CONTEXT_GAME_STATE_NETHER: + stateStr = "Into the Nether"; + break; + case CONTEXT_GAME_STATE_CD: + stateStr = "Listening to a disc"; + break; + case CONTEXT_GAME_STATE_MAP: + stateStr = "Looking at a map"; + break; + case CONTEXT_GAME_STATE_ENCHANTING: + stateStr = "Enchanting"; + break; + case CONTEXT_GAME_STATE_BREWING: + stateStr = "Brewing a potion"; + break; + case CONTEXT_GAME_STATE_ANVIL: + stateStr = "Working at the Anvil"; + break; + case CONTEXT_GAME_STATE_TRADING: + stateStr = "Meeting the neighbours"; + break; + default: + stateStr = ""; + break; + } + + presence.state = stateStr; + + Discord_UpdatePresence(&presence); +} + +void DiscordPresence::SetCurrentGameActivity(int details) +{ + static char finalDetails[64]; + const char* detailsStr = ""; + const char* gameTypeStr = ""; + + Minecraft* pMinecraft = Minecraft::GetInstance(); + if (pMinecraft->level != nullptr) + { + GameType* gameType = pMinecraft->level->getLevelData()->getGameType(); + + if (gameType == GameType::SURVIVAL) + gameTypeStr = "Survival Mode"; + else if (gameType == GameType::CREATIVE) + gameTypeStr = "Creative Mode"; + else if (gameType == GameType::ADVENTURE) + gameTypeStr = "Adventure Mode"; + else + gameTypeStr = "Unknown Mode"; + } + + switch(details) + { + case CONTEXT_PRESENCE_IDLE: + detailsStr = "Idle"; + break; + case CONTEXT_PRESENCE_MENUS: + detailsStr = "In the menus"; + break; + case CONTEXT_PRESENCE_MULTIPLAYER: + detailsStr = "Playing Multiplayer - %s"; + break; + case CONTEXT_PRESENCE_MULTIPLAYEROFFLINE: + detailsStr = "Offline Multiplayer - %s"; + break; + case CONTEXT_PRESENCE_MULTIPLAYER_1P: + detailsStr = "Playing Alone - %s"; + break; + case CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE: + detailsStr = "Offline Alone - %s"; + break; + default: + detailsStr = ""; + break; + } + + snprintf(finalDetails, sizeof(finalDetails), detailsStr, gameTypeStr); + presence.details = finalDetails; + + Discord_UpdatePresence(&presence); +} \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Windows64_DiscordPresence.h b/Minecraft.Client/Windows64/Windows64_DiscordPresence.h new file mode 100644 index 00000000..bc722407 --- /dev/null +++ b/Minecraft.Client/Windows64/Windows64_DiscordPresence.h @@ -0,0 +1,15 @@ +#pragma once + +class DiscordPresence +{ +public: + void Initialise(); + void Shutdown(); + + void Tick(); + + void SetPresenceContext(int state); + void SetCurrentGameActivity(int details); +}; + +extern DiscordPresence g_DiscordPresence; \ No newline at end of file diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index cb7a7365..9fec2b91 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -51,6 +51,7 @@ #include "Network\WinsockNetLayer.h" #include "Windows64_Xuid.h" #include "Common/UI/UI.h" +#include "Windows64_DiscordPresence.h" // Forward-declare the internal Renderer class and its global instance from 4J_Render_PC_d.lib. // C4JRender (RenderManager) is a stateless wrapper — all D3D state lives in InternalRenderManager. @@ -780,7 +781,6 @@ void SeedEditBox() g_hWnd, reinterpret_cast(DlgProc)); } - //--------------------------------------------------------------------------- LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam) { @@ -1325,6 +1325,7 @@ static Minecraft* InitialiseMinecraftRuntime() app.InitGameSettings(); app.InitialiseTips(); + g_DiscordPresence.Initialise(); return pMinecraft; } @@ -1732,6 +1733,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, ui.tick(); ui.render(); + g_DiscordPresence.Tick(); + pMinecraft->gameRenderer->ApplyGammaPostProcess(); #if 0 @@ -1975,8 +1978,10 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, Vec3::resetPool(); } + // Shutdown discord presence + g_DiscordPresence.Shutdown(); + // Free resources, unregister custom classes, and exit. - // app.Uninit(); CleanupDevice(); return 0; } diff --git a/Minecraft.Client/cmake/sources/Windows.cmake b/Minecraft.Client/cmake/sources/Windows.cmake index adc39947..7dbb14ef 100644 --- a/Minecraft.Client/cmake/sources/Windows.cmake +++ b/Minecraft.Client/cmake/sources/Windows.cmake @@ -346,6 +346,8 @@ set(_MINECRAFT_CLIENT_WINDOWS_WINDOWS64 "${BASE_DIR}/Resource.h" "${BASE_DIR}/Windows64_App.cpp" "${BASE_DIR}/Windows64_App.h" + "${BASE_DIR}/Windows64_DiscordPresence.cpp" + "${BASE_DIR}/Windows64_DiscordPresence.h" "${BASE_DIR}/Windows64_UIController.cpp" "${BASE_DIR}/Windows64_UIController.h" "${BASE_DIR}/KeyboardMouseInput.cpp"