aws / aws-gamekit-unreal

The AWS GameKit Plugin for Unreal
https://docs.aws.amazon.com/gamekit/latest/DevGuide/getting-started.html
Apache License 2.0
69 stars 19 forks source link

Can't add a function handle to the aws-gamekit #13

Open DevGarou opened 2 years ago

DevGarou commented 2 years ago

I need the access token from AwsGameKitIdentity and I've seen that the function GetToken is public in here so I wanted to expose it to the aws-gamekit-unreal plugin. But when I try to call it here what I have: LogAwsGameKit: Error: AWS GameKit SessionManager Plugin Function (GameKitSessionManagerGetToken) is null

Here are the mofications I've done to the code: in AwsGameKitSessionManagerWrapper.h

class AWSGAMEKITRUNTIME_API AwsGameKitSessionManagerWrapper : public AwsGameKitLibraryWrapper
{
private:
    /**
    * Function pointer handles
    */
    DEFINE_FUNC_HANDLE(GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE, GameKitSessionManagerInstanceCreate, (const char* clientConfigFile, FuncLogCallback logCb));
    DEFINE_FUNC_HANDLE(bool, GameKitSessionManagerAreSettingsLoaded, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, FeatureType featureType));
    DEFINE_FUNC_HANDLE(void, GameKitSessionManagerReloadConfigFile, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, const char* clientConfigFile));
    DEFINE_FUNC_HANDLE(void, GameKitSessionManagerReloadConfigContents, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, const char* clientConfigFileContents));
    DEFINE_FUNC_HANDLE(void, GameKitSessionManagerSetToken, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, GameKit::TokenType tokenType, const char* value));
    DEFINE_FUNC_HANDLE(void, GameKitSessionManagerInstanceRelease, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance));
+   DEFINE_FUNC_HANDLE(unsigned int, GameKitSessionManagerGetToken, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, GameKit::TokenType tokenType));

+    virtual char* GameKitSessionManagerGetToken(GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, GameKit::TokenType tokenType);

in AwsGameKitSessionManagerWrapper.cpp :

void AwsGameKitSessionManagerWrapper::importFunctions(void* loadedDllHandle)
{
    UE_LOG(LogAwsGameKit, Display, TEXT("AwsGameKitSessionManagerWrapper::importFunctions()"));

    LOAD_PLUGIN_FUNC(GameKitSessionManagerInstanceCreate, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerInstanceRelease, loadedDllHandle);    
    LOAD_PLUGIN_FUNC(GameKitSessionManagerAreSettingsLoaded, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerReloadConfigFile, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerSetToken, loadedDllHandle);
+  LOAD_PLUGIN_FUNC(GameKitSessionManagerGetToken, loadedDllHandle);
}

unsigned int AwsGameKitSessionManagerWrapper::GameKitSessionManagerGetToken(GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType)
{
    CHECK_PLUGIN_FUNC_IS_LOADED(SessionManager, GameKitSessionManagerGetToken, GAMEKIT_ERROR_GENERAL);

    return INVOKE_FUNC(GameKitSessionManagerGetToken, sessionManagerInstance, dispatchReceiver, resultCallback, tokenType);
}

and here is how I call it:

FString UAwsGameKitUserSystemProvider::GetAccessToken()
{
    FAwsGameKitRuntimeModule* AwsRuntimeModule = FModuleManager::GetModulePtr<FAwsGameKitRuntimeModule>(TEXT("AwsGameKitRuntime"));
    if (!AwsRuntimeModule)
        return TEXT("");

    SessionManagerLibrary const SessionManagerLib = AwsRuntimeModule->GetSessionManagerLibrary();
    FString const AccessToken = SessionManagerLib.SessionManagerWrapper->GameKitSessionManagerGetToken(SessionManagerLib.SessionManagerInstanceHandle, TokenType::AccessToken);
    UE_LOG(LogAWSAuth, Warning, TEXT("Got access token: %s"), *AccessToken);
    return AccessToken;
}

The AwsGameKitRuntimeModule is loaded correctly and I verified that the GetToken method is exported in the aws-gamekit-authentication.dll so I don't know what is the issue here.

Thanks,

schichko commented 2 years ago

Hi DevGarou,

I am a dev on the GameKit team and it looks like we did not properly expose the GetToken API. If you take a look at the exports from gamekit/authentication here you can see that GetToken is not actually being exposed.

In order to be able to properly call GetToken from Unreal it needs to be added to exports.cpp first. I will spend some time on my end getting this to work and then I can share the code snippets you will need to add. After that all you will need to do is rebuild the aws-gamekit dlls according to the documentation.

schichko commented 2 years ago

Hello again, here is the solution. I have broken it up into the files you need to change for each repository to get this to work. Once you make the changes to the aws-gamekit repositories make sure you rebuild it accord to our README. We will look at officially adding this in a future release but I tested this on my machine and it was working so please let me know if you have any issues and I would be happy to help you.

Changes for the aws-gamekit repository

aws-gamekit-authentication/include/aws/gamekit/authentication/exports.h (line 85)

GAMEKIT_API void GameKitSessionManagerSetToken(GAMEKIT_SESSIONMANAGER_INSTANCE_HANDLE sessionManagerInstance, GameKit::TokenType tokenType, const char* value);

/**
 * @brief Sets a token's value.
 * @param sessionManagerInstance Pointer to GameKitSessionManager instance created with GameKitSessionManagerInstanceCreate().
 * @param dispatchReceiver Pointer to the caller object (object that will handle the callback function).
 * @param resultCallback Pointer to the callback function to invoke on completion.
 * @param tokenType The type of token to set.
 * @return The value of the token.
 */
GAMEKIT_API unsigned int GameKitSessionManagerGetToken(GAMEKIT_SESSIONMANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType);

aws-gamekit-authentication/source/aws/gamekit/authentication/exports.cpp (line 42)

GAMEKIT_API unsigned int GameKitSessionManagerGetToken(GAMEKIT_SESSIONMANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType)
{
    std::string tokenValue = ((GameKit::Authentication::GameKitSessionManager*)sessionManagerInstance)->GetToken(tokenType);

    if (!tokenValue.empty() && resultCallback != nullptr)
    {
        resultCallback(dispatchReceiver, tokenValue.c_str());

        return GameKit::GAMEKIT_SUCCESS;
    }

    return GameKit::GAMEKIT_ERROR_GENERAL;
}

Changes for the Unreal plugin repository

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Private/SessionManager/SessionManagerWrapper.cpp (line 30)

void AwsGameKitSessionManagerWrapper::importFunctions(void* loadedDllHandle)
{
    UE_LOG(LogAwsGameKit, Display, TEXT("AwsGameKitSessionManagerWrapper::importFunctions()"));

    LOAD_PLUGIN_FUNC(GameKitSessionManagerInstanceCreate, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerInstanceRelease, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerAreSettingsLoaded, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerReloadConfigFile, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerSetToken, loadedDllHandle);
    LOAD_PLUGIN_FUNC(GameKitSessionManagerGetToken, loadedDllHandle);
}

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Private/SessionManager/SessionManagerWrapper.cpp (line 216)

unsigned int AwsGameKitSessionManagerWrapper::GameKitSessionManagerGetToken(GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType)
{
    CHECK_PLUGIN_FUNC_IS_LOADED(SessionManager, GameKitSessionManagerGetToken, GAMEKIT_ERROR_GENERAL);

    return INVOKE_FUNC(GameKitSessionManagerGetToken, sessionManagerInstance, dispatchReceiver, resultCallback, tokenType);
}

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Public/SessionManager/SessionManagerWrapper.h(line 48)

  DEFINE_FUNC_HANDLE(void, GameKitSessionManagerSetToken, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, GameKit::TokenType tokenType, const char* value));
  DEFINE_FUNC_HANDLE(unsigned int, GameKitSessionManagerGetToken, (GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType));

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Public/SessionManager/SessionManagerWrapper.h(line 148)

    /**
     * @brief Sets a token's value.
     * @param sessionManagerInstance Pointer to GameKitSessionManager instance created with GameKitSessionManagerInstanceCreate().
     * @param dispatchReceiver Pointer to the caller object (object that will handle the callback function).
     * @param resultCallback Pointer to the callback function to invoke on completion.
     * @param tokenType The type of token to set.
     * @return The value of the token.
    */
    virtual unsigned int GameKitSessionManagerGetToken(GAMEKIT_SESSION_MANAGER_INSTANCE_HANDLE sessionManagerInstance, DISPATCH_RECEIVER_HANDLE dispatchReceiver, CharPtrCallback resultCallback, GameKit::TokenType tokenType);

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Private/SessionManager/AwsGameKitSessionManager.cpp (line 40)

FString AwsGameKitSessionManager::GetToken(TokenType_E tokenType)
{
    SessionManagerLibrary sessionManagerLibrary = GetSessionManagerLibraryFromModule();

    FString tokenValue;
    auto tokenSetter = [&tokenValue](const char* tokenVal)
    {
        tokenValue = tokenVal;
    };
    typedef LambdaDispatcher<decltype(tokenSetter), void, const char*> TokenValueSetter;

    IntResult result = sessionManagerLibrary.SessionManagerWrapper->GameKitSessionManagerGetToken(sessionManagerLibrary.SessionManagerInstanceHandle, (void*)&tokenSetter, TokenValueSetter::Dispatch, AwsGameKitEnumConverter::ConvertTokenTypeEnum(tokenType));

    if (result.Result != GameKit::GAMEKIT_SUCCESS)
    {
        result.ErrorMessage = FString("Error: AwsGameKitSessionManager::GetToken() Failed to get Token.");
        FString const error = GameKit::StatusCodeToHexFStr(result.Result);
        FString const message = result.ErrorMessage + " : " + error;
        UE_LOG(LogAwsGameKit, Log, TEXT("%s"), *message); 
        tokenValue = "";
    }

    return tokenValue;
}

Plugin/AwsGameKit/Source/AwsGameKitRuntime/Public/SessionManager/AwsGameKitSessionManager.h (line 40)

  /**
     * @brief Sets a token's value
     * @param tokenType The type of token to set.
     * @return The value of the token.
    */
    static FString GetToken(TokenType_E tokenType);
QuentinGarou commented 2 years ago

Thanks a lot for the response you gave me! However I'm stuck on compiling the aws-gamekit repo. I followed all the steps and when it comes to compiling the project here is the response I get (below). If you have any idea why it doesn't work it would be really nice! Thanks

C:\Users\dev\source\repos\aws\aws-gamekit>python scripts/aws_gamekit_cpp_build.py Windows --vs_type Community --clean Release
INFO:root:Running command: ['C:\\Users\\dev\\source\\repos\\aws\\aws-gamekit\\scripts\\Win64\\regenerate_projects.bat', 'C:\\Users\\dev\\source\\repos\\aws\\aws-sdk-cpp', 'C:\\Users\\dev\\source\\repos\\aws\\boost_1_76_0', 'C:\\Users\\dev\\source\\repos\\aws\\yaml-cpp', 'C:\\Users\\dev\\source\\repos\\aws\\googletest', 'C:\\Users\\dev\\source\\repos\\aws\\pybind11', 'C:\\Users\\dev\\source\\repos\\aws\\aws-gamekit', 'Release'] from directory: C:\Users\dev\source\repos\aws\aws-gamekit
Build Configuration=Release
CMake Error at CMakeLists.txt:54 (find_package):
  By not providing "FindAWSSDK.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "AWSSDK", but
  CMake did not find one.

  Could not find a package configuration file provided by "AWSSDK" with any
  of the following names:

    AWSSDKConfig.cmake
    awssdk-config.cmake

  Add the installation prefix of "AWSSDK" to CMAKE_PREFIX_PATH or set
  "AWSSDK_DIR" to a directory containing one of the above files.  If "AWSSDK"
  provides a separate development package or SDK, be sure it has been
  installed.

INFO:root:
INFO:root:C:\Users\dev\source\repos\aws\aws-gamekit>REM Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
INFO:root:
INFO:root:C:\Users\dev\source\repos\aws\aws-gamekit>REM SPDX-License-Identifier: Apache-2.0
INFO:root:
INFO:root:C:\Users\dev\source\repos\aws\aws-gamekit>set CMAKE_PREFIX_PATH=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\Release
INFO:root:
INFO:root:C:\Users\dev\source\repos\aws\aws-gamekit>cmake -G "Visual Studio 16 2019" -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -Daws-c-http_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-http\cmake -Daws-c-io_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-io\cmake -Daws-c-common_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-common\cmake -Daws-c-cal_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-cal\cmake -Daws-c-compression_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-compression\cmake -Daws-c-mqtt_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-mqtt\cmake -Daws-c-auth_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-auth\cmake -Daws-c-event-stream_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-event-stream\cmake -Daws-checksums_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-checksums\cmake -Daws-c-s3_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-c-s3\cmake -DAWSSDK_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\AWSSDK -Daws-cpp-sdk-core_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-core -Daws-crt-cpp_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\aws-crt-cpp\cmake -Daws-cpp-sdk-cloudformation_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-cloudformation -Daws-cpp-sdk-cognito-idp_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-cognito-idp -Daws-cpp-sdk-sts_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-sts -Daws-cpp-sdk-secretsmanager_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-secretsmanager -Daws-cpp-sdk-ssm_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-ssm -Daws-cpp-sdk-s3_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-s3 -Daws-cpp-sdk-lambda_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-lambda -Daws-cpp-sdk-apigateway_DIR=C:\Users\dev\source\repos\aws\aws-sdk-cpp\install\x86_64\windows\Release\lib\cmake\aws-cpp-sdk-apigateway -DBOOST_ROOT=C:\Users\dev\source\repos\aws\boost_1_76_0 -DBOOST_LIBRARYDIR=C:\Users\dev\source\repos\aws\boost_1_76_0\stage\lib -Dyaml-cpp_DIR=C:\Users\dev\source\repos\aws\yaml-cpp\install\Release\share\cmake\yaml-cpp -DGTEST_LINKED_AS_SHARED_LIBRARY=1 -DGTest_DIR=C:\Users\dev\source\repos\aws\googletest\build\install\lib\cmake\GTest -DGTEST_SRC=C:\Users\dev\source\repos\aws\googletest\build\install\include -Dpybind11_DIR=C:\Users\dev\source\repos\aws\pybind11\install\Release\share\cmake\pybind11 -DCMAKE_INSTALL_PREFIX=C:\Users\dev\source\repos\aws\aws-gamekit\install\Release --log-level=Verbose C:\Users\dev\source\repos\aws\aws-gamekit
INFO:root:-- Selecting Windows SDK version 10.0.20348.0 to target Windows 10.0.19044.
INFO:root:-- The C compiler identification is MSVC 19.29.30140.0
INFO:root:-- The CXX compiler identification is MSVC 19.29.30140.0
INFO:root:-- Detecting C compiler ABI info
INFO:root:-- Detecting C compiler ABI info - done
INFO:root:-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
INFO:root:-- Detecting C compile features
INFO:root:-- Detecting C compile features - done
INFO:root:-- Detecting CXX compiler ABI info
INFO:root:-- Detecting CXX compiler ABI info - done
INFO:root:-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
INFO:root:-- Detecting CXX compile features
INFO:root:-- Detecting CXX compile features - done
INFO:root:-- Configuring incomplete, errors occurred!
INFO:root:See also "C:/Users/dev/source/repos/aws/aws-gamekit/CMakeFiles/CMakeOutput.log".
INFO:root:
INFO:root:Running command: ['C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe', 'ALL_BUILD.vcxproj', '-p:Configuration=Release', '-m', '-t:Clean'] from directory: C:\Users\dev\source\repos\aws\aws-gamekit
ERROR:root:Command: ['C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe', 'ALL_BUILD.vcxproj', '-p:Configuration=Release', '-m', '-t:Clean'] from directory: C:\Users\dev\source\repos\aws\aws-gamekit failed.
INFO:root:Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
INFO:root:Copyright (C) Microsoft Corporation. All rights reserved.
INFO:root:
INFO:root:MSBUILD : error MSB1009: Project file does not exist.
INFO:root:Switch: ALL_BUILD.vcxproj
INFO:root:
Traceback (most recent call last):
  File "C:\Users\dev\source\repos\aws\aws-gamekit\scripts\aws_gamekit_cpp_build.py", line 40, in <module>
    build_libs()
  File "C:\Users\dev\source\repos\aws\aws-gamekit\scripts\aws_gamekit_cpp_build.py", line 31, in build_libs
    windows.build(args)
  File "C:\Users\dev\source\repos\aws\aws-gamekit\scripts\Win64\build.py", line 54, in build
    run_and_log([str(MS_BUILD), "ALL_BUILD.vcxproj", f"-p:Configuration={args.type}", "-m", "-t:Clean" if args.clean else ""])
  File "C:\Users\dev\source\repos\aws\aws-gamekit\scripts\common.py", line 31, in run_and_log
    raise err
  File "C:\Users\dev\source\repos\aws\aws-gamekit\scripts\common.py", line 21, in run_and_log
    output = subprocess.check_output(command)
  File "C:\Users\dev\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 420, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "C:\Users\dev\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 524, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe', 'ALL_BUILD.vcxproj', '-p:Configuration=Release', '-m', '-t:Clean']' returned non-zero exit status 1.
schichko commented 2 years ago

You're welcome! I have seen this issue before and it's related to the path to the AWSSDK dependency not being correct. I see your building aws-gamekit for release, when you built the AWSSDK did you also build for release?

The build type for aws-gamekit and the aws-sdk should be the same.

amzn-adrian commented 2 years ago

Hi QuentinGarou,

Is C:\\Users\\dev\\source\\repos\\aws\\aws-sdk-cpp the location of your AWS SDK build or repo? When aws_gamekit_cpp_build.py asks for AWS SDK you should provide the path to the build.