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

# XUserAddAsync

> XUserAddAsync

# XUserAddAsync

게임 세션에 사용자를 비동기적으로 추가합니다.

## 구문

```cpp theme={null}
HRESULT XUserAddAsync(  
         XUserAddOptions options,  
         XAsyncBlock* async  
)  
```

### 매개변수

*options*   \_In\_\
형식: [XUserAddOptions](/reference/system/xuser/enums/xuseraddoptions)

게임 세션에 사용자를 추가하기 위한 옵션입니다.

*async*   \_Inout\_\
형식: [XAsyncBlock\*](/reference/system/xasync/structs/xasyncblock)

호출의 상태를 폴링하고 호출 결과를 가져오기 위한 [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)입니다.

### 반환값

형식: HRESULT

HRESULT 성공 또는 오류 코드입니다.
오류 코드 목록은 [Error Codes](/reference/errorcodes)를 참조하십시오.

## 설명

**XUserAddAsync**는 게임에 사용자를 추가하는 비동기 작업을 시작합니다. 작업 결과를 가져오려면
[XUserAddResult](/reference/system/xuser/functions/xuseraddresult)를 사용합니다.

**XUserAddAsync**는
[XUserAddOptions::AddDefaultUserSilently](/reference/system/xuser/enums/xuseraddoptions) 또는
[XUserAddOptions::AddDefaultUserAllowingUI](/reference/system/xuser/enums/xuseraddoptions)가 *options* 매개변수에 전달되지 않는 한 항상 계정 선택 UI를 표시합니다.

**XUserAddOptions::AddDefaultUserSilently**를 사용하는 경우 **XUserAddAsync**는 UI를 표시하지 않습니다.

[간소화된 사용자 모델(NDA 항목)](/build/core-features/common/user/gamecore-user-models)을 사용할 때 이 함수에는 몇 가지 고려 사항이 있습니다.

* 간소화된 사용자 모델을 사용할 때, 개발자는 *options*가
  **XUserAddOptions::AddDefaultUserSilently**로 설정되도록 해야 합니다.
* 콘솔에서 간소화된 사용자 모델을 사용하는 loose-deployed 게임은 기본 사용자가 이미 로그인되어 있지 않으면
  실행이 허용되지 않습니다.
* PC에서 간소화된 사용자 모델을 사용하는 loose-deployed 게임은 사용자 없이도 실행할 수 있지만,
  게임이 **XUserAddAsync**를 호출하고 로그인된 사용자가 없는 경우, 게임이 종료되며
  사용자 로그인을 돕기 위해 PC Bootstrapper가 실행됩니다. 사용자가 XBOX Live에 완전히 로그인되어 있으면
  이후 실행은 정상적으로 작동합니다.

*options*를 **XUserAddOptions::AddDefaultUserSilently**로 설정하여 **XUserAddAsync**를 반복해서 호출하는 경우
개발자가 알아야 할 몇 가지 예외적인 상황이 있습니다.

* 이 함수를 반복해서 호출할 때 게임을 시작한 기본 사용자를 알고 있는 경우, 동일한 사용자를 반환합니다.
* 이전에 알려진 기본 사용자가 로그아웃했고, 장치에 로그인된 사용자가 한 명뿐인 경우,
  해당 사용자를 새 "기본" 사용자로 표시하고 반환합니다.
* 이전에 알려진 기본 사용자가 로그아웃했고, 장치에 로그인된 사용자가 여러 명인 경우,
  E\_GAMEUSER\_NO\_DEFAULT\_USER를 반환합니다.

기본 사용자를 사용할 수 없는 경우, [XUserAddResult](/reference/system/xuser/functions/xuseraddresult)는
E\_GAMEUSER\_NO\_DEFAULT\_USER를 반환합니다. *options*를
**XUserAddOptions::AddDefaultUserSilently**로 설정하지 않고 **XUserAddAsync**를 호출해야 합니다.

*options*를 **XUserAddOptions::AddDefaultUserAllowingUI**로 설정하여
**XUserAddAsync**를 반복해서 호출하는 경우에도 개발자가 알아야 할 몇 가지 예외적인 상황이 있습니다. 이는 자동(무음) UI 경우와 매우 유사(동일하지는 않음)합니다.

* 이 함수를 반복해서 호출할 때 게임을 시작한 기본 사용자를 알고 있는 경우, 동일한 사용자를 반환합니다.
* 이전에 알려진 기본 사용자가 로그아웃했고, 장치에 로그인된 사용자가 한 명뿐인 경우, 해당 사용자를 새 "기본" 사용자로 표시하고 반환합니다.
* 처음 게임을 시작한 사용자가 로그아웃했고, 사용자 수가 0명이거나 두 명 이상인 경우, 시스템이 UI를 표시하여 사용자를 가져오고 해당 사용자를 기본 사용자로 설정합니다.

[XUserAddOptions::AllowGuests](/reference/system/xuser/enums/xuseraddoptions)는
**XUserAddOptions::AddDefaultUserSilently**와 함께 사용할 수 없습니다. 게스트는 기본 사용자가 될 수 없습니다. 현재 플랫폼이 게스트를 지원하는지 여부와 관계없이
**XUserAddOptions::AllowGuests**를 안전하게 사용할 수 있습니다.

**XUsers** API에서 가져오는 각 **XUserHandle** 핸들은
[XUserCloseHandle](/reference/system/xuser/functions/xuserclosehandle)을 호출하여 한 번만 닫아야 합니다.

**XUserAddAsync**가 성공적으로 완료되면 입력 장치 페어링이 수행됩니다. **XUserAddOptions::AddDefaultUserSilently** 또는 **XUserAddOptions::AddDefaultUserAllowingUI** 옵션으로 인해 UI 없이 로그인이 자동으로 이루어진 경우, 시스템에서 사용자에게 할당된 입력 장치가 타이틀에 전파됩니다. 로그인을 위해 UI가 표시된 경우, 사용자를 선택한 입력 장치가 해당 사용자에게 할당됩니다.

장치 연결은 [XUserRegisterForDeviceAssociationChanged](/reference/system/xuser/functions/xuserregisterfordeviceassociationchanged) 메서드를 통해 추적할 수 있습니다.

다음 예제는 게임 세션에 사용자를 비동기적으로 추가하는 방법을 보여줍니다.

```cpp theme={null}
HRESULT AddUserComplete(XAsyncBlock* ab)
{
    unique_user_handle user;
    RETURN_IF_FAILED(XUserAddResult(ab, &user));

    XUserLocalId userLocalId;
    XUserGetLocalId(user.get(), &userLocalId);

    auto iter = std::find_if(
        _users.begin(),
        _users.end(),
        [&userLocalId](const User& candidate)
    {
        XUserLocalId candidateUserLocalId;
        XUserGetLocalId(candidate.Handle(), &candidateUserLocalId);
        return candidateUserLocalId == userLocalId;
    });

    // User already known
    if (iter != _users.end())
    {
        appLog.AddLog("User already in list\n");
        return S_OK;
    }

    try
    {
        _users.emplace_back(user.get());
        _users.back().LoadGamerPicAsync(_queue);
    }
    CATCH_RETURN();

    return S_OK;
}

HRESULT AddUser(bool allowGuests, bool silent)
{
    auto asyncBlock = std::make_unique<XAsyncBlock>();
    ZeroMemory(asyncBlock.get(), sizeof(*asyncBlock));
    asyncBlock->queue = _queue;
    asyncBlock->context = this;
    asyncBlock->callback = [](XAsyncBlock* ab)
    {
        auto asyncBlock = std::unique_ptr<XAsyncBlock>(ab);
        LOG_IF_FAILED(static_cast<UserWindow*>(ab->context)->AddUserComplete(ab));
    };

    XUserAddOptions options = XUserAddOptions::None;

    if (allowGuests)
    {
        WI_SET_FLAG(options, XUserAddOptions::AllowGuests);
    }

    if (silent)
    {
        WI_SET_FLAG(options, XUserAddOptions::AddDefaultUserSilently);
    }

    if (SUCCEEDED_LOG(XUserAddAsync(
        options,
        asyncBlock.get())))
    {
        // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
        // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
        asyncBlock.release();
    }

    return S_OK;
}
```

## 요구 사항

**헤더:** XUser.h

**라이브러리:** xgameruntime.lib

**지원되는 플랫폼:** Windows, Steam Deck, XBOX One 계열 콘솔 및 XBOX Series 콘솔

## 개념 문서

* [Microsoft Game Development Kit(GDK) API 작업 실행](/build/core-features/common/async/async-libraries/async-library-xasync-example-run-gdk-task)
* [비동기 프로그래밍 설계 목표 및 개선 사항](/build/core-features/common/async/async-whitepaper)
* [게임에서 플레이어 로그인 구현](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/pc-dev/tutorials/pc-e2e-guide/e2e-services/e2e-user-sign-in)
* [Game Chat 2 소개](/services/xbox-services/multiplayer/chat/game-chat2/game-chat-2-intro)
* [Game Chat 2 C++ API 사용](/services/xbox-services/multiplayer/chat/game-chat2/using-game-chat-2)
* [플레이어 로그인 구현](https://learn.microsoft.com/gaming/gdk/docs/services/playfab-integration/gdk-playfab-player-sign-in-steps)

## 함께 보기

[XUser](/reference/system/xuser/xuser_members)

[XUserAddOptions](/reference/system/xuser/enums/xuseraddoptions)

[XUserCloseHandle](/reference/system/xuser/functions/xuserclosehandle)


## Related topics

- [XUserAddOptions](/ko/reference/system/xuser/enums/xuseraddoptions.md)
- [XUserAddResult](/ko/reference/system/xuser/functions/xuseraddresult.md)
- [GDK용 Unity C# API 래퍼](/ko/build/gdk-and-engines/unity/unity-api-wrappers.md)
- [사용자 ID 및 XUser](/ko/build/core-features/common/user/player-identity-xuser.md)
- [로그인 및 샌드박스 오류 문제 해결](/ko/services/xbox-services/develop/troubleshooting/live-troubleshoot-sandboxes.md)
