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

# 查找大厅

> 使用基于可搜索属性、成员数量和基于距离的排序对公共 PlayFab 大厅进行过滤和排序,实现大厅发现。

对于游戏来说,让玩家找到满足特定条件(例如地图、难度等游戏内属性)的大厅通常非常有用。此搜索功能使玩家能够找到他们想要的、与他们想要的人一起参与的游戏会话。

本文介绍如何使用 **FindLobbies** 使玩家能够查找大厅。若要了解在游戏中如何使用查找大厅,请参阅[常见场景](#common-scenarios)。

<Note>
  不建议使用 **FindLobbies** 来实现后台匹配。在这种情况下,我们强烈建议使用[匹配功能](/services/playfab/multiplayer/matchmaking)。否则,你必须通过过滤、排序和其他技术(例如在搜索数据字段中使用随机化值)来处理所有玩家试图加入同一大厅时的冲突。
</Note>

## 了解大厅搜索属性与查找大厅之间的关系

玩家通过定义搜索属性使他们的大厅可被发现。玩家通过调用 **FindLobbies** 并使用查询字符串来根据当前活跃大厅上定义的搜索属性对其搜索结果进行过滤和排序,从而找到这些可被发现的大厅。与这些查询匹配的大厅会返回给调用玩家。

有关定义搜索属性的更多信息,请查看[创建可搜索的大厅](/services/playfab/multiplayer/lobby/define-search-keywords)

## 如何使用 FindLobbies

调用 **FindLobbies** 时,你可以使用 filter 参数将查询限制为仅返回与基于大厅自定义搜索属性的某些条件相匹配的搜索结果。

此外,你可以使用排序参数根据搜索属性对从服务返回的结果进行排序。这很有用,因为服务只会返回有限数量的搜索结果。排序可确保你看到最相关的搜索结果。

### 常见场景

以下是游戏中使用 **FindLobbies** 功能的几种常见方式。

* 查找你游戏中特定游戏模式的游戏会话大厅
* 查找由你的好友主持的游戏会话大厅
* 查找玩家足够多以容纳所有本地玩家的游戏会话大厅
* 查找你已经加入的大厅,以便在游戏客户端或游戏服务器意外崩溃后恢复连接。

### 支持的搜索键

在定义自定义搜索属性时,只允许使用一组受限的键。

* 对于字符串属性,支持以下键:string\_key1、string\_key2、\[...] string\_key30
* 对于数值属性,支持以下键:number\_key1、number\_key2、\[...] number\_key30

### 构造 FindLobbies 的查询字符串

**FindLobbies** API 的查询字符串采用类似 OData 的语法。过滤字符串的最大长度为 600 个字符。

可以使用这些 OData 运算符来组合查询字符串。运算符区分大小写。

| 运算符 | 含义    | 示例                                                      |
| --- | ----- | ------------------------------------------------------- |
| eq  | 等于    | string\_key1 eq 'CaptureTheFlag'                        |
| lt  | 小于    | number\_key2 lt 10                                      |
| le  | 小于或等于 | number\_key2 le 10                                      |
| gt  | 大于    | number\_key3 gt 100                                     |
| ge  | 大于或等于 | number\_key3 ge 100                                     |
| ne  | 不等于   | string\_key1 ne 'CaptureTheFlag'                        |
| and | 与     | string\_key1 eq 'CaptureTheFlag' and number\_key2 lt 10 |

<Note>
  比较字符串属性时,请务必将被比较的值用单引号包裹。例如,“string\_key1 eq **'SOME STRING VALUE'**”。数值属性无需包裹。
</Note>

也有可用的预定义运算符。在指定时,它们必须以 “lobby/” 作为前缀。

| 运算符                  | 含义                                 | 示例                                 |
| -------------------- | ---------------------------------- | ---------------------------------- |
| memberCount          | 大厅中玩家的数量                           | lobby/memberCount eq 5             |
| maxMemberCount       | 大厅允许的最大玩家数                         | lobby/maxMemberCount gt 10         |
| memberCountRemaining | 还可以加入大厅的玩家剩余数量                     | lobby/memberCountRemaining gt 0    |
| membershipLock       | 大厅的锁定状态,必须等于 'Unlocked' 或 'Locked' | lobby/membershipLock eq 'Unlocked' |
| amOwner              | 你是其所有者的大厅,必须等于 'true'              | lobby/amOwner eq 'true'            |
| amMember             | 你是其成员的大厅,必须等于 'true'               | lobby/amMember eq 'true'           |
| amServer             | 服务器已加入的客户端所拥有的大厅,必须等于 'true'       | lobby/amServer eq 'true'           |

有关这些常量的 SDK 定义,请参阅[此处](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/constants/pflobbysearchkeys)的文档。

### 排序

一个 OData 风格的字符串,包含此查询的排序方式,可为升序 (“asc”) 或降序 (“desc”)。OrderBy 子句可用于任何搜索数字键或数字类型的预定义搜索键。若要按最接近某个数字的方式排序,可以使用距离标记以按给定数字搜索键的距离排序。你不能对距离排序使用升序或降序。此字段仅支持一个排序子句或一个距离子句。如果未提供排序或给定排序需要判定并列,则默认排序为按创建时间降序。

| 示例                          | 含义          |
| --------------------------- | ----------- |
| number\_key1 asc            | 按数字搜索键升序排序  |
| lobby/memberCount desc      | 按数字搜索键降序排序  |
| distance\{number\_key1 = 5} | 按与给定数字的距离排序 |
| *default*                   | 按创建时间降序排序   |

## 使用 Lobby 和 Matchmaking SDK 查找大厅的示例

在此示例中,玩家想要查找满足以下要求的所有大厅:

* 游戏模式为 “DeathMatch”
* 竞技风格为 “Ranked”
* 玩家的技能等级位于大厅的最低和最高技能限制内。

此外,玩家希望以下面的准则对结果进行排序:

* 最优技能等级最接近玩家技能等级的大厅应排在前面

```cpp theme={null}
static PFMultiplayerHandle g_pfmHandle = nullptr;

#define SUPPORT_XBL_CROSSPLAY

#define PFLOBBY_SEARCH_KEY_GAME_MODE "string_key1"
#define PFLOBBY_SEARCH_KEY_COMPETITION_STYLE "string_key2"
#define PFLOBBY_SEARCH_KEY_SKILL "number_key1"

#define GAME_MODE_DEATH_MATCH "DeathMatch"
#define COMPETITION_STYLE_RANKED "Ranked"

// Find lobbies based on player's search criteria.
void FindGamesWithRuntimeQuery(
    uint32_t minimumSkill,
    uint32_t maximumSkill,
    uint32_t optimalSkill)
{
    PFLobbySearchFriendsFilter friendsFilter;
    friendsFilter.includeSteamFriends = true;
#ifdef SUPPORT_XBL_CROSSPLAY
    friendsFilter.includeXboxFriendsToken = MyGame::GetLocalUserXboxToken();
#endif // SUPPORT_XBL_CROSSPLAY

    // Limit results based on friend's filter.
    PFLobbySearchConfiguration searchConfiguration = { 0 };
    searchConfiguration.friendsFilter = &friendsFilter;

    // Create filter string based on player's search parameters.
    std::string filterString;
    filterString += PFLOBBY_SEARCH_KEY_GAME_MODE + std::string(" eq ") + "'" + GAME_MODE_DEATH_MATCH + "'";
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_COMPETITION_STYLE + std::string(" eq ") + "'" + COMPETITION_STYLE_RANKED + "'";
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_SKILL + std::string(" ge ") + std::to_string(minimumSkill);
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_SKILL + std::string(" le ") + std::to_string(maximumSkill);

    // Create sort string based on player's sort preference.
    std::string sortString;
    sortString += std::string("distance{") + PFLOBBY_SEARCH_KEY_SKILL + "=" + std::to_string(optimalSkill) + "}";

    searchConfiguration.filterString = filterString.c_str();
    searchConfiguration.sortString = sortString.c_str();

    HRESULT hr = PFMultiplayerFindLobbies(g_pfmHandle, &m_localUser, &searchConfiguration, nullptr);
}

void ProcessStateChanges()
{
    while (true)
    {
        uint32_t stateChangeCount;
        const PFLobbyStateChange* const* stateChanges;
        RETURN_VOID_IF_FAILED(PFMultiplayerStartProcessingLobbyStateChanges(
            g_pfmHandle,
            &stateChangeCount,
            &stateChanges));

        for (uint32_t i = 0; i < stateChangeCount; ++i)
        {
            const PFLobbyStateChange* stateChange = stateChanges[i];
            switch (stateChange->stateChangeType)
            {
                case PFLobbyStateChangeType::FindLobbiesCompleted:
                {
                    GuiPostCurrentLobbySearchResults(
                        static_cast<const PFLobbyFindLobbiesCompletedStateChange&>(*stateChange));
                    break;
                }
                default:
                {
                    break;
                }
            }
        }

        RETURN_VOID_IF_FAILED(PFMultiplayerFinishProcessingLobbyStateChanges(
            g_pfmHandle,
            stateChangeCount,
            stateChanges));
    }
}

// Update game UI to display search results when a list of matching lobbies is returned.
void GuiPostCurrentLobbySearchResults(
    const PFLobbyFindLobbiesCompletedStateChange& stateChange)
{
    if (FAILED(stateChange.result))
    {
        GuiToastErrorAndExitScreen();
        return;
    }

    for (uint32_t i = 0; i < stateChange.searchResultCount; ++i)
    {
        const PFLobbySearchResult& searchResult = stateChange.searchResults[i];
        GuiPostLobbySearchResultRow(searchResult); // defined elsewhere
    }
}
```

## 另请参阅

* [创建可搜索的大厅](/services/playfab/multiplayer/lobby/define-search-keywords)
* [加入大厅](/services/playfab/multiplayer/lobby/join-lobbies)
* [大厅与匹配](/services/playfab/multiplayer/lobby/lobby-and-matchmaking)
* [大厅属性](/services/playfab/multiplayer/lobby/lobby-properties)
* [创建大厅](/services/playfab/multiplayer/lobby/create-a-lobby)


## Related topics

- [使用多人 SDK 将 Party 与 Lobby 集成](/zh-CN/services/playfab/multiplayer/networking/party-lobby-integration.md)
- [Multiplayer Unity 插件快速入门](/zh-CN/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-plugin-quickstart.md)
- [从 MPSD 迁移到 PlayFab Multiplayer 和 MPA](/zh-CN/services/xbox-services/multiplayer/mpsd/concepts/live-mpsd-to-mlp.md)
- [大厅邀请](/zh-CN/services/playfab/multiplayer/lobby/lobby-invites.md)
- [加入大厅](/zh-CN/services/playfab/multiplayer/lobby/join-lobbies.md)
