Changes to allow plugin to work in Shipping Builds

This commit is contained in:
oreyg 2018-01-21 08:17:01 +06:00
parent b85758ec19
commit 66453fdda3
10 changed files with 243 additions and 134 deletions

View File

@ -0,0 +1,2 @@
#include "Core.h"
#include "DiscordRpc.h"

View File

@ -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")));
}
}
}

View File

@ -0,0 +1,84 @@
#pragma once
#include <stdint.h>
// 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

View File

@ -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"));
}
}
}

View File

@ -1,7 +1,5 @@
#include "DicordRpcPrivatePCH"
#include "DiscordRpcBlueprint.h" #include "DiscordRpcBlueprint.h"
#include "discord-rpc.h" #include "discord-rpc.h"
DEFINE_LOG_CATEGORY(Discord) DEFINE_LOG_CATEGORY(Discord)

View File

@ -1,50 +1,71 @@
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "discordrpc.h" #include "DiscordRpcPrivatePCH.h"
#include "Core.h"
#include "IPluginManager.h" #include "IPluginManager.h"
#include "ModuleManager.h" #include "ModuleManager.h"
#define LOCTEXT_NAMESPACE "FdiscordrpcModule" #define LOCTEXT_NAMESPACE "FDiscordRpcModule"
void FdiscordrpcModule::StartupModule() void FDiscordRpcModule::StartupModule()
{ {
// This code will execute after your module is loaded into memory; the exact timing is specified #if !PLATFORM_LINUX
// in the .uplugin file per-module #if defined(DISCORD_DYNAMIC_LIB)
// Get the base directory of this plugin // Get the base directory of this plugin
FString BaseDir = IPluginManager::Get().FindPlugin("discordrpc")->GetBaseDir(); FString BaseDir = IPluginManager::Get().FindPlugin("DiscordRpc")->GetBaseDir();
const FString SDKDir = FPaths::Combine(*BaseDir, TEXT("ThirdParty"), TEXT("DiscordRpcLibrary"));
// Add on the relative location of the third party dll and load it
FString LibraryPath;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS
LibraryPath = FPaths::Combine( const FString LibName = TEXT("discord-rpc");
*BaseDir, TEXT("Binaries/ThirdParty/discordrpcLibrary/Win64/discord-rpc.dll")); 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 #elif PLATFORM_MAC
LibraryPath = FPaths::Combine( const FString LibName = TEXT("discord-rpc");
*BaseDir, TEXT("Source/ThirdParty/discordrpcLibrary/Mac/Release/libdiscord-rpc.dylib")); const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Mac"));
#endif // PLATFORM_WINDOWS if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) {
FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT(LOCTEXT_NAMESPACE, "Failed to load DiscordRpc plugin. Plug-in will not be functional."));
DiscordLibraryHandle = FreeDependency(DiscordRpcLibraryHandle);
!LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr;
if (!DiscordLibraryHandle) {
FMessageDialog::Open(
EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load discord-rpc library"));
} }
#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 // Free the dll handle
FPlatformProcess::FreeDllHandle(DiscordLibraryHandle); #if !PLATFORM_LINUX
DiscordLibraryHandle = nullptr; #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 #undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FdiscordrpcModule, discordrpc) IMPLEMENT_MODULE(FDiscordRpcModule, DiscordRpc)

View File

@ -1,5 +1,3 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"

View File

@ -4,7 +4,7 @@
#include "ModuleManager.h" #include "ModuleManager.h"
class FdiscordrpcModule : public IModuleInterface { class FDiscordRpcModule : public IModuleInterface {
public: public:
/** IModuleInterface implementation */ /** IModuleInterface implementation */
virtual void StartupModule() override; virtual void StartupModule() override;
@ -13,4 +13,8 @@ public:
private: private:
/** Handle to the test dll we will load */ /** Handle to the test dll we will load */
void* DiscordLibraryHandle; 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);
}; };

View File

@ -7,59 +7,45 @@ public class discordrpc : ModuleRules
public discordrpc(ReadOnlyTargetRules Target) : base(Target) public discordrpc(ReadOnlyTargetRules Target) : base(Target)
{ {
Definitions.Add("DISCORD_DYNAMIC_LIB=1"); Definitions.Add("DISCORD_DYNAMIC_LIB=1");
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange( PublicIncludePaths.AddRange(
new string[] { new string[] {
"discordrpc/Public" "DiscordRpc/Public"
// ... add public include paths required here ...
} }
); );
PrivateIncludePaths.AddRange( PrivateIncludePaths.AddRange(
new string[] { new string[] {
"discordrpc/Private", "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( PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
}
);
PrivateDependencyModuleNames.AddRange(
new string[] new string[]
{ {
"CoreUObject", "CoreUObject",
"Engine", "Engine",
"Slate", "Slate",
"SlateCore", "SlateCore",
"Core",
"discordrpcLibrary",
"Projects" "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( DynamicallyLoadedModuleNames.AddRange(
new string[] new string[]
{ {
// ... add any modules that your module loads dynamically here ... // ... add any modules that your module loads dynamically here ...
} }
); );
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "ThirdParty", "DiscordRpcLibrary"));
PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include"));
} }
} }

View File

@ -15,9 +15,9 @@
"Installed": false, "Installed": false,
"Modules": [ "Modules": [
{ {
"Name": "discordrpc", "Name": "DiscordRpc",
"Type": "Developer", "Type": "Runtime",
"LoadingPhase": "Default" "LoadingPhase": "PreDefault"
} }
] ]
} }