跳到主要内容
版本:v3

好友模式

阅读本文前请先完成 SDK 初始化

响应好友变化通知

好友模块支持客户端监听好友状态变化,在游戏中实时给玩家提示。 你需要在调用上线接口前注册好友状态变更监听实例,这样,玩家上线后就能收到相应通知:

TDSFriends.FriendStatusChangedDelegate = new TDSFriendStatusChangedDelegate {
// 新增好友(触发时机同「已发送的好友申请被接受」)
OnFriendAdd = friendInfo => {},
// 新增好友申请
OnNewRequestComing = req => {},
// 已发送的好友申请被接受
OnRequestAccepted = req => {},
// 已发送的好友申请被拒绝
OnRequestDeclined = req => {},
// 好友上线
OnFriendOnline = userId => {},
// 好友下线
OnFriendOffline = userId => {},
// 好友富信息变更
OnRichPresenceChanged = (userId, richPresence) => {},
// 当前玩家成功上线(长连接建立成功)
OnConnected = () => {},
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
OnDisconnected = () => {},
// 当前连接异常
OnConnectionError = (code, message) => {},
};

上述事件中的「好友」,均指「好友模式」下的「好友」。 目前 SDK 暂不支持监听关注模式下的事件。

如果想要停止监听:

TDSFriends.FriendStatusChangedDelegate = null;

玩家上线

玩家成功登录后,需要调用该接口建立和好友服务云端的长连接。 长连接建立后,如果网络临时中断,SDK 会在网络恢复后自动重连。

await TDSFriends.Online();

玩家下线

玩家登出后,需要调用此接口断开和云端的长连接。

await TDSFriends.Offline();

根据昵称查询好友

在不知道玩家 objectId 的情况下,可以通过玩家昵称查询好友。 例如,搜索昵称为 Tarara 的好友:

ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.SearchUserByName("Tarara");
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据,详见后文
Dictionary<string, string> richPresence = RichPresence;
// 好友是否在线
bool online = info.Online;
}

注意,使用这一功能的前提是内建账户系统中设置了 nickname(昵称)字段。 参见内建账户系统文档

好友码

每个已登录玩家都有一个好友码,可以分享给其他玩家用于添加好友。

访问 TDSUsershortId 属性可获取好友码:

// currentUser 是已登录的 TDSUser
string shortId = currentUser["shortId"];

可以通过好友码查询玩家:

TDSFriendInfo friendInfo = await TDSFriends.SearchUserByShortCode(shortId);

根据 objectId 查询好友

除了昵称、好友码外,还可以根据 objectId 查找好友。

查询 objectId 为 5b0b97cf06f4fd0abc0abe35 的好友:

TDSFriendInfo friendInfo = await TDSFriends.SearchUserById("5b0b97cf06f4fd0abc0abe35");

富信息

富信息用于呈现玩家状态等信息,如在线状态、正在使用哪个英雄、正处于哪个游戏模式等。

在控制台添加富信息相关配置后,可以根据已配置的富信息字段,设置对应的富信息内容:

await TDSFriends.SetRichPresence("score", "60");

这里 score 是在控制台配置的富信息字段。 富信息的字段有两种类型:

  • variable 类型,值是字符串。例如,之前的代码实例中,score 在控制台配置为 variable 类型,因此客户端设置富信息字段的值时填了 60,云端返回给客户端的富信息为 "score": "60",在游戏界面该玩家的好友会看到当前玩家的富信息显示为「得分 60」之类。这里,开发者需要自行实现将 score 显示为「得分」等本地化内容的逻辑。

  • token 类型,值是以 # 开头的字符串。例如,下面的代码实例中 display 字段的类型是 token,客户端设置富信息字段的值时填了 #matching,这个值在云端会进行多语言匹配,返回给客户端的富信息会直接替换为本地化的内容:"display": "匹配中"。注意,如果多语言匹配失败则会返回空字符串("display": " ")。

需要一次性配置多个字段时,可以传入一组字段:

Dictionary<string, string> info = new Dictionary<string, string>();
info.Add("score", "60");
info.Add("display", "#matching");
await TDSFriends.SetRichPresences(info);

控制台最多配置 20 个富信息字段,字段名(key)长度不超过 128 bytes,字段值(value)长度不超过 256 bytes。

如需清除当前玩家的某项富信息,可以调用以下接口:

TDSFriends.ClearRichPresence("score");

同样,可以批量清除一组富信息:

IEnumerable<string> keys = new string[] {"score", "display"}
await TDSFriends.ClearRichPresences(keys);

设置和清除富信息接口有调用频率限制,每 30s 最多各触发一次。

富信息提供了 REST API 接口。 开发者可以自行编写程序或脚本调用这些接口在服务端进行管理性质的操作。

添加好友

可以通过指定好友码添加相应玩家为好友。

await TDSFriends.AddFriendByShortCode(shortId);

如果当前玩家已经在对方的好友列表中,那么对方会直接成为当前玩家的好友。 否则,会向对方发送好友申请。

添加好友时可以指定额外的属性,例如,将对方放入 coworkers(同事)分组:

Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriendByShortCode(shortId, attrs);

此外,也可以通过指定某个 TDSUserobjectId 来添加他为好友。 比如,假设 Tarara 的 objectId5b0b97cf06f4fd0abc0abe35,可以通过以下代码添加她为好友:

await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35");

通过 objectId 添加好友同样可以指定额外属性:

Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35", attrs);

删除好友

成为好友的两个玩家,之后也可以单方面删除好友。 例如,和 Tarara 成为好友后,当前玩家又改变主意,不想和 Tarara 做朋友了:

await TDSFriends.DeleteFriend("5b0b97cf06f4fd0abc0abe35");

拉黑

添加黑名单用户

将用户加入黑名单,无论双方是否是好友,都可以进行该操作。拉黑后,双方之间进行中的好友申请都会被删除,且双方无法再发起以及接受对方的好友申请。查询好友列表时也无法查到已在黑名单中的好友,黑名单用户最多 100 人。

假设 Tarara 的 objectId 是 5b0b97cf06f4fd0abc0abe35,可以这样将 Tarara 加到黑名单:

await TDSFriends.BlockFriend("5b0b97cf06f4fd0abc0abe35");

移除黑名单用户

从黑名单移除用户,如果目标用户曾经是当前用户的好友,则恢复进入当前用户好友列表。

await TDSFriends.UnblockFriend("5b0b97cf06f4fd0abc0abe35");

查询黑名单列表

分页查询黑名单用户列表。

var from = 0;
var limit = 100;
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.QueryBlockList(from, limit);
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}

其中:

  • from 为获取列表的起始位置,第一页为 0,下一页为上一次获取数据的总数量。
  • limit 为每页获取数据的数量。

查询好友申请列表

好友申请有三种状态:

  • pending,对方没有回应,还处于等待中。好友申请创建之后默认是此状态。
  • accepted,对方已经接受,现在双方成为好友。
  • declined,对方已经拒绝。

SDK 提供了查询好友申请的接口。 例如,查询处于 pending 状态的前 20 条申请:

var from = 0;
var limit = 100;
ReadOnlyCollection<LCFriendshipRequest> requests = await TDSFriends.QueryFriendRequestList (
LCFriendshipRequest.STATUS_PENDING, from, limit
);

LCFriendshipRequest.STATUS_PENDING 即表示好友申请状态为 pending。 类似地,LCFriendshipRequest.STATUS_ACCEPTEDLCFriendshipRequest.STATUS_DECLINED 分别表示好友申请状态为 accepteddeclinedLCFriendshipRequest.STATUS_ANY 则表示任意状态。

如果希望返回结果中携带好友申请发起人的富信息,那么可以使用以下接口:

ReadOnlyCollection<TDSFriendshipRequest> requests = await TDSFriends.QueryFriendRequestWithFriendStateList (
LCFriendshipRequest.STATUS_PENDING, from, limit
);
foreach (TDSFriendshipRequest request in requests) {
// 好友申请(参见 QueryFriendRequestList)
LCFriendshipRequest req = request.FriendshipRequest;
// 申请发起人的富信息
TDSFriendInfo info = request.FriendInfo;
}

处理好友申请

对于新的好友请求,玩家可以同意或者拒绝,也可以什么都不做,无视这些请求,甚至直接删除。

// LCFriendshipRequest request

// 接受
await TDSFriends.AcceptFriendshipRequest(request);
// 接受并添加额外属性
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AcceptFriendshipRequest(request, attrs);

// 拒绝
await TDSFriends.DeclineFriendshipRequest(request);
// 删除
await request.Delete();

注意:

  1. 对方拒绝了当前玩家发起的好友申请之后,玩家通过之前接口的添加好友接口再次发送申请时会收到报错,表明对方不想和当前玩家成为好友。
  2. 对方删除了当前玩家发起的好友请求后,当前玩家还可以再次发起申请。

查询好友列表

玩家可以查询自己的好友列表。查询时可以限定返回结果数量及起始位置:

var from = 0;
var limit = 100;
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.QueryFriendList(from, limit);
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}

查询是否好友

可以通过指定某个 TDSUserobjectId 来查询他是否是当前玩家的好友。 比如,假设 Tarara 的 objectId5b0b97cf06f4fd0abc0abe35

bool isFriend = await TDSFriends.CheckFriendship("5b0b97cf06f4fd0abc0abe35");

分享链接

落地页

使用分享链接功能需要首先部署落地页网站。 落地页网站可以部署在云引擎或其他支持部署纯静态网站的服务器上。 如果计划部署在云引擎上,需注意云引擎的免费实例会自动休眠,请购买标准实例使用。

我们提供了开源的落地页示例项目,修改相应配置后可直接构建、部署、使用。 注意,示例项目中的 GAME_ANDROID_LINK 环境变量格式为 scheme://host/pathhostpath 的值需和 Android 的 AndroidManifest.xml 中的值保持一致。

例如,假设 AndroidManifest.xml 中的相关配置如下:

<activity
android:name="com.tapsdk.friends.TDSFriendsRouterPageActivity"
android:allowTaskReparenting="true"
android:configChanges="keyboardHidden|orientation"
android:exported="true"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="游戏应用ID"
android:path="/friends"
android:scheme="tapsdk" />
<!-- scheme不能出现大写或者下划线,<a href="[scheme]://[host]/[path]?[query]">启动应用程序</a> -->
</intent-filter>
</activity>

那么落地页项目中 GAME_ANDROID_LINK 的值为 tapsdk://游戏应用ID/friends

落地页网站的地址需要在客户端配置:

TDSFriends.SetShareLink("https://please-replace-with-your-domain.example.com");

如果落地页部署在云引擎网站上,那么地址就是 https://你的云引擎自定义域名

生成链接

部署完落地页网站并在客户端配置好相应地址后,调用以下接口即可生成好友邀请页网址:

string inviteUrl = await TDSFriends.GenerateFriendInvitationLink();

分享链接中传递的用户名称默认为玩家昵称(nickname), 因此,默认情况下,使用分享链接的前提是内建账户系统中设置了 nickname(昵称)字段。 参见内建账户系统文档。 如果希望使用其他名称,可以在调用上述接口时另行指定。 另外,还可以传入其他信息,这些信息会作为 URL 查询参数拼接在好友邀请页网址后面。 例如,昵称为 Tarara 的玩家,邀请好友时希望使用「她姥姥」这个名称,邀请链接希望附加 ref=taptap 这个参数,可以这样调用:

Dictionary<string, object> parameters = new Dictionary<string, object> {
{ "ref", "taptap" }
};
string inviteUrl = await TDSFriends.GenerateFriendInvitationLink("她姥姥", parameters);

处理链接

玩家通过邀请链接打开游戏后,开发者需要调用该接口。 调用该接口后,SDK 会自动向对应的玩家发起好友申请。

public class DeepLinkManager : MonoBehaviour
{
// 略
private async void onDeepLinkActivated(string url) {
await TDSFriends.HandleFriendInvitationLink(url);
}
}

开发者也可以通过 SDK 提供的接口解析链接,获取玩家的 objectId、名称、传入的其他参数,定制相应的逻辑。

public class DeepLinkManager : MonoBehaviour
{
// 略
private async void onDeepLinkActivated(string url) {
TDSFriendLinkInfo invitation = TDSFriends.ParseFriendInvitationLink(url);
string userObjectId = invitation.Identity;
string name = invitation.RoleName;
Dictionary<string, string> parameters = invitation.Queries;
await TDSFriends.Follow(userObjectId);
}
}