> ## 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.

# Multiplayer Activity에 대한 예제 코드

> 활동 설정, 초대 보내기, GDK 타이틀에서 최근 플레이어 목록 업데이트를 위한 XBOX Multiplayer Activity C++ 빠른 시작 예제입니다.

<a id="top" />

이 항목은 Multiplayer Activity Client API의 기본 사용에 대한 빠른 시작 가이드로 사용됩니다. 이 항목에서는 활동 관리, 초대 보내기 및 최근 플레이어 목록에 플레이어 추가에 대해 설명합니다.

[활동](#activities) [초대](#invites) [최근 플레이어](#recent-players)

<a id="activities" />

## 활동

### 활동 설정

타이틀이 멀티플레이어 경험을 시작하거나 참여할 때마다, 활동을 만들어야 합니다. 이렇게 하면 셸과 타이틀 내의 다른 플레이어가 플레이어의 활동을 볼 수 있고, 다른 플레이어가 진행 중인 게임에 잠재적으로 참여할 수 있게 합니다. 플레이어가 타이틀에 대한 활동에 참여하려고 하고 실행되지 않는 경우, 활성화되고 연결 문자열이 전달됩니다.

타이틀은 플레이어가 참여하거나 나갈 때 활동을 업데이트해야 합니다. 이렇게 하면 다른 플레이어에게 활동에 대한 더 풍부한 보기를 제공하고 활동이 가득 찼는지 알려줍니다.

활동 필드에 대한 자세한 내용은 [활동 내용](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-activities#activity-contents)을 참조하세요.

활동을 설정하기 위한 코드 예제는 다음과 같습니다. 활동을 만드는 것과 기존 활동을 업데이트하는 것 모두에 적용됩니다.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

XblMultiplayerActivityInfo info{};
info.connectionString = "dummyConnectionString";
info.joinRestriction = XblMultiplayerActivityJoinRestriction::Followed;
info.maxPlayers = 10;
info.currentPlayers = 1;
info.groupId = "dummyGroupId";

HRESULT hr = XblMultiplayerActivitySetActivityAsync(
    xblContext,
    &info,
    false,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityInfo](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo)
* [XblMultiplayerActivityJoinRestriction](/reference/live/xsapi-c/multiplayer_activity_c/enums/xblmultiplayeractivityjoinrestriction)
* [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync)

[이 항목의 맨 위로 돌아가기.](#top)

<a id="getting-an-activity" />

### 활동 가져오기

타이틀은 다른 플레이어의 활동을 알고 싶어할 수 있습니다. 예를 들어, 타이틀은 활동과 함께 타이틀 내 플레이어의 친구에 대한 게임 내 UI를 표시하려고 할 수 있습니다.

활동을 검색하기 위한 코드 예제는 다음과 같습니다.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.

    size_t resultSize{};
    HRESULT hr = XblMultiplayerActivityGetActivityResultSize(async, &resultSize);
    if (SUCCEEDED(hr))
    {
        std::vector<uint8_t> buffer(resultSize);
        XblMultiplayerActivityInfo* activityInfo{};
        size_t resultCount{};
        hr = XblMultiplayerActivityGetActivityResult(async, buffer.size(), buffer.data(), &activityInfo, &resultCount, nullptr);
        if (SUCCEEDED(hr))
        {
            // ...
        }
    }
};

HRESULT hr = XblMultiplayerActivityGetActivityAsync(
    xblContext,
    &xuid,
    1,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XblMultiplayerActivityGetActivityResultSize](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresultsize)
* [XblMultiplayerActivityInfo](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo)
* [XblMultiplayerActivityGetActivityResult](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresult)
* [XblMultiplayerActivityGetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityasync)

[이 항목의 맨 위로 돌아가기.](#top)

### 활동 삭제

플레이어가 멀티플레이어 활동을 종료하거나 나가면, 타이틀은 다음 코드를 사용하여 활동을 삭제해야 합니다.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityDeleteActivityAsync(xblContext, async.get());

if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityDeleteActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitydeleteactivityasync)

[이 항목의 맨 위로 돌아가기.](#top)

<a id="invites" />

## 초대

### UI 없이 초대 보내기

플레이어는 다른 하나 이상의 플레이어에게 직접 초대를 보내려고 할 수 있습니다. 초대를 보내기 전에, 타이틀은 활동이 설정되어 있는지 확인해야 합니다. 이렇게 하면 셸이 현재 활동을 기반으로 초대를 보내기 때문에 셸과 타이틀 간에 연속성이 보장됩니다.

UI 없이 초대를 보내려면, [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync)(위 예제 참조)를 사용하여 활동이 설정된 후, 타이틀은 초대할 플레이어 배열과 현재 활동에서 사용되는 것과 동일한 연결 문자열을 전달하여 [XblMultiplayerActivitySendInvitesAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync) API를 호출해야 합니다.

초대 내용에 대한 자세한 내용은 [다른 플레이어가 멀티플레이어 경험에 참여하도록 요청 보내기.](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites)를 참조하세요.

UI 없이 초대를 보내기 위한 코드 예제는 다음과 같습니다.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivitySendInvitesAsync(
    xblContext,
    &xuid,
    1,
    true, // Setting false will send the invite to only players on the sender's platform.
    "dummyConnectionString",
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivitySendInvitesAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync)

### UI로 초대 보내기

플레이어는 다른 하나 이상의 플레이어에게 직접 초대를 보내려고 할 수 있습니다. 초대를 보내기 전에, 타이틀은 활동이 설정되어 있는지 확인해야 합니다. 이렇게 하면 셸이 현재 활동을 기반으로 초대를 보내기 때문에 셸과 타이틀 간에 연속성이 보장됩니다.

UI로 초대를 보내려면, [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync)(위 예제 참조)를 사용하여 활동이 설정된 후, 타이틀은 요청 사용자를 전달하여 [XGameUiShowMultiplayerActivityGameInviteAsync](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync) API를 호출해야 합니다. 이는 타이틀의 현재 활동을 사용하고 연결 문자열과 설정을 사용하여 플레이어를 초대합니다.

초대 내용에 대한 자세한 내용은 [다른 플레이어가 멀티플레이어 경험에 참여하도록 요청 보내기.](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites)를 참조하세요.

UI로 초대를 보내기 위한 코드 예제는 다음과 같습니다.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XGameUiShowMultiplayerActivityGameInviteResult(async);
    if (hrAsync == S_OK) 
    { 
        // Handle success 
    } 
    else 
    { 
        // Likely will only happen during development - usually indicates 
        // an invalid user was passed in or that there is no multiplayer activity set
    }     
};

HRESULT hr = XGameUiShowMultiplayerActivityGameInviteAsync(
    async.get()
    requestingUser
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XGameUiShowMultiplayerActivityGameInviteAsync](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync)
* [XGameUiShowMultiplayerActivityGameInviteResult](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteresult)

[이 항목의 맨 위로 돌아가기.](#top)

### 초대 받기

플레이어가 초대를 수락했을 때 알림을 받으려면, 타이틀은 `XGameInviteRegisterForEvent`를 사용하여 초대 알림에 등록할 수 있습니다. 초대가 수락될 때마다, 형식화된 URI가 등록된 콜백을 통해 타이틀에 전달됩니다. URI를 구문 분석하여 초대 발신자, 수신자 및 연결 문자열을 확인할 수 있습니다. 연결 문자열은 타이틀별로 지정되며 멀티플레이어 활동이 생성될 때 설정됩니다. Multiplayer Activity 서비스를 사용하는 타이틀의 경우, URI의 전체 형식은 다음 표에 표시되어 있습니다.

| 플랫폼                                                                          | 형식                                                                                                       |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| 콘솔의 Microsoft Game Development Kit(GDK) 또는 XBOX One Software Development Kit | `ms-xbl-<titleId>://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>`   |
| PC의 Microsoft Game Development Kit(GDK) 또는 Universal Windows Platform(UWP)   | `ms-xbl-multiplayer://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>` |

초대 알림이 더 이상 필요하지 않은 경우, `XGameInviteUnregisterForEvent`를 사용하여 콜백 등록을 취소할 수 있습니다. 수락된 초대를 등록하고 처리하기 위한 코드 예제는 다음과 같습니다.

```cpp theme={null}
void CALLBACK MyXGameInviteEventCallback(
    _In_opt_ void* context,
    _In_ const char* inviteUri)
{
    if (inviteUri != nullptr)
    {
        std::string uri{ inviteUri };
        size_t invitedUserBegin = uri.find("invitedUser=");
        size_t senderBegin = uri.find("sender=");
        std::string invitedUser = uri.substr(invitedUserBegin, uri.find('&', invitedUserBegin) - invitedUserBegin);
        std::string sender = uri.substr(senderBegin, uri.find('&', senderBegin) - senderBegin);
        std::string connectionString = uri.substr(uri.find("connectionString="));

        // ...
    }
}

XTaskQueueRegistrationToken token = { 0 };
HRESULT hr = XGameInviteRegisterForEvent(
    queue,
    nullptr,
    MyXGameInviteEventCallback,
    &token
    );

// ...
bool result = XGameInviteUnregisterForEvent(token, true);
```

자세한 내용은 다음을 참조하세요.

* [XGameInviteRegisterForEvent](/reference/system/xgameinvite/functions/xgameinviteregisterforevent)
* [XGameInviteUnregisterForEvent](/reference/system/xgameinvite/functions/xgameinviteunregisterforevent)

[이 항목의 맨 위로 돌아가기.](#top)

<a id="recent-players" />

## 최근 플레이어

플레이어의 최근 플레이어 목록을 업데이트하려면, 타이틀은 현재 플레이어와 의미 있는 상호작용을 한 다른 플레이어의 목록을 제출해야 합니다. 목록은 단방향입니다. 즉, 각 플레이어의 클라이언트는 자신의 목록을 업데이트해야 하며, 플레이어 목록은 서로의 목록에 영향을 미치지 않습니다.

예를 들어, 플레이어 그룹이 게임 전 로비에 함께 있고 매치되어 있다고 가정해 보겠습니다. 각 플레이어는 매치가 시작될 때 로비에 있는 모든 다른 `xuids`로 목록을 업데이트합니다. 새 플레이어가 참여하는 경우, 개별적으로 작성될 수 있습니다.

<Note>
  의미 있는 상호작용을 정의하는 것을 결정할 수 있습니다. 한 타이틀의 경우, 로비에 있는 것일 수 있습니다. 다른 타이틀의 경우, 한 플레이어가 다른 플레이어를 쏘는 것일 수 있습니다. 세 번째 타이틀의 경우, 다른 플레이어가 화면에 보이는 것만으로도 충분할 수 있습니다.
</Note>

매치 세션이 시작될 때까지 플레이어 팀이 보이지 않도록 하려는 시나리오에서는, 서로 표시하려는 시점까지 플레이어 목록 작성을 지연시킬 수 있습니다. 클라이언트 측 최근 플레이어 목록을 플러시하려면, 즉시 강제 플러시가 필요한 경우 `XblMultiplayerActivityFlushRecentPlayersAsync`를 호출할 수 있습니다. 그렇지 않으면 최근 플레이어 목록은 5초마다 자동으로 플러시됩니다.

최근 플레이어 목록 업데이트 및 업데이트 플러시에 대한 코드 예제는 다음과 같습니다.

### 최근 플레이어 업데이트

```cpp theme={null}
XblMultiplayerActivityRecentPlayerUpdate update{ xuid };
HRESULT hr = XblMultiplayerActivityUpdateRecentPlayers(xblContext, &update, 1);
```

자세한 내용은 다음을 참조하세요.

* [XblMultiplayerActivityRecentPlayerUpdate](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityrecentplayerupdate)
* [XblMultiplayerActivityUpdateRecentPlayers](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityupdaterecentplayers)

[이 항목의 맨 위로 돌아가기.](#top)

### 최근 플레이어 플러시

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityFlushRecentPlayersAsync(xblContext, async.get());
if (SUCCEEDED(hr))
{
    async.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityFlushRecentPlayersAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityflushrecentplayersasync)

[이 항목의 맨 위로 돌아가기.](#top)


## Related topics

- [Multiplayer Activity 예제 코드](/ko/services/xbox-services/multiplayer/mpa/how-to/live-mpa-how-to-nav.md)
- [Multiplayer Activity(MPA)](/ko/services/xbox-services/multiplayer/mpa/live-mpa-nav.md)
- [Real-Time Activity(RTA) 서비스 예제 코드](/ko/services/xbox-services/fundamentals/rta/how-to/live-rta-howto-nav.md)
- [XblMultiplayerActivityGetActivityResultSize](/ko/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresultsize.md)
- [XblMultiplayerActivityGetActivityResult](/ko/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresult.md)
