# 围绕已被屏蔽用户的配对

**URL:** https://heroiclabs.com/docs/zh/nakama/guides/concepts/matchmaking-blocked-users/
**Summary:** 关于实施Nakama的配对程序以避免用户匹配到其已屏蔽用户的指南。

---


# 围绕已被屏蔽用户的配对

Nakama的[配对程序](../../../concepts/multiplayer/matchmaker/)可以将用户聚集在一起，进行应用程序中可用的任何类型的社交游戏或交互。与任何社区一样，有些用户会相处融洽，有些则不会。

当一位用户[屏蔽](../../../concepts/friends/#block-a-friend)了另一位用户，理想情况下，配对程序不应将这两位用户置于同一个比赛、群组或其他此类社交功能中。

本指南介绍了一种方法，您可以使用该方法避免用户匹配其已经屏蔽的其他用户。这包括：

* 查找每个用户已屏蔽用户的列表
* 在各自[配对程序属性](../../../concepts/multiplayer/matchmaker/#properties)中使用该列表
* 在配对程序[查询](../../../concepts/multiplayer/matchmaker/#query)中添加子句，避免匹配到已被屏蔽的用户

## 列出被屏蔽用户

使用[列出好友API](../../../server-framework/typescript-runtime/function-reference/#friendsList)，仅筛选处于被屏蔽状态的用户，获得该玩家已屏蔽的所有用户的完整列表。

{{< code type="client" >}}
```csharp
var blockedState = 3;
var blockedFriendsResult = await client.ListFriendsAsync(session, blockedState, 100, null);
```
{{< / code >}}

{{< code type="client" >}}
```javascript
const blockedState = 3;
const blockedFriendsResult = await client.listFriends(session, null, blockedState);
```
{{< / code >}}

{{< code type="client" >}}
```cpp
int blockedState = 3;
auto successCallback = [](NFriendsPtr blockedFriendsResult)
{
  // Blocked friends available as blockedFriendsResult->friends
};

client->listFriends(session, {}, blockedState, {}, successCallback);
```
{{< / code >}}

{{< code type="client" framework="godot3" >}}
```gdscript
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = yield(client.list_friends_async(session, blocked_state), "completed")
```
{{< / code >}}

{{< missing type="client" lang="java" />}}
{{< missing type="client" lang="lua" framework="defold" />}}
{{< missing type="client" lang="shell" />}}
{{< missing type="client" lang="bash" />}}

您需要将被屏蔽的用户ID的完整列表写入一个用空格分隔的字符串（例如`user-id-1 user-id-2 user-id-3`），该字符串将成为用户的配对程序属性的一部分。

{{< code type="client" >}}
```csharp
var blockedFriendIds = string.Join(" ", blockedFriendsResult.Friends.Select(x => x.User.Id));
```
{{< / code >}}

{{< code type="client" >}}
```javascript
const blockedFriendIds = blockedFriendsResult.friends.map(friend => friend.userId).join(' ');
```
{{< / code >}}

{{< code type="client" >}}
```cpp
auto successCallback = [](NFriendListPtr blockedFriendsResult)
{
  string blockedFriendIds = "";
  for (NFriend friend : blockedFriendsResult->friends) {
    blockedFriendIdsString += friend.user.id + " ";
  }
};
```
{{< / code >}}

{{< code type="client" framework="godot3" >}}
```gdscript
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "
```
{{< / code >}}

{{< missing type="client" lang="java" />}}
{{< missing type="client" lang="lua" framework="defold" />}}
{{< missing type="client" lang="shell" />}}
{{< missing type="client" lang="bash" />}}

## 配对程序条件

每位用户的配对程序标准现在将包括一个附加的属性，该属性使用上面创建的被屏蔽用户连接字符串的键`blocked` 。

{{< code type="client" >}}
```csharp
var stringProperties = new Dictionary<string, string>
{
    { "blocked", blockedFriendIds }
}; 
```
{{< / code >}}

{{< code type="client" >}}
```javascript
const stringProperties = {
  "blocked": blockedFriendIds
};
```
{{< / code >}}

{{< code type="client" >}}
```cpp
NStringMap stringProperties;
stringProperties.emplace("blocked", blockedFriendIds);
```
{{< / code >}}

{{< code type="client" framework="godot3" >}}
```gdscript
var string_properties = { "blocked", blocked_friend_ids }
```
{{< / code >}}

{{< missing type="client" lang="java" />}}
{{< missing type="client" lang="lua" framework="defold" />}}
{{< missing type="client" lang="shell" />}}
{{< missing type="client" lang="bash" />}}

除了新属性之外，每个用户的配对程序查询还将在`-properties.blocked:/.my\-user\-id./`表单中包含一个新的[`must not`](../../../concepts/multiplayer/query-syntax/#must-not)子句。

通过使用玩家自己的ID，此子句确保搜索的玩家不会出现在任何潜在匹配的屏蔽列表中 - 即该玩家不会与任何已屏蔽他们的玩家匹配，并且最终任何玩家都不会匹配到他们已屏蔽的任何人。

完整的配对程序请求如下所示：

{{< code type="client" >}}
```csharp
var blockedState = 3;
var blockedFriendsResult = await client.ListFriendsAsync(session, blockedState, 100, null);
var blockedFriendIds = string.Join(" ", blockedFriendsResult.Friends.Select(x => x.User.Id));]

var stringProperties = new Dictionary<string, string>
{
    { "blocked", blockedFriendIds }
};

var ticket =
    await socket.AddMatchmakerAsync($"-properties.blocked:/.{session.UserId}./", 2, 4, stringProperties, null);
```
{{< /code >}}

{{< code type="client" >}}
```javascript
const blockedState = 3;
const blockedFriendsResult = await client.listFriends(session, null, blockedState);
const blockedFriendIds = blockedFriendsResult.friends.map(friend => friend.userId).join(' ');

const stringProperties = {
  "blocked": blockedFriendIds
};

const ticket = await socket.addMatchmaker(`-properties.blocked:/.${session.userId}./`, 2, 4, stringProperties, null);
```
{{< / code >}}

{{< code type="client" >}}
```cpp
int blockedState = 3;
auto successCallback = [](NFriendsPtr blockedFriendsResult)
{
  string blockedFriendIds = "";
  for (NFriend friend : blockedFriendsResult->friends) {
    blockedFriendIdsString += friend.user.id + " ";
  }

  NStringMap stringProperties;
  NStringDoubleMap numericProperties;
  stringProperties.emplace("blocked", blockedFriendIds);

  string query = "-properties.blocked:/." + blockedFriendIds + "./";
  rtClient->addMatchmaker(2, 4, query, stringProperties, numericProperties, matchmakerSuccessCallback);
};

client->listFriends(session, {}, blockedState, {}, successCallback);
```
{{< / code >}}


{{< code type="client" framework="godot3" >}}
```gdscript
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = yield(client.list_friends_async(session, blocked_state), "completed")
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "

var string_properties = { "blocked", blocked_friend_ids }

var query = "-properties.blocked:/.%s./" % [blocked_friend_ids]
var ticket : NakamaRTAPI.MatchmakerTicket = yield(socket.add_matchmaker_async(query, 2, 4, string_properties, null), "completed")
```
{{< / code >}}

{{< missing type="client" lang="java" />}}
{{< missing type="client" lang="lua" framework="defold" />}}
{{< missing type="client" lang="shell" />}}
{{< missing type="client" lang="bash" />}}