Unreal Engine
Unreal Plugin 기본 설명
해당 문서는 플러그인 방식을 사용하여 Unreal Engine 4, 5 개발 환경에서 기존 SDK 적용 방식보다 보다 손쉽게 적용하는 방법을 제공하기 위하여 작성되었습니다.
Unreal Plugin에는 AppGuardCore.framework 명칭으로 배포되는 AppGuard SDK가 포함되어 배포됩니다.
AppGuardCore.framework는 Unreal Project/Plugins/AppGuardSDK/Source/AppGuardSDK/Libs/IOS/ 내부에 AppGuardCore.framework.zip 파일로 배포됩니다.
AppGuardCore.framework는 Do Not Embed로 프로젝트에 링크되고, 빌드됩니다.
if(Target.Platform == UnrealTargetPlatform.IOS)
{
string LibPath = Path.Combine(ModuleDirectory, "Libs/IOS");
PrivateIncludePaths.Add("AppGuardSDK/Private/IOS");
PublicFrameworks.Add("Security");
PublicAdditionalFrameworks.Add(
new Framework(
"AppGuardCore",
Path.Combine(LibPath, "AppGuardCore.framework.zip"),
""
)
);
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory,
Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("IOSPlugin",
Path.Combine(PluginPath, "AppGuardSDK_UPL_IOS.xml"));
}
Unreal Plugin 다운로드 및 설치하기
Unreal Plugin을 설치하고, Unreal Engine 4, 5에서 프로젝트를 구성하는 방법은 다음과 같습니다.
-
AppGuard 매니저 서버에 접속하여 Download > Unreal Pluings 를 선택하여 최신 버전으로 다운로드합니다.
-
다운로드된
AppGuardUnrealPlugin.zip파일 내 /AppGuardSDK 라는 폴더가 존재하며, 해당 AppGuardSDK 폴더를 Project/Plugins/ 경로 내로 복사합니다. -
Project/Source/ProjectName/ 경로 내의
APPNAME.Build.cs파일을 열어 아래와 같이"AppGuardSDK"를 추가하여 Unreal 프로젝트 내 AppGuard SDK 설치할 수 있습니다.
PublicDependencyModuleNames.AddRange(new string[]
{
"Core", "CoreUObject", "Engine", "InputCore", "AppGuardSDK"
});
AppGuard Config 파일 다운로드 및 설정하기
-
AppGuard 매니저 서버에 접속하여 [Applying Security]-[다운로드]-[CHAPTER 2. nProtect AppGuard CONFIG 파일 다운로드]-[CONFIG FILE DOWNLOAD] 를 선택하여 다운로드합니다.
-
다운로드된 Config 파일을 압축 해제 시 AppGuard Config 파일은
appguard,appguard.crt,appguard.mf,appguard1060004개의 파일로 구성되어있습니다. -
위 4개의 파일을 아래의 경로에 복사합니다.
Copy To : Project/Binaries/IOS/Payload/APPNAME.app/
[Unreal Editor] 에서 아직 IOS 빌드를 수행한 적이 없는 경우, Project/Binaries/IOS 폴더가 존재하지 않을 수 있습니다. 이러한 경우에는 IOS 빌드를 한 번 수행한 후 위의 작업을 수행해 주시기 바랍니다.
AppGuard SDK Privacy Manifests 적용하기(UE4, UE5)
해당 가이드는 Privacy Manifests 적용을 위해서는 AppGuard SDK v1.10.1.2이상을 사용해야합니다.
AppGuardCore.framework의 모듈은 AppGuardCore.framework를 Link하는 TARGETS에 병합되고 배포됩니다.
Apple Privacy Manifests 관련한 PrivacyInfo.xcprivacy는 AppGuard SDK를 Link한 TARGETS의 PrivacyInfo.xcprivacy에
AppGuardCore.framework의 PrivacyInfo.xcprivacy 내용이 명시되어야 합니다.
이에 따라 PrivacyInfo.xcprivacy에 AppGuardCore.framework 관련 내용을 명시하기 위해 아래 가이드를 참고하여 병합 작업을 수행하여 주시길 바랍니다.
-
Unreal Project 내 사용 중인
PrivacyInfo.xcprivacy파일이 존재하는 경우- AppGuardCore.framework 내부의
PrivacyInfo.xcprivacy파일의 내용과 기존의 사용 중인PrivacyInfo.xcprivacy과 비교하여 누락된 부분을 확인합니다. - 누락된 부분을 찾은 경우 누락된 부분을 이미 사용중이신
PrivacyInfo.xcprivacy파일에 추가 및 병합하여 주시기 바랍니다.
- AppGuardCore.framework 내부의
-
Unreal Project 내
PrivacyInfo.xcprivacy파일이 존재하지 않는 경우- 아래 내용을 복사하여
PrivacyInfo.xcprivacy파일을 생성합니다.
아래 내용은 UE5.4에서 생성하는PrivacyInfo.xcprivacy파일과 AppGuardCore.framework 의PrivacyInfo.xcprivacy파일을 병합한 내용입니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeCrashData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeGameplayContent</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeProductInteraction</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeUserID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeDeviceID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeOtherDataTypes</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>- 생성한
PrivacyInfo.xcprivacy파일을 UnrealProjects/XXXXProject/Binaries/IOS/Payload/XXXXX.app/ 내부에 복사하여 추가하여 주시길 바랍니다.
- 아래 내용을 복사하여
UE5.2 이상에서 지원하는 Modernized Xcode 옵션을 사용하여 빌드하시는 경우
PrivacyInfo.xcprivacy의 복사 위치는 Unreal Project/XXXXProject/Binaries/IOS/XXXXX.app/ 내부에 복사하여 주시기 바랍니다.
AppGuard for iOS SDK v1.10.1.2 이상에서는 AppGuardCore.framework 명칭으로 배포되며,
해당 SDK는 static framework로 제작되고, 배포됩니다.
AppGuard for iOS SDK v1.10.1.2 이상에서는 Apple 요구한 Privacy Manifest에서 명시한 Required reason API 항목 중 NSPrivacyAccessedAPICategoryUserDefaults 외 다른 API는 사용하지 않은 점 참고바랍니다.
static framewrok로 링크되는 타사의 SDK의 경우 AppGuard SDK와 마찬가지로 고객사의 PrivacyInfo.xcprivacy에 병합되는 작업이 필요할 수 있습니다.
AppGuardSDK Unreal Plugin 적용
Delegate에 콜백 등록 및 AppGuard 초기화 함수 호출하기
App 실행 시 보안 정책 위반 행위가 탐지될 경우 Callback을 통해 이벤트를 받으려면 Delegate에 콜백을 등록해야 합니다.
또한 AppGuard 초기화 작업을 위해 UAppGuardSDKBlueprintLibrary::Start(); 함수를 반드시 호출해야 합니다.
이때 해당 함수의 호출 시점은 앱 실행 시 가장 먼저 실행되는 시점 에 적용하여야 합니다.
#include “AppGuardSDKPlugin.h”
#include “AppGuardSDKBlueprintLibrary.h”
void ASampleProjectGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) {
//. 보 안 탐지용 콜백 함수 등록
FAppGuardSDKModule::OnDetected.AddUObject(this, &ASampleProject::OnDetected); // 콜백 등록
//. 서버인증용 콜백 함수 등록
FAppGuardSDKModule::OnS2AuthCompleted.AddUObject(this, &ASampleProject::OnS2AuthCompleted);
//. AppGuardCore.framework 사용을 위한 AppGuard 초기화
UAppGuardSDKBlueprintLibrary::Start();
}
/* 보안 탐지용 콜백 함수 샘플 */
void ASampleProjectGameMode::OnDetected (int data) {
bool killed = data > 0;
int code = data > 0 ? data : data * -1;
/*
Data 의 값이 양수일 경우, Appguard 는 30초 후 종료 처리됩니다.
아래 샘플 코드를 이용하여 사용자에게 노출될 화면에 출력하도록 하여야 합니다.
*/
if (killed) {
//. 종료 알림 창을 노출하여 게임이 종료되는 것을 사용자에게 알립니다.
//. 종료 알림 창은 확인 버튼 클릭 시 앱이 종료되도록 구성하여야 합니다.
}
}
/* 서버인증용 콜백 함수 샘플 */
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data) {
//. 서버인증 용 콜백 함수 구현 부분은 [서버인증 적용] 단계 참조 요망
}
실제 서비스 Release 시 위의 보안 탐지용 콜백 함수와 서버인증용 콜백 함수 내 로그 출력 함수를 반드시 제거해주시길 바랍니다.
UserID 설정하기
정책 위반 탐지 시 로그 서버에 User ID를 전송하기 위한 SetUserId() 메소드를 제공합니다.
아래 샘플 코드와 같이 userID 부분에 실제 해당 세션의 사용자 ID를 FString 형태의 데이터로 전달하여 사용할 수 있습니다.
#include “AppGuardSDKPlugin.h”
#include “AppGuardSDKBlueprintLibrary.h”
UAppGuardSDKBlueprintLibrary::SetUserId(TEXT("userID"));
서버인증 적용(선택)
본 내용은 서버인증 사용 시 필요한 내용이며, 서버인증 미사용 시 아래 내용은 무관한 내용입니다.
서버인증용 콜백 함수 구현하기
서버인증 관련 콜백은 Delegate에 콜백 등록 및 AppGuard 초기화 함수 호출하기 부분에서 작성한 OnS2AuthCompleted() 콜백 메서드를 통하여 서버인증 동작 이벤트가 전달됩니다.
아래 샘플 코드와 같이 서버인증 상태 결과를 OnS2AuthCompleted() 콜백 메서드를 통해 확인할 수 있습니다.
#include “AppGuardSDKPlugin.h”
#include “AppGuardSDKBlueprintLibrary.h”
// 서버인증용 콜백 함수 샘플
void ASampleProjectGameMode::OnS2AuthCompleted (int value, FString data)
{
switch (value)
{
case AppGuardEventType::S2Auth::S2AUTH_RESULT_SUCCESS:
/*
서버 인증이 성공하였으며, 정상적으로 인증이 완료되었습니다.
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_RETRY:
/*
서버 인증이 실패하였으며, 재인증을 시도할 것입니다. 일시적인 클라이언트 네트워크 장애 또는 서버 장애일 수 있으며,
해당 재시도는 내부 메커니즘에 따라 최대 3분 동안 수행될 수 있습니다.
*/
break;
case AppGuardEventType::S2Auth::S2AUTH_RESULT_FAIL:
/*
서버 인증이 완전히 실패하였으며, 더 이상 서버 인증을 시도하지 않 습니다.
*/
break;
}
}
아래의 서버인증 시작하기 설명과 같이 UAppGuardSDKBlueprintLibrary::SetUniqueClientId() 메서드를 호출하면
해당 시점부터 AppGuard 보안 모듈이 서버 인증을 시도하며, 위 샘플 코드에 예시된 것과 같이 3가지 상태 코드를 콜백 메서드로 전달합니다.
실제 서비스 Release 시 위의 서버인증용 콜백 함수 내 로그 출력 함수를 반드시 제거 해주시길 바랍니다.
서버 인증 시작하기
클라이언트에서 서버 인증을 시작하기 위해서는 아래 샘플 코드와 같이 서버에서 수신한 해당 사용자의 세션에 대한 UniqueClientID 를 아래와 같은 메서드를 사용하여 사용할 수 있습니다.
#include “AppGuardSDKPlugin.h”
#include “AppGuardSDKBlueprintLibrary.h”
UAppGuardSDKBlueprintLibrary::SetUniqueClientId(TEXT("Formatted-Unique-Client-Id", 180));
위 함수의 첫번째 인자로 주어진 Formatted-Unique-Client-Id의 규칙 및 생성 방법은 [주요 API] 를 참고하여 주시기 바랍니다.