# PlayDrop 游戏中的分享、好友和邀请

带图片或短片分享游戏，读取启动数据，选择好友，在 PlayDrop Chat 中发送邀请卡和挑战卡，并推荐其他游戏。

Source: https://www.playdrop.ai/zh-hans/create/learn/social

分享面板、好友列表和聊天都由 PlayDrop 处理；你的游戏只需在合适的时机调用它们。玩家会带来他们的朋友，朋友们会直接进入你的游戏。

## 分享游戏

在点按或点击时调用 `sdk.host.share()`。它会分享游戏的公开页面，可附带文字、一张图片或一段短视频，以及可选的启动数据。

```js
shareButton.addEventListener("click", async () => {
  try {
    await sdk.host.share({ text: `I reached level ${level} in Moon Jump`, image: scoreCardBlob, payload: "level-7" });
  } catch (error) {
    console.warn("Share failed", error);
  }
});
```

- `image`：一个最大 8 MiB 的 GIF、JPEG、PNG 或 WebP Blob。无法附加图片的宿主只会分享链接。
- `video`：一个最长 15 秒、最大 20,000,000 字节的 MP4 Blob，用来代替图片。效果最好的是 1080p、16:9、9:16 或 1:1 的 H.264/AAC 视频。不支持视频的宿主会以 `host_share_video_unsupported` 拒绝，而不是改为分享普通链接。
- 在点按之前准备好 Blob；点按之后再生成，可能会失去浏览器的分享权限。
- 你不能分享自定义 URL 或其他文件。链接始终是游戏的页面。

图片错误有 `invalid_host_share_image`、`host_share_image_type` 和 `host_share_image_too_large`。

## 读取启动数据

`payload` 最多 256 个 base64url 字符。打开分享链接的玩家启动游戏时，`sdk.host.launchPayload` 会被设为它，否则为 `null`。请把它当作不可信的输入：先验证它，并在服务器上检查玩家是否可以加入它指定的房间。绝不能把凭据放进去。

## 选择好友并发送游戏卡片

`sdk.social.selectFriends({ max })` 会打开 PlayDrop 的好友选择器（1 到 10 位，默认 1 位），只返回玩家选择的好友；如果玩家取消，则返回 `[]`。然后发送一张会出现在 PlayDrop Chat 中的卡片：

```js
const [friend] = await sdk.social.selectFriends({ max: 1 });
if (friend) {
  await sdk.social.sendMessage({
    recipientUserId: friend.id,
    type: "challenge",
    title: "Beat my time: 42.3 s",
    subtitle: "Moon Jump, level 7",
    payload: "level-7",
    clientMessageId: `challenge-${runId}-${friend.id}`,
  });
}
```

- `type` 为 `invite`、`request`、`gift`、`challenge` 或 `turn`。
- `title` 最多 80 个字符，`subtitle` 最多 160 个字符。
- `expiresInSeconds` 为 60 秒到 30 天（默认值）。
- `clientMessageId` 让重试变得安全：重复使用它会返回原来的消息。
- 你可以给玩家选择的好友、玩这款游戏的好友，以及玩家已经互发过游戏消息的玩家发消息。不能给在匹配中遇到的陌生人发消息。

用 `getMessages({ limit })` 读取收到的卡片（最早的在前），然后用 `consumeMessage(message.id)` 把每张卡片标记为已处理。发送者是 `message.from.id`。

```js
const page = await sdk.social.getMessages({ limit: 20 });
for (const message of page.messages) {
  await applyCard(message.type, message.from.id, message.payload);
  await sdk.social.consumeMessage(message.id);
}
```

用 `cursor: page.nextCursor` 继续读取，直到它为 `null`。

## 玩这款游戏的好友

`sdk.social.listGameFriends()` 返回最近在这款游戏中有过会话的好友：很适合用来做“一起玩”按钮的列表。它不会公开完整的好友列表或在线状态。`openProfile(userId)` 会打开某位玩家的个人资料，`openChat({ recipientUserId, draftMessage })` 会打开 Chat，并带有一份可编辑的草稿，由玩家自己发送。

从好友那里来的新玩家可能设置了 `sdk.host.launchFriend`。可以提议和这位好友一起玩，并用 `selectFriends({ max: 1 })` 确认；绝不能自动开始任何操作。

## 推荐其他游戏

在自然的休息时机，例如游戏结束时，`sdk.host.showGames({ games: ["@creator/name"] })` 会显示一到三款其他公开游戏的 PlayDrop 卡片，并暂停你的游戏。它会返回 `played`（PlayDrop 随后切换游戏）或 `dismissed`。`sdk.host.preloadGame(ref)` 会提示玩家接下来可能打开的游戏。

## 要求

分享和社交调用需要使用 SDK 的[包](https://www.playdrop.ai/zh-hans/create/learn/packaging)。好友功能需要已登录的玩家。宿主自己的窗口会暂停游戏；请处理好[暂停和恢复](https://www.playdrop.ai/zh-hans/create/learn/lifecycle)。

## 相关指南

- [在线队伍和语音](https://www.playdrop.ai/zh-hans/create/learn/online-party): 让朋友们在线一起玩你的游戏：声明队伍人数，打开 PlayDrop 的队伍窗口，用 sdk.multiplayer.join 加入预留的房间，并控制房间语音。
- [可见性与曝光](https://www.playdrop.ai/zh-hans/create/learn/distribution): 选择谁可以打开 PlayDrop 游戏，了解账号默认设置和版本发布的规则，以及 Boost、互玩、即玩和搜索如何带来新玩家。
- [排行榜](https://www.playdrop.ai/zh-hans/create/learn/leaderboards): 在 catalogue.json 中声明排行榜，用 sdk.leaderboards 提交分数，并显示前几名和玩家附近的排名。包括分数类型、限制和更新规则。
