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

# 使用 SmartMatch 和 MPM 进行多人游戏匹配

> 使用 Multiplayer Manager 和 SmartMatch 匹配来查找 XBOX Live 玩家、创建大厅会话、发送可选邀请以及启动多人游戏对局。

<a id="top" />

本主题介绍使用 Multiplayer Manager 实现 SmartMatch 匹配所需的基本步骤。

当玩家想要玩游戏时,可能没有足够的在线好友,或者他们只是想与在线的随机玩家对战。
你可以使用 SmartMatch 服务来查找其他 XBOX 玩家。

## 查找对局

以下步骤使用 Multiplayer Manager 向玩家的好友发送邀请,以便该好友可以加入正在进行的游戏。

1. [初始化 Multiplayer Manager](#initialize-multiplayer-manager)
2. [通过添加本地用户创建大厅会话](#create-lobby)
3. [向好友发送邀请(可选)](#send-invites)
4. [接受邀请(可选)](#accept-invites)
5. [查找对局](#find-match)

步骤 1、2、3 和 5 在执行邀请的设备上完成。
步骤 4 通常在被邀请者的设备上启动,在通过协议激活启动应用之后。

有关详细信息,请参阅[使用 SmartMatch 匹配玩游戏(流程图)](/services/xbox-services/multiplayer/mpm/concepts/flowcharts/live-mpm-play-with-smartmatch-matchmaking)。

## 初始化 Multiplayer Manager <a id="initialize-multiplayer-manager" />

当使用有效的会话模板名称初始化 Multiplayer Manager 时,会自动创建大厅会话对象。会话模板在服务配置中定义。

<Note>在添加用户之前,服务上的大厅会话实例不会被创建。</Note>

### 扁平 C API

```cpp theme={null}
HRESULT hr = XblMultiplayerManagerInitialize(lobbySessionTemplateName, queueUsedByMultiplayerManager);
```

有关详细信息,请参阅 [XblMultiplayerManagerInitialize](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerinitialize)。

[返回本主题顶部。](#top)

## 通过添加本地用户创建大厅会话<a id="create-lobby" />

将本地登录的 XBOX 服务用户添加到大厅会话。
当添加第一个用户时,会承载一个新的大厅。
所有其他用户以次要用户身份被添加到现有大厅。

Multiplayer Manager 在系统外壳中通告该大厅,以便好友加入。
只有在你添加了本地用户之后,才能发送邀请、设置大厅属性以及访问大厅成员。

当本地用户加入大厅时,我们建议设置他们的连接地址和任何自定义属性。

你必须对所有本地登录的用户重复此过程。

### 添加单个本地用户

#### 扁平 C API

```cpp theme={null}
HRESULT hr = XblMultiplayerManagerLobbySessionAddLocalUser(xblUserHandle);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set member connection address.
const char* connectionAddress = "1.1.1.1";
hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
    xblUserHandle, connectionAddress, context);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set custom member properties.
const char* propName = "Name";
const char* propValueJson = "{}";
hr = XblMultiplayerManagerLobbySessionSetProperties(propName, propValueJson, context);

if (!SUCCEEDED(hr))
{
    // Handle failure.
}
...
```

有关详细信息,请参阅以下内容:

* [XblMultiplayerManagerLobbySessionAddLocalUser](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionaddlocaluser)
* [XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetlocalmemberconnectionaddress)
* [XblMultiplayerManagerLobbySessionSetProperties](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetproperties)

[返回本主题顶部。](#top)

### 添加多个本地用户

#### 扁平 C API

```cpp theme={null}
std::vector<XblUserHandle> xblUsers;
for (XblUserHandle xblUserHandle : xblUsers)
{
    HRESULT hr = XblMultiplayerManagerLobbySessionAddLocalUser(xblUserHandle);

    if (!SUCCEEDED(hr))
    {
        // Handle failure.
    }

    // Set member connection address.
    const char* connectionAddress = "1.1.1.1";
    hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
        xblUserHandle, connectionAddress, context);

    if (!SUCCEEDED(hr))
    {
        // Handle failure.
    }

    // Set custom member properties.
    const char* propName = "Name";
    const char* propValueJson = "{}";
    hr = XblMultiplayerManagerLobbySessionSetProperties(propName, propValueJson, context);
    ...
}
```

有关详细信息,请参阅以下内容:

* [XblMultiplayerManagerLobbySessionAddLocalUser](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionaddlocaluser)
* [XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetlocalmemberconnectionaddress)
* [XblMultiplayerManagerLobbySessionSetProperties](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetproperties)

这些更改在下一次 [XblMultiplayerManagerDoWork](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerdowork) 调用时被批处理。
每次将本地用户添加到大厅会话时,Multiplayer Manager 都会触发 [XblMultiplayerEventType](/reference/live/xsapi-c/multiplayer_manager_c/enums/xblmultiplayereventtype)`::UserAdded` 事件。

我们建议检查事件的错误代码,以查看该用户是否已成功添加。
如果失败,错误消息会提供失败原因的详细信息。

Multiplayer Manager 执行以下功能,以通过添加本地用户来创建大厅会话。

* 向 XBOX 服务多人游戏服务注册 Real-Time Activity 和多人游戏订阅。
* 创建大厅会话。
* 将所有本地玩家加入为活动状态。
* 上传安全设备地址 (SDA)。
* 设置成员属性。
* 注册会话变更事件。
* 将大厅会话设置为活动会话。

[返回本主题顶部。](#top)

## 向好友发送邀请(可选) <a id="send-invites" />

显示标准 XBOX UI,玩家可以从中选择好友或最近玩过的玩家邀请加入游戏。
当玩家确认选择时,Multiplayer Manager 会向所选玩家发送邀请。

游戏也可以使用 [XblMultiplayerManagerLobbySessionInviteUsers](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessioninviteusers) 方法向一组由 XBOX 服务用户 ID 定义的玩家发送邀请。
如果你使用自己的游戏内 UI 而不是标准 XBOX UI,则此方法很有用。

#### 扁平 C API

```cpp theme={null}
size_t xuidsCount = 1;
uint64_t xuids[1] = {};
xuids[0] = 1234567891234567;
HRESULT hr = XblMultiplayerManagerLobbySessionInviteUsers(
    xblUserHandle, 
    xuids, 
    xuidsCount, 
    nullptr,    // ContextStringId 
    nullptr     // CustomActivationContext
);
```

有关详细信息,请参阅 [XblMultiplayerManagerLobbySessionInviteUsers](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessioninviteusers)。

Multiplayer Manager 执行以下功能以向好友发送邀请。

* 显示 XBOX 标准游戏可调用 UI (TCUI)
* 直接向所选玩家发送邀请

[返回本主题顶部。](#top)

## 接受邀请(可选) <a id="accept-invites" />

当受邀玩家接受游戏邀请或通过外壳 UI 加入好友的游戏时,系统会通过协议激活在其设备上启动游戏。
游戏启动后,Multiplayer Manager 可以使用协议激活的事件参数加入大厅。

如果未通过 [XblMultiplayerManagerLobbySessionAddLocalUser](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionaddlocaluser) 添加受邀用户,则 [XblMultiplayerManagerJoinLobby](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerjoinlobby) 会失败,并通过 `JoinLobbyCompleted` 事件调用 [XblMultiplayerEventArgsXuid](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayereventargsxuid) 提供邀请所针对的 xuid。

加入大厅后,我们建议设置本地成员的连接地址以及该成员的任何自定义属性。
如果不存在主机,你还可以通过 [XblMultiplayerManagerLobbySessionSetSynchronizedHost](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetsynchronizedhost) 设置主机。

最后,如果游戏已在进行中且有空位容纳被邀请者,Multiplayer Manager 会自动将用户加入游戏会话。
游戏会通过 `JoinGameCompleted` 事件收到通知,并提供相应的错误代码和消息。

错误或成功结果通过 `JoinLobbyCompleted` 事件处理。

#### 扁平 C API

```cpp theme={null}
HRESULT hr = XblMultiplayerManagerJoinLobby(inviteHandleId, xblUserHandle);
if (!SUCCEEDED(hr))
{
    // Handle failure.
}

// Set member connection address.
const char* connectionAddress = "1.1.1.1";
hr = XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress(
    xblUserHandle, connectionAddress, context);
```

有关详细信息,请参阅以下内容:

* [XblMultiplayerManagerJoinLobby](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerjoinlobby)
* [XblMultiplayerManagerLobbySessionSetLocalMemberConnectionAddress](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerlobbysessionsetlocalmemberconnectionaddress)

Multiplayer Manager 执行以下功能以接受邀请。

* 注册 Real-Time Activity 和多人游戏订阅。
* 加入大厅会话。
* 清理现有的大厅状态。
* 将所有本地玩家加入为活动状态。
* 上传 SDA。
* 设置成员属性。
* 注册会话变更事件。
* 将大厅会话设置为活动会话。
* 加入游戏会话(如果存在)。
* 使用传输句柄。

### 查找对局 <a id="find-match" />

在邀请被接受并且主机准备开始游戏后,你可以使用 SmartMatch 执行以下操作之一:

* 通过调用 [XblMultiplayerManagerFindMatch](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerfindmatch) 查找具有足够开放玩家席位以容纳大厅会话中所有成员的现有游戏。
* 通过调用 [XblMultiplayerManagerJoinGameFromLobby](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerjoingamefromlobby) 并随后调用 [XblMultiplayerManagerAutoFillMembersDuringMatchmaking](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerautofillmembersduringmatchmaking) 来创建一个新的游戏会话,该会话包含大厅会话中的所有成员,并使用寻找同类型游戏的其他玩家填充开放席位。

在你可以调用 [XblMultiplayerManagerFindMatch](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerfindmatch) 之前,必须先在服务配置中配置 hopper。
hopper 定义了 SmartMatch 用于匹配玩家的规则。

#### 扁平 C API

```cpp theme={null}
uint32_t timeoutInSeconds = 30;
HRESULT hr = XblMultiplayerManagerFindMatch(hopperName, attributesJson, timeoutInSeconds);
if (!SUCCEEDED(hr))
{
    // Handle failure.
}
```

有关详细信息,请参阅 [XblMultiplayerManagerFindMatch](/reference/live/xsapi-c/multiplayer_manager_c/functions/xblmultiplayermanagerfindmatch)。

Multiplayer Manager 执行以下功能以查找对局。

* 创建匹配票据。
* 处理所有服务质量 (QoS) 阶段。
* 处理名单变更。
* 重新提交(如果需要)。
* 加入目标游戏会话。
* 通过大厅会话通告游戏。

[返回本主题顶部。](#top)


## Related topics

- [SmartMatch 匹配](/zh-CN/services/xbox-services/multiplayer/matchmaking/live-matchmaking-nav.md)
- [使用 SmartMatch 匹配玩游戏(流程图)](/zh-CN/services/xbox-services/multiplayer/mpm/concepts/flowcharts/live-mpm-play-with-smartmatch-matchmaking.md)
- [使用 SmartMatch 匹配](/zh-CN/services/xbox-services/multiplayer/matchmaking/concepts/live-matchmaking-how-tos.md)
- [匹配](/zh-CN/services/xbox-services/multiplayer/matchmaking/index.md)
- [常见的多人游戏方案](/zh-CN/services/xbox-services/multiplayer/overviews/live-common-multiplayer-scenarios.md)
