跳到主要内容
版本:v3

关注模式

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

响应好友变化通知

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

TDSFollows.FriendStatusChangedDelegate = new TDSFriendStatusChangedDelegate {
// 当前玩家成功上线(长连接建立成功)
OnConnected = () => {},
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
OnDisconnected = () => {},
// 当前连接异常
OnConnectionError = (code, message) => {},
};

如果想要停止监听:

TDSFollows.FriendStatusChangedDelegate = null;

玩家上线

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

await TDSFollows.Online();

玩家下线

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

await TDSFollows.Offline();

根据昵称查询好友

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

ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFollows.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 TDSFollows.SearchUserByShortCode(shortId);

根据 objectId 查询好友

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

查询 objectId 为 5b0b97cf06f4fd0abc0abe35 的好友:

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

富信息

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

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

await TDSFollows.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 TDSFollows.SetRichPresences(info);

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

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

TDSFollows.ClearRichPresence("score");

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

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

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

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

关注

可以通过指定好友码关注相应玩家:

await TDSFollows.FollowByShortCode(shortId);

关注玩家时可以指定额外的属性,例如,将对方放入 coworkers(同事)分组:

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

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

await TDSFollows.Follow("5b0b97cf06f4fd0abc0abe35");

通过 objectId 关注玩家同样可以指定额外属性:

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

注意,一个玩家 最多关注 5000 个玩家。

取关

可以通过指定 objectId 或好友码来取消关注之前关注的玩家。 例如,之前关注了 Tarara,当前玩家后来改变主意,不想关注 Tarara 了:

await TDSFollows.UnFollow("5b0b97cf06f4fd0abc0abe35");

await TDSFollows.UnFollowByShortCode(shortIdOfTarara);

拉黑

玩家可以拉黑其他玩家,使其他玩家无法关注自己。 拉黑时会解除彼此之间的关注关系。 和关注、取关类似,可以通过 objectId 或好友码来指定想要拉黑的玩家。 例如,假设 Tarara 的 objectId 是 5b0b97cf06f4fd0abc0abe35,可以这样拉黑 Tarara:

await TDSFollows.Block("5b0b97cf06f4fd0abc0abe35");

await TDSFollows.BlockByShortCode(shortIdOfTarara);

玩家也可以取消拉黑之前拉黑的玩家:

await TDSFollows.Unblock("5b0b97cf06f4fd0abc0abe35");

await TDSFollows.UnblockByShortCode(shortIdOfTarara);

如果玩家之前存在关注关系,取消拉黑后不会自动恢复关注

玩家可以查询自己拉黑了哪些人:

FriendResult result = await TDSFollows.QueryBlockList(cursor, limit, sortCondition);

注意:

  • 黑名单上限 100 人。也就是说,一个玩家最多拉黑 100 个玩家。
  • 玩家甲拉黑玩家乙后,不仅玩家乙无法关注玩家甲,玩家甲也无法关注玩家乙。如果玩家甲之前已经关注了玩家乙,或玩家乙之前已经关注了玩家甲,在玩家甲拉黑玩家乙时都会取消关注。

查询互关列表

玩家可以查询哪些玩家和自己是「互相关注」关系。 该接口除了会返回好友列表外,还会返回游标。 指定游标和返回数量,可以实现翻页功能。 同时,支持根据在线状态获取排序后的结果(当前在线的玩家在前):

// 首次查询
string cursor = null;
// 默认 50,最大 500
int limit = 50;
// 根据在线状态排序
SortCondition sortCondition = SortCondition.OnlineCondition
FriendResult result = await TDSFollows.QueryMutualList(cursor, limit, sortCondition);

ReadOnlyCollection<TDSFriendInfo> friendInfos = result.FriendList;
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据
Dictionary<string, string> richPresence = info.RichPresence;
// 玩家是否在线
bool online = info.Online;
}

// 翻页
string cursor = result.Cursor;
FriendResult more = await TDSFollows.QueryMutualList(cursor, limit, sortCondition);

注意,可以根据在线状态排序的前提是游戏正确地接入了好友服务,包括在玩家登录后调用上线接口,玩家登出后调用下线接口。 否则,由于游戏未正确上报玩家的在线状态,好友服务无从得知玩家的在线状态,查询结果自然也无法支持根据在线状态排序。

查询关注列表

类似地,玩家可以查询自己关注了哪些玩家,接口与查询互关列表类似,也同样支持根据在线状态排序:

FriendResult result = await TDSFollows.QueryFolloweeList(cursor, limit, sortCondition);

查询粉丝列表

玩家还可以查询哪些玩家关注了自己,也就是自己的粉丝,接口与查询互关、关注列表类似,但不支持根据在线状态排序

FriendResult result = await TDSFollows.QueryFollowerList(cursor, limit, sortCondition);

如果查询时指定了根据在线状态排序,云端会忽略这一条件,仍然返回未排序的查询结果。

分享链接

落地页

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

我们提供了开源的落地页示例项目,修改相应配置后可直接构建、部署、使用。 注意,示例项目中的 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

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

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

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

生成链接

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

string inviteUrl = await TDSFollows.GenerateFriendInvitationLink();

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

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

处理链接

玩家通过邀请链接打开游戏后,需要调用 SDK 提供的接口关注邀请者。

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

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

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

注意:

落地页示例项目默认使用好友模式,需要设置环境变量 INVITE_TYPEfollow 切换为关注模式。