diff --git a/examples/unrealstatus/Plugins/DiscordRpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h b/examples/unrealstatus/Plugins/DiscordRpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h new file mode 100644 index 0000000..0c66aba --- /dev/null +++ b/examples/unrealstatus/Plugins/DiscordRpc/Source/DiscordRpc/Private/DiscordRpcPrivatePCH.h @@ -0,0 +1,2 @@ +#include "Core.h" +#include "DiscordRpc.h" \ No newline at end of file diff --git a/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs b/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs new file mode 100644 index 0000000..ff7c1a3 --- /dev/null +++ b/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/DiscordRpcLibrary.Build.cs @@ -0,0 +1,43 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +using System.IO; +using UnrealBuildTool; + +public class discordrpcLibrary : ModuleRules +{ + public discordrpcLibrary(ReadOnlyTargetRules Target) : base(Target) + { + Type = ModuleType.External; + Definitions.Add("DISCORD_DYNAMIC_LIB=1"); + + string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "ThirdParty", "discordrpc")); + + if (Target.Platform == UnrealTargetPlatform.Win64) + { + string lib = Path.Combine(BaseDirectory, "Win64"); + + // Include headers + PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); + + // Add the import library + PublicLibraryPaths.Add(lib); + PublicAdditionalLibraries.Add(Path.Combine(lib, "discord-rpc.lib")); + + // Dynamic + RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "discord-rpc.dll"))); + PublicDelayLoadDLLs.Add("discord-rpc.dll"); + } + else if (Target.Platform == UnrealTargetPlatform.Linux) + { + string lib = Path.Combine(BaseDirectory, "Linux", "x86_64-unknown-linux-gnu"); + + // Include headers + PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); + + // Add the import library + PublicLibraryPaths.Add(lib); + PublicAdditionalLibraries.Add(Path.Combine(lib, "libdiscord-rpc.so")); + RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "libdiscord-rpc.so"))); + } + } +} \ No newline at end of file diff --git a/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/Include/discord-rpc.h b/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/Include/discord-rpc.h new file mode 100644 index 0000000..05c9344 --- /dev/null +++ b/examples/unrealstatus/Plugins/DiscordRpc/ThirdParty/DiscordRpcLibrary/Include/discord-rpc.h @@ -0,0 +1,84 @@ +#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 DiscordJoinRequest { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordJoinRequest; + +typedef struct DiscordEventHandlers { + void (*ready)(); + 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 DiscordJoinRequest* 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_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/discordrpcLibrary/discordrpcLibrary.Build.cs b/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/discordrpcLibrary/discordrpcLibrary.Build.cs deleted file mode 100644 index ac67153..0000000 --- a/examples/unrealstatus/Plugins/discordrpc/Source/ThirdParty/discordrpcLibrary/discordrpcLibrary.Build.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -using System.IO; -using UnrealBuildTool; - -public class discordrpcLibrary : ModuleRules -{ - public discordrpcLibrary(ReadOnlyTargetRules Target) : base(Target) - { - Type = ModuleType.External; - - if (Target.Platform == UnrealTargetPlatform.Win64) - { - // Add the import library - PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Include")); - PublicLibraryPaths.Add(Path.Combine(ModuleDirectory, "x64", "Release")); - PublicAdditionalLibraries.Add("discord-rpc.lib"); - - // Delay-load the DLL, so we can load it from the right place first - PublicDelayLoadDLLs.Add("discord-rpc.dll"); - } - else if (Target.Platform == UnrealTargetPlatform.Mac) - { - PublicDelayLoadDLLs.Add(Path.Combine(ModuleDirectory, "Mac", "Release", "libdiscord-rpc.dylib")); - } - } -} diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/DiscordRpcBlueprint.cpp b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/DiscordRpcBlueprint.cpp index 5305806..5ad637b 100644 --- a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/DiscordRpcBlueprint.cpp +++ b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/DiscordRpcBlueprint.cpp @@ -1,7 +1,5 @@ - - +#include "DicordRpcPrivatePCH" #include "DiscordRpcBlueprint.h" - #include "discord-rpc.h" DEFINE_LOG_CATEGORY(Discord) diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/discordrpc.cpp b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/discordrpc.cpp index dc5237a..d8ff536 100644 --- a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/discordrpc.cpp +++ b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Private/discordrpc.cpp @@ -1,50 +1,71 @@ // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. -#include "discordrpc.h" -#include "Core.h" +#include "DiscordRpcPrivatePCH.h" #include "IPluginManager.h" #include "ModuleManager.h" -#define LOCTEXT_NAMESPACE "FdiscordrpcModule" - -void FdiscordrpcModule::StartupModule() -{ - // This code will execute after your module is loaded into memory; the exact timing is specified - // in the .uplugin file per-module +#define LOCTEXT_NAMESPACE "FDiscordRpcModule" +void FDiscordRpcModule::StartupModule() +{ +#if !PLATFORM_LINUX +#if defined(DISCORD_DYNAMIC_LIB) // Get the base directory of this plugin - FString BaseDir = IPluginManager::Get().FindPlugin("discordrpc")->GetBaseDir(); - - // Add on the relative location of the third party dll and load it - FString LibraryPath; + FString BaseDir = IPluginManager::Get().FindPlugin("DiscordRpc")->GetBaseDir(); + const FString SDKDir = FPaths::Combine(*BaseDir, TEXT("ThirdParty"), TEXT("DiscordRpcLibrary")); #if PLATFORM_WINDOWS - LibraryPath = FPaths::Combine( - *BaseDir, TEXT("Binaries/ThirdParty/discordrpcLibrary/Win64/discord-rpc.dll")); + const FString LibName = TEXT("discord-rpc"); + const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Win64")); + if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) { + FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT(LOCTEXT_NAMESPACE, "Failed to load DiscordRpc plugin. Plug-in will not be functional.")); + FreeDependency(DiscordRpcLibraryHandle); + } #elif PLATFORM_MAC - LibraryPath = FPaths::Combine( - *BaseDir, TEXT("Source/ThirdParty/discordrpcLibrary/Mac/Release/libdiscord-rpc.dylib")); -#endif // PLATFORM_WINDOWS - - DiscordLibraryHandle = - !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr; - - if (!DiscordLibraryHandle) { - FMessageDialog::Open( - EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load discord-rpc library")); - } + const FString LibName = TEXT("discord-rpc"); + const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Mac")); + if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) { + FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT(LOCTEXT_NAMESPACE, "Failed to load DiscordRpc plugin. Plug-in will not be functional.")); + FreeDependency(DiscordRpcLibraryHandle); + } +#endif +#endif +#endif } -void FdiscordrpcModule::ShutdownModule() +void FDiscordRpcModule::ShutdownModule() { - // This function may be called during shutdown to clean up your module. For modules that - // support dynamic reloading, - // we call this function before unloading the module. - // Free the dll handle - FPlatformProcess::FreeDllHandle(DiscordLibraryHandle); - DiscordLibraryHandle = nullptr; +#if !PLATFORM_LINUX +#if defined(DISCORD_DYNAMIC_LIB) + FreeDependency(DiscordRpcLibraryHandle); +#endif +#endif +} + +bool FDiscordAPIModule::LoadDependency(const FString& Dir, const FString& Name, void*& Handle) +{ + FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension(); + FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib); + + Handle = FPlatformProcess::GetDllHandle(*Path); + + if (Handle == nullptr) + { + return false; + } + + return true; +} + +void FDiscordAPIModule::FreeDependency(void*& Handle) +{ + if (Handle != nullptr) + { + FPlatformProcess::FreeDllHandle(Handle); + Handle = nullptr; + } } #undef LOCTEXT_NAMESPACE -IMPLEMENT_MODULE(FdiscordrpcModule, discordrpc) \ No newline at end of file +IMPLEMENT_MODULE(FDiscordRpcModule, DiscordRpc) \ No newline at end of file diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/DiscordRpcBlueprint.h b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/DiscordRpcBlueprint.h index e6c1e91..7fbad7b 100644 --- a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/DiscordRpcBlueprint.h +++ b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/DiscordRpcBlueprint.h @@ -1,5 +1,3 @@ - - #pragma once #include "CoreMinimal.h" diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/discordrpc.h b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/discordrpc.h index 8a9323c..f5b27ea 100644 --- a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/discordrpc.h +++ b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/Public/discordrpc.h @@ -4,7 +4,7 @@ #include "ModuleManager.h" -class FdiscordrpcModule : public IModuleInterface { +class FDiscordRpcModule : public IModuleInterface { public: /** IModuleInterface implementation */ virtual void StartupModule() override; @@ -13,4 +13,8 @@ public: private: /** Handle to the test dll we will load */ void* DiscordLibraryHandle; + + /** StartupModule is covered with defines, these functions are the place to put breakpoints */ + static bool LoadDependency(const FString& Dir, const FString& Name, void*& Handle); + static void FreeDependency(void*& Handle); }; \ No newline at end of file diff --git a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/discordrpc.Build.cs b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/discordrpc.Build.cs index d34e809..4249e5f 100644 --- a/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/discordrpc.Build.cs +++ b/examples/unrealstatus/Plugins/discordrpc/Source/discordrpc/discordrpc.Build.cs @@ -1,65 +1,51 @@ -// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. - -using UnrealBuildTool; - -public class discordrpc : ModuleRules -{ - public discordrpc(ReadOnlyTargetRules Target) : base(Target) - { - Definitions.Add("DISCORD_DYNAMIC_LIB=1"); - PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; - - PublicIncludePaths.AddRange( - new string[] { - "discordrpc/Public" - // ... add public include paths required here ... - } - ); - - - PrivateIncludePaths.AddRange( - new string[] { - "discordrpc/Private", - "../../../../../include" - // ... add other private include paths required here ... - } - ); - - PublicLibraryPaths.AddRange( - new string[] { - System.IO.Path.Combine(ModuleDirectory, "../../Binaries/ThirdParty/discordrpcLibrary/", Target.Platform.ToString()), - } - ); - - - PublicDependencyModuleNames.AddRange( - new string[] - { - "CoreUObject", - "Engine", - "Slate", - "SlateCore", - "Core", - "discordrpcLibrary", - "Projects" - // ... add other public dependencies that you statically link with here ... - } - ); - - - PrivateDependencyModuleNames.AddRange( - new string[] - { - // ... add private dependencies that you statically link with here ... - } - ); - - - DynamicallyLoadedModuleNames.AddRange( - new string[] - { - // ... add any modules that your module loads dynamically here ... - } - ); - } -} +// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; + +public class discordrpc : ModuleRules +{ + public discordrpc(ReadOnlyTargetRules Target) : base(Target) + { + Definitions.Add("DISCORD_DYNAMIC_LIB=1"); + + PublicIncludePaths.AddRange( + new string[] { + "DiscordRpc/Public" + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + "DiscordRpc/Private" + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + "Projects" + } + ); + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + + string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "ThirdParty", "DiscordRpcLibrary")); + PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include")); + } +} \ No newline at end of file diff --git a/examples/unrealstatus/Plugins/discordrpc/discordrpc.uplugin b/examples/unrealstatus/Plugins/discordrpc/discordrpc.uplugin index ca77578..59e49d9 100644 --- a/examples/unrealstatus/Plugins/discordrpc/discordrpc.uplugin +++ b/examples/unrealstatus/Plugins/discordrpc/discordrpc.uplugin @@ -15,9 +15,9 @@ "Installed": false, "Modules": [ { - "Name": "discordrpc", - "Type": "Developer", - "LoadingPhase": "Default" + "Name": "DiscordRpc", + "Type": "Runtime", + "LoadingPhase": "PreDefault" } ] } \ No newline at end of file