> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gerenciar e licenciar conteúdo para download (DLC)

> Use produtos duráveis como conteúdo para download (DLC) no seu título — configuração no Partner Center, verificações de licenciamento, gerenciamento de instalação e código de direitos em tempo de execução.

O conteúdo para download (DLC) consiste em um produto que, quando comprado, fornece ao usuário um pacote para download. Os DLCs precisam ser licenciados e montados de forma independente antes que seu conteúdo possa ser acessado.

Os pacotes de DLC podem ser licenciados de acordo com o comportamento de compartilhamento de conteúdo de cada dispositivo, conforme descrito no [Modelo de compartilhamento de produtos para jogos](/pt-BR/publishing/xstore-commerce/xstore-product-sharing).

O Partner Center também dá suporte a produtos duráveis que não têm pacotes. Um durável sem pacote é adequado para produtos somente de licença, habilitando conteúdo já instalado com o jogo base. Esses tipos de produtos somente de licença eliminam as etapas de criação de pacotes vazios que, de outra forma, os usuários precisariam baixar. Para obter mais informações, confira [Como usar um durável sem pacote](/pt-BR/publishing/xstore-commerce/xstore-dwob).

## Fluxo de trabalho de desenvolvimento para DLC

Consulte a documentação de pacotes de conteúdo para download (DLC) para saber mais sobre como configurar o conteúdo de DLC, incluindo como fazer a associação com o jogo base por meio do MicrosoftGame.config.

Há três maneiras de instalar DLC:

1. [Implantação de DLC solta](#1-loose-dlc-deployment)
2. [Instalar o pacote de DLC localmente](#2-locally-install-dlc-package)
3. [Instalar o pacote de DLC pela Store](#3-install-dlc-package-from-store)

### 1. Implantação de DLC solta

Instale o diretório que aponta para o MicrosoftGame.config e os arquivos de ativos da sua DLC solta:

**XBOX:**

```cmd theme={null}
> xbapp deploy <DLC directory>

Package Full Name: 41336MicrosoftATG.DLC1_2020.10.14.0_neutral__dspnxghe87tn0
The operation completed successfully.
```

**PC:**

```cmd theme={null}
> wdapp register <DLC directory>  

Registered 41336MicrosoftATG.DLC1_2020.10.14.0_x64__dspnxghe87tn0
Copied temporary generated AppXManifest.xml file to C:\Users\<ntuser>\AppData\Local\Temp\41336MicrosoftATG.DLC1_2020.10.14.0_x64__dspnxghe87tn0_AppXManifest.xml
The operation completed successfully.
```

### 2. Instalar o pacote de DLC localmente

Instale o .xvc/.msixvc criado pelo makepkg:

**XBOX:**

```cmd theme={null}
> xbapp install <xvc package>  

12:16:21.800 Registered for streaming: 41336MicrosoftATG.DLC1_2020.10.14.0_neutral__dspnxghe87tn0_xs.xvc
12:16:22.645 Launch   0.00% Package   0.00%
12:16:32.650 Launch 100.00% Package 100.00%
12:16:32.651 Streaming install finished

The operation completed successfully.
```

**PC:**

```cmd theme={null}
> wdapp install <.msixvc package>  

Starting installation. See the Microsoft Store app for further details.
Launch   100% Package   100%
Installed 100%.
Installed 41336MicrosoftATG.DLC1_2020.10.14.0_x64__dspnxghe87tn0
```

### 3. Instalar o pacote de DLC pela Store

Com uma conta de teste conectada à sandbox de desenvolvimento, pesquise ou acesse por link direto a página do produto DLC no aplicativo Store e instale.

## Validar a instalação da DLC

**XBOX:**

```cmd theme={null}
> xbapp listdlc

Registered DLC by Package Full Name:

   41336MicrosoftATG.DLC1_2020.10.14.0_neutral__dspnxghe87tn0

The operation completed successfully.
```

**PC:**

```cmd theme={null}
> wdapp listdlc

Registered DLC packages by Package Full Name:

41336MicrosoftATG.DLC1_2020.10.14.0_x64__dspnxghe87tn0

The operation completed successfully.
```

No PC, também é possível ver a DLC instalada para um título específico usando `get-appxpackage` no PowerShell; observe a seção **Dependencies**:

```cmd theme={null}
> get-appxpackage 41336MicrosoftATG.DownloadableContent

Name              : 41336MicrosoftATG.DownloadableContent
Publisher         : CN=A4954634-DF4B-47C7-AB70-D3215D246AF1
Architecture      : X64
ResourceId        :
Version           : 2020.10.14.0
PackageFullName   : 41336MicrosoftATG.DownloadableContent_2020.10.14.0_x64__dspnxghe87tn0
InstallLocation   : E:\Repos\ATG\gx_dev\Samples\Live\DownloadableContent\Gaming.Desktop.x64\Debug
IsFramework       : False
PackageFamilyName : 41336MicrosoftATG.DownloadableContent_dspnxghe87tn0
PublisherId       : dspnxghe87tn0
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : True
NonRemovable      : False
Dependencies      : {41336MicrosoftATG.DLC1_2020.10.14.0_x64__dspnxghe87tn0}
IsPartiallyStaged : False
SignatureKind     : None
Status            : Ok
```

**SignatureKind** indica o tipo de pacote instalado: *None* para um pacote compilado e instalado localmente, *Store* para um pacote instalado pela Store.

## Comprar e instalar DLC

Consulte o artigo [Operações básicas da loja](/pt-BR/publishing/xstore-commerce/xstore-basic-operations) para entender como enumerar o catálogo e oferecer a possibilidade de comprar complementos. É possível determinar se um produto complementar é DLC examinando `[XStoreProduct](/reference/system/xstore/xstore_members).hasDigitalDownload`.

Se uma DLC for comprada pela Store, ela será colocada na fila para download.

Se uma DLC for comprada usando [XStoreShowPurchaseUiAsync](/pt-BR/reference/system/xstore/xstore_members), ela não será colocada na fila para download. Em vez disso, o jogo deve solicitar um download manualmente seguindo o código. Opcionalmente, um monitor pode ser criado para acompanhar o progresso.

O **identificador de pacote** é uma cadeia de caracteres opaca que identifica um pacote específico. O identificador é exclusivo por pacote, mas diferente a cada instância iniciada do jogo. Portanto, não armazene nem reutilize o identificador além da sessão atual.

Você pode usar os seguintes métodos para obter o identificador de um pacote, dependendo do cenário:

* Depois de chamar [XStoreDownloadAndInstallPackagesAsync](/pt-BR/reference/system/xstore/xstore_members) para baixar e instalar pacotes, você pode obter os identificadores desses pacotes chamando [XStoreDownloadAndInstallPackagesResult](/pt-BR/reference/system/xstore/xstore_members).
* Você pode obter os identificadores de pacotes já baixados e instalados chamando [XPackageEnumeratePackages](/pt-BR/reference/system/xstore/xstore_members) e, em seguida, recuperando o identificador do pacote da estrutura [XPackageDetails](/pt-BR/reference/system/xstore/xstore_members) retornada para sua função de retorno de chamada [XPackageEnumerationCallback](/pt-BR/reference/system/xstore/xstore_members) para cada pacote enumerado.
* Você pode obter o identificador de pacote do jogo atual chamando [XPackageGetCurrentProcessPackageIdentifier](/pt-BR/reference/system/xstore/xstore_members).

```cpp theme={null}
void StartDownload()
{
    auto async = new XAsyncBlock{};
    async->queue = m_asyncQueue;
    async->context = this;
    async->callback = [](XAsyncBlock* asyncBlockInner)
    {
        uint32_t count = 0;
        HRESULT hr = XStoreDownloadAndInstallPackagesResultCount(asyncBlockInner, &count);

        std::vector<char[XPACKAGE_IDENTIFIER_MAX_LENGTH]> packageIds(count);

        XStoreDownloadAndInstallPackagesResult(asyncBlockInner, count, packageIds.data());

        for(auto packageId : packageIds)
        {
            hr = XPackageCreateInstallationMonitor(
                packageId,  
                0,  
                nullptr,  
                1000,  
                m_asyncQueue,
                &m_pimHandle);

            if(SUCCEEDED(hr))
            {
                XTaskQueueRegistrationToken callbackToken;

                XPackageRegisterInstallationProgressChanged(
                    m_pimHandle,
                    this,
                    [](void* context, XPackageInstallationMonitorHandle pimHandle)
                    {
                        XPackageInstallationProgress progress;
                        XPackageGetInstallationProgress(pimHandle, &progress);

                        if(!progress.completed)
                        {
                            printf("%llu%% installed\n", static_cast<double>(progress.installedBytes) / static_cast<double>(progress.totalBytes);
                        }
                        else
                        {
                            XPackageCloseInstallationMonitorHandle(pimHandle);
                        }
                    }, &callbackToken);

                // Persist callbackToken to unregister upon completion
            }
        }

        delete asyncBlockInner;
    }

    const char* storeIds[] =  
    {
        "9PLNMXRKNM4C",  
        "9PLNMXRKNM5D"
    };

    HRESULT hr = XStoreDownloadAndInstallPackagesAsync(storeContext, storeIds, ARRAYSIZE(storeIds), async);

    if (FAILED(hr))
    {
        delete async;
        return;
    }
}
```

## Enumerar pacotes de DLC

Independentemente de como as DLCs são instaladas, o jogo precisa enumerar as DLCs instaladas antes de usá-las. É ao enumerar as DLCs instaladas que o identificador de pacote é obtido.

```cpp theme={null}
bool CALLBACK DlcCallback(void* context, const XPackageDetails* details)
{
    printf("DLC found: name: %s packageId: %s\n", details->displayName, details->packageIdentifier);

    return true;
}

void RefreshInstalledPackages()
{
    HRESULT hr = XPackageEnumeratePackages(
        XPackageKind::Content,  
        XPackageEnumerationScope::ThisAndRelated,  
        this,  
        DlcCallback);
}
```

## Detectar que um pacote de DLC está instalado

```cpp theme={null}
void RegisterPackageInstalledEvent()
{
    XPackageRegisterPackageInstalled(
        m_asyncQueue,
        this,  
        [](void *context, const XPackageDetails *package)
        {
            printf("Package Installed event received: %s\n", package->displayName);
        },  
        &m_packageInstallToken);
}
```

Confira a seção [Solução de problemas](/pt-BR/publishing/xstore-commerce/xstore-troubleshooting) se o exemplo de código não estiver sendo alcançado. O evento deve ser disparado independentemente do método pelo qual o pacote de DLC é instalado.

## Adquirir a licença da DLC

Em desenvolvimento, confira as observações em [Testar o licenciamento de DLC em desenvolvimento](#testing-dlc-licensing-in-development).

O jogo base precisa adquirir a licença da DLC para determinar se deve dar ao usuário acesso ao seu conteúdo.

Os jogos normalmente usam o Licenciamento Restritivo, no qual, depois que o jogo adquire a licença de um pacote, o acesso ao pacote fica bloqueado para esse dispositivo e essa instância do produto. O jogo deve liberar a licença antes que outra instância ou dispositivo possa adquirir os direitos de acesso e a licença. Fale com seu representante de conta da Microsoft para garantir que seu jogo esteja configurado para usar o Licenciamento Restritivo (não configurado no Partner Center). Para obter mais informações, confira [Licenciamento aberto e restritivo](/pt-BR/publishing/xstore-commerce/xstore-open-restrictive-licensing).

Como o jogo deve liberar a licença, ele é responsável por acompanhar todas as licenças de DLC que adquire e liberá-las quando não forem mais necessárias ou no encerramento. Se o jogo não liberar uma licença, ela será liberada automaticamente após um período de tempo limite.

```cpp theme={null}
void CALLBACK AcquireLicenseForPackageCallback(XAsyncBlock* async)
{
    XStoreLicenseHandle licenseHandle = nullptr;

    HRESULT hr = XStoreAcquireLicenseForPackageResult(
        async,
        &licenseHandle);

    if (FAILED(hr))
    {
        printf("Failed retrieve the license handle: 0x%x\n", hr);
        return;
    }

    bool isValid = XStoreIsLicenseValid(licenseHandle);

    printf("isValid: %s\n", isValid ? "true" : "false");

    hr = XStoreRegisterPackageLicenseLost(licenseHandle, m_asyncQueue, context,
       [](void *context)  
       {
           // Check if the license lost corresponded to any mounted DLC
           // If so, it is up to the game to determine an appropriate time
           // to unmount the DLC, e.g. after the current match is completed
       });

    delete async;
}

void AcquireLicenseForPackage(const char* packageIdentifier)
{
    auto async = new XAsyncBlock{};
    async->context = this;
    async->queue = m_asyncQueue;
    async->callback = AcquireLicenseForPackageCallback;

    HRESULT hr = XStoreAcquireLicenseForPackageAsync(
        m_storeContext,
        packageIdentifier,
        async);

    if (FAILED(hr))
    {
        delete async;
        return;
    }
}
```

## Determinar a origem da licença da DLC

Usando [XStoreCanAcquireLicenseForPackageAsync](/pt-BR/reference/system/xstore/xstore_members) ou [XStoreCanAcquireLicenseForStoreIdAsync](/pt-BR/reference/system/xstore/xstore_members) (dependendo do tipo de identificador), é possível determinar se a DLC é

1. Licenciável, para que você possa apresentar opções de compra caso não seja
2. Licenciável por disco ou por licença digital

```cpp theme={null}
void PreviewLicense(const char* storeId)
{
    auto async = new XAsyncBlock{};
    async->queue = m_asyncQueue;
    async->callback = [](XAsyncBlock* async)
    {
        XStoreCanAcquireLicenseResult result;

        HRESULT hr = XStoreCanAcquireLicenseForStoreIdResult(
            async,
            &result);

        if (FAILED(hr))
        {
            printf("Error calling XStoreCanAcquireLicenseForStoreIdResult: 0x%x\n", hr);
        }
        else
        {
            // Status = 1 Licensable and
            // a. licensableSku = "DISC" if disc licensed
            // b. licensableSku = "0010" or similar if digital licensed
            printf("Status: %u LicensableSku: %s\n", result.status, result.licensableSku);
        }

        delete async;
    };

    HRESULT hr = XStoreCanAcquireLicenseForStoreIdAsync(
        m_xStoreContext,
        storeId,
        async);

    if (FAILED(hr))
    {
        delete async;

        printf("Error calling XStoreCanAcquireLicenseForStoreIdAsync: 0x%x", hr);
        return;
    }
}
```

## Montar e desmontar DLC

Depois que a licença da DLC for adquirida com êxito, o conteúdo da DLC poderá ser montado e acessado.

```cpp theme={null}

void CALLBACK MountPackageCallback(XAsyncBlock* async)
{
    XPackageMountHandle mountHandle = {};

    HRESULT hr = XPackageMountWithUiResult(async, &mountHandle);

    if (SUCCEEDED(hr))
    {
        // Access DLC goodness
    }
    else
    {
        XStoreCloseLicenseHandle(license);
        printf("Error mounting package: 0x%x\n", hr);
    }

    delete async;
};

void MountPackage(const char* packageIdentifier)
{
    auto async = new XAsyncBlock{};
    async->queue = m_asyncQueue;
    async->context = context;
    async->callback = MountPackageCallback;

    HRESULT hr = XPackageMountWithUiAsync(packageIdentifier, async);

    if (FAILED(hr))
    {
        printf("XPackageMountWithUiAsync failed : 0x%x\n", hr);
        delete async;
    }
}
```

Ao desmontar, libere todos os tokens e identificadores:

```cpp theme={null}
void UnmountPackage(XPackageMountHandle mountHandle, XStoreLicenseHandle license, XTaskQueueRegistrationToken licenseLostToken)
{
    XStoreUnregisterPackageLicenseLost(license, licenseLostToken, false);

    XPackageCloseMountHandle(mountHandle);

    XStoreCloseLicenseHandle(license);
}
```

## Desinstalar DLC

Use [XPackageUninstallPackage](/pt-BR/reference/system/xstore/xstore_members) para desinstalar um pacote de DLC. O pacote deve ser desmontado primeiro.

## Smart Delivery e DLC

É possível que títulos do XBOX Series X/S licenciem e montem DLC criada para o título do XBOX One. Normalmente, esse cenário ocorre quando o pacote de DLC não contém dados usados pelo jogo. A única maneira de verificar é se a ID `AllowedProduct` da DLC ERA no seu package.appxmanifest, que é um GUID, corresponde à ID de produto XBOX herdada atribuída ao produto no Partner Center.

Caso contrário, o título possivelmente foi migrado do XBOX Developer Portal (XDP) desativado e só funciona com pacotes baixados da Store, pois a versão do XBOX Series X/S é atribuída à ID de produto do XBOX One. Para fins de desenvolvimento, confira a observação na seção [Solução de problemas](/pt-BR/publishing/xstore-commerce/xstore-troubleshooting).

## DLC de produtos diferentes

É possível enumerar e usar DLC de um produto diferente. Para o título que deseja usar uma DLC de um produto diferente, atribua uma relação "Can sell and use" ao produto DLC na seção **Product relationship setup** do Partner Center. A seleção de produtos disponíveis é limitada à conta do editor.

## Testar o licenciamento de DLC em desenvolvimento

Para obter mais informações, confira [Habilitar testes de licença](/pt-BR/publishing/xstore-commerce/xstore-licensing-setup).

Os pacotes de DLC locais devem ser criados com um parâmetro /contentid.

Cada pacote de DLC deve ter seu EKBID substituído dos valores padrão.

## Documentação de referência da API

* [XStore (conteúdo da API)](/pt-BR/reference/system/xstore/xstore_members)
  * Funções
    * [XStoreShowPurchaseUiAsync](/pt-BR/reference/system/xstore/xstore_members)
    * [XStoreDownloadAndInstallPackagesAsync](/pt-BR/reference/system/xstore/xstore_members)
    * [XStoreDownloadAndInstallPackagesResult](/pt-BR/reference/system/xstore/xstore_members)
    * [XStoreCanAcquireLicenseForPackageAsync](/pt-BR/reference/system/xstore/xstore_members)
    * [XStoreCanAcquireLicenseForStoreIdAsync](/pt-BR/reference/system/xstore/xstore_members)
  * Estruturas
    * [xstoreproduct](/pt-BR/reference/system/xstore/xstore_members)
* [XPackage (conteúdo da API)](/pt-BR/reference/system/xstore/xstore_members)
  * Funções
    * [XPackageEnumeratePackages](/pt-BR/reference/system/xstore/xstore_members)
    * [XPackageEnumerationCallback](/pt-BR/reference/system/xstore/xstore_members)
    * [XPackageGetCurrentProcessPackageIdentifier](/pt-BR/reference/system/xstore/xstore_members)
    * [XPackageUninstallPackage](/pt-BR/reference/system/xstore/xstore_members)
  * Estruturas
    * [XPackageDetails](/pt-BR/reference/system/xstore/xstore_members)

## Confira também

[Visão geral do Commerce](/pt-BR/publishing/xstore-commerce/xstore-commerce-overview)

[Habilitar testes de licença](/pt-BR/publishing/xstore-commerce/xstore-licensing-setup)

[Como usar um durável sem pacote](/pt-BR/publishing/xstore-commerce/xstore-dwob)

[Referência da API XStore](/pt-BR/reference/system/xstore/xstore_members)


## Related topics

- [Guia de BVT de console da certificação](/pt-BR/publishing/game-publishing/concepts/certification/certification-console-bvt-guide.md)
- [XR-037 Dependências de pacotes de conteúdo](/pt-BR/publishing/certification/xr/xr-037.md)
- [Requisitos XBOX testados na certificação para jogos de console XBOX](/pt-BR/publishing/certification/console-cert-tested-requirements.md)
- [Administración y licencias de contenido descargable (DLC)](/es/publishing/xstore-commerce/xstore-dlc.md)
- [Guia de BVT de PC da certificação](/pt-BR/publishing/game-publishing/concepts/certification/certification-pc-bvt-guide.md)
