Downloadable Content (DLC) API

Downloadable content (DLC) is an additional content created for a release content. It is distributed through the internet by the content official publisher.

How to use Downloadable Content (DLC) API

Note

Remember that you should call Top Level API - Api.Init() and DLC API - DLC.IsReady() to setup the SDK library and client runtime before you call the Downloadable Content API. And please remember to call Top Level API - Api.Shutdown() to teardown the library runtime after you finish using VIVEPORT SDK.

bool IsReady(callback) : This API provides developers to allow the content developer to get the DLC SDK outcome..

int GetCount() : This API provides developers to get the amount of DLC package from the end user location.

bool GetIsAvailable(int index , char* appId, bool &isAvailable) : This API allows developers to allow the developer to check whether the end user already purchased this DLC content or not.

Important

Please see the Error Codes and Trouble Shooting pages to know what to do when you got problems using the VIVEPORT SDK.

Detailed Example in Unity

using UnityEngine;
using System;
using Viveport;

/** Language: C# */
public class ViveportDemo_DLC : MonoBehaviour
{
#if UNITY_ANDROID
     private int nWidth = 180, nHeight = 100;
#else
     private int nWidth = 140, nHeight = 40;
#endif

    private int nXStart = 10, nYStart = 35;

    static string APP_ID = "76d0898e-8772-49a9-aa55-1ec251a21686";
    private static bool bInit = true, bIsReady = false, bIsDLCAvailable = false;
    private static int dlcCount = -1;
    private static string dlcAppId = "";
    private int dlcIndex = 0;

    // Use this for initialization
    void Start()
    {
        Api.Init(InitStatusHandler, APP_ID);
    }

    void OnGUI()
    {
        GUIStyle CustButton = new GUIStyle("button");
    #if UNITY_ANDROID
        CustButton.fontSize = 23;
    #endif
        if (bInit == false)
            GUI.contentColor = Color.white;
        else
            GUI.contentColor = Color.gray;
        // Init function
        if (GUI.Button(new Rect(nXStart, nYStart, nWidth, nHeight), "Init", CustButton))
        {
            if (bInit == false)
                Api.Init(InitStatusHandler, APP_ID);
        }

        if (bInit == true)
            GUI.contentColor = Color.white;
        else
            GUI.contentColor = Color.grey;

        // Shutdown function
        if (GUI.Button(new Rect((nXStart + 1 * (nWidth + 10)), nYStart, nWidth, nHeight), "Shutdown", CustButton))
        {
            if (bInit == true)
                Api.Shutdown(ShutdownHandler);
        }

    #if !UNITY_ANDROID
        // IsDLCReady function
        if (GUI.Button(new Rect((nXStart + 2 * (nWidth + 10)), nYStart, nWidth, nHeight), "IsDLCReady", CustButton))
        {
            if (bInit == true)
                DLC.IsDlcReady(IsDLCReadyHandler);
        }

        // GetDLCCount function
        if (GUI.Button(new Rect((nXStart + 3 * (nWidth + 10)), nYStart, nWidth, nHeight), "GetDLCCount", CustButton))
        {
            if (bInit == true && bIsReady == true)
            {
                dlcCount = DLC.GetCount();
                Viveport.Core.Logger.Log("DLC count: " + dlcCount);
            }
        }

        // GetIsAvailable function
        if (GUI.Button(new Rect((nXStart + 4 * (nWidth + 10)), nYStart, nWidth, nHeight), "GetIsAvailable", CustButton))
        {
           if (bInit == true && bIsReady == true)
            {
                bool isInRange = DLC.GetIsAvailable(dlcIndex, out dlcAppId, out bIsDLCAvailable);
                if (isInRange)
                {
                    Viveport.Core.Logger.Log("Is DLC available: " + bIsDLCAvailable);
                    Viveport.Core.Logger.Log("DLC APP ID: " + dlcAppId);
                }
            }
        }
    #endif
    }

    private static void InitStatusHandler(int nResult)
    {
        if (nResult == 0)
        {
            bInit = true;
            bIsReady = false;
            Viveport.Core.Logger.Log("InitStatusHandler is successful");
        }
        else
        {
            // Init error, close your app and make sure your app ID is correct or not.
            bInit = false;
            Viveport.Core.Logger.Log("InitStatusHandler error : " + nResult);
        }
    }

    private static void ShutdownHandler(int nResult)
    {
        if (nResult == 0)
        {
            bInit = false;
            bIsReady = false;
            Viveport.Core.Logger.Log("ShutdownHandler is successful");
        }
        else
        {
            Viveport.Core.Logger.Log("ShutdownHandler error: " + nResult);
        }
    }

    private static void IsDLCReadyHandler(int nResult)
    {
        if (nResult == 0)
        {
            Viveport.Core.Logger.Log("DLC is ready");
            bIsReady = true;
        }
        else
        {
            Viveport.Core.Logger.Log("IsDLCReadyHandler error: " + nResult);
        }
    }
}

Detailed Example in Unreal

ViveportDLCDemo.h

#include "Components/ActorComponent.h"
#include "ViveportApi.h"
#include "ViveportDLC.h"

#include "ViveportDLCDemo.generated.h"


UCLASS( ClassGroup=(Viveport), meta=(BlueprintSpawnableComponent) )
class VIVEPORTSDK_API UViveportDLCDemo : public UActorComponent
{
    GENERATED_BODY()

public:
    // Sets default values for this component's properties
    UViveportDLCDemo();

    // Called when the game starts
    virtual void BeginPlay() override;

    void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

    // Called every frame
    virtual void TickComponent(
        float DeltaTime,
        ELevelTick TickType,
        FActorComponentTickFunction* ThisTickFunction
    ) override;

    /** The APP ID for auth verify */
    FString DLC_APP_ID = "76d0898e-8772-49a9-aa55-1ec251a21686";

    private:
       // callback interface
       class MyViveportDLCStatus : public ViveportApiStatus
       {
       protected:
           UViveportDLCDemo* mDemo;
       public:
           void SetDemoPtr(UViveportDLCDemo* p) { mDemo = p; }
       };

    class MyDLCInitCallback : public MyViveportDLCStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(int error_code
        ) override;
    };

    MyDLCInitCallback myDLCInitCallback;

    class MyDLCShutdownCallback : public MyViveportDLCStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(int error_code
        ) override;
    };

    MyDLCShutdownCallback myDLCShutdownCallback;

    class MyIsDLCReadyCallback : public MyViveportDLCStatus
    {
    public:
        void OnSuccess(
        ) override;
        void OnFailure(int error_code
        ) override;
    };

    MyIsDLCReadyCallback myIsDLCReadyCallback;

public:
    ViveportApiStatus* GetDLCInitCallback() { return &myDLCInitCallback; }
    ViveportApiStatus* GetDLCShutdownCallback() { return &myDLCShutdownCallback; }
    ViveportApiStatus* GetISDLCReadyCallback() { return &myIsDLCReadyCallback; }
};

ViveportDLCDemo.cpp

#include "ViveportSDKPrivatePCH.h"
#include "ViveportDLCDemo.h"


// Sets default values for this component's properties
UViveportDLCDemo::UViveportDLCDemo()
{
    // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
    // off to improve performance if you don't need them.
    PrimaryComponentTick.bCanEverTick = true;
}


// Called when the game starts
void UViveportDLCDemo::BeginPlay()
{
    Super::BeginPlay();
    myDLCInitCallback.SetDemoPtr(this);
    myIsDLCReadyCallback.SetDemoPtr(this);

    UViveportApi::Init(&myDLCInitCallback, DLC_APP_ID);
}

void UViveportDLCDemo::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
   Super::EndPlay(EndPlayReason);

    // Call ViveportApi::Shutdown()
    UViveportApi::Shutdown(&myDLCShutdownCallback);
}


// Called every frame
void UViveportDLCDemo::TickComponent(
    float DeltaTime,
    ELevelTick TickType,
    FActorComponentTickFunction* ThisTickFunction
    )
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

/***************************************************************
*            MyDLCInitCallback
***************************************************************/

void UViveportDLCDemo::MyDLCInitCallback::OnSuccess()
{
    FString fstring("Init success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    UViveportDLC::IsReady(mDemo->GetISDLCReadyCallback());
}

void UViveportDLCDemo::MyDLCInitCallback::OnFailure(int error_code)
{
    FString fstring = FString::Printf(TEXT("Init failure. error=%d"), error_code);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*               MyDLCShutdownCallback
***************************************************************/

void UViveportDLCDemo::MyDLCShutdownCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportDLCDemo][MyDLCShutdownCallback] Shutdown success."));
    FString fstring("Shutdown success.");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

void UViveportDLCDemo::MyDLCShutdownCallback::OnFailure(int error_code)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportDLCDemo][MyDLCShutdownCallback] Shutdown failure. Error = %d"), error_code);
    FString fstring = FString::Printf(TEXT("Shutdown failure. error=%d"), error_code);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}

/***************************************************************
*               MyISDLCReadyCallback
***************************************************************/

void UViveportDLCDemo::MyIsDLCReadyCallback::OnSuccess()
{
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportDLCDemo][MyIsDLCReadyCallback] IsReady success."));
    FString fstring = FString::Printf(TEXT("Is ready success"));
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Get DLC count
    int dlcCount = UViveportDLC::GetCount();
    UE_LOG(ViveportSDK, Log, TEXT("[UViveportDLCDemo][GetDLCCount] %d"), dlcCount);
    fstring = FString::Printf(TEXT("GetDLCCount: %d"), dlcCount);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);

    // Get DLC data by index
    static FString dlcAppId = mDemo->DLC_APP_ID;
    static bool isAvailable = false;
    bool isIndexZeroInRange = UViveportDLC::GetIsAvailable(0, dlcAppId, isAvailable);
    if (isIndexZeroInRange)
    {
        UE_LOG(ViveportSDK, Log, TEXT("[UViveportDLCDemo][GetDLCDataByIndex] DLC App ID: %s, Is available: %s"),
            *dlcAppId,
            isAvailable ? TEXT("true") : TEXT("false"));
        fstring = FString::Printf(TEXT("DLC App ID: %s, Is available: %s"),
            *dlcAppId,
            isAvailable ? TEXT("true") : TEXT("false"));
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
    }
    else
    {
        UE_LOG(ViveportSDK, Log, TEXT("[UViveportDLCDemo][GetDLCDataByIndex] Index zero is not in range"));
        fstring = FString::Printf(TEXT("Index zero is not in range"));
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
    }
}

void UViveportDLCDemo::MyIsDLCReadyCallback::OnFailure(int error_code)
{
    UE_LOG(ViveportSDK, Error, TEXT("[UViveportDLCDemo][MyIsDLCReadyCallback] IsReady failure. Code = %d"), error_code);
    FString fstring = FString::Printf(TEXT("IsReady failure. Code = %d"), error_code);
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, fstring);
}