好友模式
阅读本文前请先完成 SDK 初始化。
好友通知设置
好友模块默认会向游戏推送好友状态及申请的通知,如果游戏需要关闭,可调用如下接口:
- Unity
- Android
- iOS
try {
await TDSFriends.DisableFriendNotification();
TapLog("关闭推送通知成功");
} catch (Exception e) {
TapLog($"关闭推送通知失败: ${e}");
}
TDSFriends.disableFriendNotification(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("消息推送关闭成功");
}
@Override
public void onFail(TDSFriendError error) {
toast("消息推送关闭失败 " + error.detailMessage);
}
});
void (^callback)(BOOL succeeded, NSError * error) = ^(BOOL succeeded, NSError * _Nullable error){
if (succeeded) {
[LogHelper log:LogInfoTypeDisplay :[NSString stringWithFormat:@"设置成功"]];
} else {
[LogHelper log:LogInfoTypeError :[NSString stringWithFormat:@"设置失败"]];
}
};
[TDSFriends disableFriendNotificationWithCallback:callback];
当关闭通知后,如果需要再次开启,可调用如下接口:
- Unity
- Android
- iOS
try {
await TDSFriends.EnableFriendNotification();
TapLog("开启推送通知成功");
} catch (Exception e) {
TapLog($"开启推送通知失败: ${e}");
}
TDSFriends.enableFriendNotification(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("消息推送关闭成功");
}
@Override
public void onFail(TDSFriendError error) {
toast("消息推送关闭失败 " + error.detailMessage);
}
});
void (^callback)(BOOL succeeded, NSError * error) = ^(BOOL succeeded, NSError * _Nullable error){
if (succeeded) {
[LogHelper log:LogInfoTypeDisplay :[NSString stringWithFormat:@"设置成功"]];
} else {
[LogHelper log:LogInfoTypeError :[NSString stringWithFormat:@"设置失败"]];
}
};
[TDSFriends enableFriendNotificationWithCallback:callback];
响应好友变化通知
好友模块支持客户端监听好友状态变化,在游戏中实时给玩家提示。 你需要在调用上线接口前注册好友状态变更监听实例,这样,玩家上线后就能收到相应通知:
- Unity
- Android
- iOS
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) => {},
};
TDSFriends.registerFriendStatusChangedListener(new FriendStatusChangedListener() {
// 新增好友(触发时机同「已发送的好友申请被接受」)
@Override
public void onFriendAdd(TDSFriendInfo friendInfo) {}
// 新增好友申请
@Override
public void onNewRequestComing(TDSFriendshipRequest request) {}
// 通过分享链接进入游戏时触发此回调
// 开发者可以在此回调中直接调用 handFriendInvitationLink
// 或通过 parseFriendInvitationLink 解析链接,获取相关参数再执行自定义的逻辑
@Override
public void onReceivedInvitationLink(String url) {}
// 已发送的好友申请被接受
@Override
public void onRequestAccepted(TDSFriendshipRequest request) {}
// 已发送的好友申请被拒绝
@Override
public void onRequestDeclined(TDSFriendshipRequest request) {}
// 好友上线
@Override
public void onFriendOnline(String userId) {}
// 好友下线
@Override
public void onFriendOffline(String userId) {}
// 好友富信息变更
@Override
public void onRichPresenceChanged(String userId, TDSRichPresence richPresence) {}
// 当前玩家成功上线(长连接建立成功)
@Override
public void onConnected() {}
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
@Override
public void onDisconnected() {}
// 当前连接异常
@Override
public void onConnectError(int code, String msg){});
}
[TDSFriends registerNotificationDelegate:self];
// 新增好友(触发时机同「已发送的好友申请被接受」)
- (void)onFriendAdd:(TDSFriendInfo *)info {}
// 新增好友申请
- (void)onNewRequestComing:(TDSFriendshipRequest *)request {}
// 已发送的好友申请被接受
- (void)onRequestAccepted:(TDSFriendshipRequest *)request {}
// 已发送的好友申请被拒绝
- (void)onRequestDeclined:(TDSFriendshipRequest *)request {}
// 好友上线
- (void)onFriendOnline:(NSString *)userId {}
// 好友下线
- (void)onFriendOffline:(NSString *)userId {}
// 好友富信息变更
- (void)onRichPresenceChanged:(NSString *)userId dictionary:(NSDictionary * _Nullable)dictionary {}
// 当前玩家成功上线(长连接建立成功)
- (void)onConnected {}
// 当前玩家长连接断开,SDK 会自动重试,开发者通常无需额外处理
- (void)onDisconnected {}
// 当前连接异常
- (void)onDisconnectedWithError:(NSError * _Nullable)error {}
上述事件中的「好友」,均指「好友模式」下的「好友」。 目前 SDK 暂不支持监听关注模式下的事件。
如果想要停止监听:
- Unity
- Android
- iOS
TDSFriends.FriendStatusChangedDelegate = null;
TDSFriends.removeFriendStatusChangedListener();
[TDSFriends unregisterNotificationDelegate];
玩家上线
玩家成功登录后,需要调用该接口建立和好友服务云端的长连接。 长连接建立后,如果网络临时中断,SDK 会在网络恢复后自动重连。
- Unity
- Android
- iOS
await TDSFriends.Online();
TDSFriends.online(new Callback<Void>() {
@Override
public void onSuccess(Void result) {
// 成功
}
@Override
public void onFail(TDSFriendError error) {
// 处理异常
}
});
建立长连接后,如果玩家通过好友邀请链接打开游戏,那么 Android SDK 也会自动发送对应的好友申请。
[TDSFriends online];
玩家下线
玩家登出后,需要调用此接口断开和云端的长连接。
- Unity
- Android
- iOS
await TDSFriends.Offline();
TDSFriends.offline();
[TDSFriends offline];
根据昵称查询好友
在不知道玩家 objectId 的情况下,可以通过玩家昵称查询好友。
例如,搜索昵称为 Tarara
的好友:
- Unity
- Android
- iOS
ReadOnlyCollection<TDSFriendInfo> friendInfos = await TDSFriends.SearchUserByName("Tarara");
foreach (TDSFriendInfo info in friendInfos) {
// 玩家信息
TDSUser user = info.User;
// 富信息数据,详见后文
Dictionary<string, string> richPresence = info.RichPresence;
// 好友是否在线
bool online = info.Online;
}
TDSFriends.searchUserByName("Tarara", new ListCallback<TDSFriendInfo>() {
@Override
public void onSuccess(List<TDSFriendInfo> friendInfoList) {
for (TDSFriendInfo info : friendInfoList) {
// 玩家信息
TDSUser user = info.getUser();
// 富信息数据,详见后文
TDSRichPresence richPresence = info.getRichPresence();
// 好友是否在线
boolean online = info.isOnline();
}
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed search friend by nickname" + error.detailMessage);
}
});
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends searchUserWithNickname:@"Tarara" option:option
callback:^(NSArray<TDSFriendInfo *> * _Nullable friendInfos, NSError * _Nullable error) {
if (friendInfos) {
for (TDSFriendInfo *info in friendInfos) {
// 玩家信息
TDSUser *user = info.user;
// 富信息数据,详见后文
NSDictionary *richPresence = info.richPresence;
// 好友是否在线
BOOL online = info.online;
}
} else if (error) {
// 处理错误
}
}];
注意,使用这一功能的前提是内建账户系统中设置了 nickname
(昵称)字段。
参见内建账户系统文档。
好友码
每个已登录玩家都有一个好友码,可以分享给其他玩家用于添加好友。
访问 TDSUser
的 shortId
属性可获取好友码:
- Unity
- Android
- iOS
// currentUser 是已登录的 TDSUser
string shortId = currentUser["shortId"];
String shortId = currentUser.getString("shortId");
NSString *shortId = currentUser[@"shortId"];
可以通过好友码查询玩家:
- Unity
- Android
- iOS
TDSFriendInfo friendInfo = await TDSFriends.SearchUserByShortCode(shortId);
TDSFriends.searchUserByShortCode(shortId, new Callback<TDSFriendInfo>() {
@Override
public void onSuccess(TDSFriendInfo friendInfo) { /* 略(参见上节) */ }
@Override
public void onFail(TDSFriendError error) { /* 略(参见上节) */ }
});
[TDSFriends searchUserWithShortCode:shortId
callback:^(TDSFriendInfo * _Nullable friendInfo, NSError * _Nullable error) {
// 略(参见上节)
}];
根据 objectId 查询好友
除了昵称、好友码外,还可以根据 objectId 查找好友。
查询 objectId 为 5b0b97cf06f4fd0abc0abe35
的好友:
- Unity
- Android
- iOS
TDSFriendInfo friendInfo = await TDSFriends.SearchUserById("5b0b97cf06f4fd0abc0abe35");
TDSFriends.searchUserById("5b0b97cf06f4fd0abc0abe35", new Callback<TDSFriendInfo>() {
@Override
public void onSuccess(TDSFriendInfo tdsFriendInfo) {
/* 略(参见上节) */
}
@Override
public void onFail(TDSFriendError tdsFriendError) {
/* 略(参见上节) */
}
});
[TDSFriends searchUserWithObjectId:@"5b0b97cf06f4fd0abc0abe35"
callback:^(TDSFriendInfo * _Nullable friendInfo, NSError * _Nullable error) {
// 略(参见上节)
}];
富信息
富信息用于呈现玩家状态等信息,如在线状态、正在使用哪个英雄、正处于哪个游戏模式等。
在控制台添加富信息相关配置后,可以根据已配置的富信息字段,设置对应的富信息内容:
- Unity
- Android
- iOS
await TDSFriends.SetRichPresence("score", "60");
TDSFriends.setRichPresence("score", "60", new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("Succeed to set rich presence.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to set rich presence: " + error.detailMessage);
}
});
[TDSFriends setRichPresenceWithKey:@"score" value:@"60"
callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Succeed to set rich presence.
} else if (error) {
// Failed to set rich presence.
}
}];
这里 score
是在控制台配置的富信息字段。
富信息的字段有两种类型:
-
variable
类型,值是字符串。例如,之前的代码实例中,score
在控制台配置为variable
类型,因此客户端设置富信息字段的值时填了60
,云端返回给客户端的富信息为"score": "60"
,在游戏界面该玩家的好友会看到当前玩家的富信息显示为「得分 60」之类。这里,开发者需要自行实现将score
显示为「得分」等本地化内容的逻辑。 -
token
类型,值是以#
开头的字符串。例如,下面的代码实例中display
字段的类型是token
,客户端设置富信息字段的值时填了#matching
,这个值在云端会进行多语言匹配,返回给客户端的富信息会直接替换为本地化的内容:"display": "匹配中"
。注意,如果多语言匹配失败则会返回空字符串("display": " "
)。
需要一次性配置多个字段时,可以传入一组字段:
- Unity
- Android
- iOS
Dictionary<string, string> info = new Dictionary<string, string>();
info.Add("score", "60");
info.Add("display", "#matching");
await TDSFriends.SetRichPresences(info);
Map<String,String> info = new HashMap<>();
info.put("score", "60");
info.put("display", "#matching");
TDSFriends.setRichPresence(info, new Callback<Void>() {
// 略
});
[TDSFriends setRichPresencesWithDictionary:@{
@"score" : @"60",
@"display" : @"#matching",
} callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
控制台最多配置 20 个富信息字段,字段名(key)长度不超过 128 bytes,字段值(value)长度不超过 256 bytes。
如需清除当前玩家的某项富信息,可以调用以下接口:
- Unity
- Android
- iOS
TDSFriends.ClearRichPresence("score");
TDSFriends.clearRichPresence("score", new Callback<Void>() {
// 略
});
[TDSFriends clearRichPresenceWithKey:@"score"
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
}];
同样,可以批量清除一组富信息:
- Unity
- Android
- iOS
IEnumerable<string> keys = new string[] {"score", "display"}
await TDSFriends.ClearRichPresences(keys);
List<String> keys = new ArrayList<>();
keys.add("score");
keys.add("display");
TDSFriends.clearRichPresence(keys, new Callback<Void>() {
// 略
});
[TDSFriends clearRichPresencesWithKeys:@[@"score", @"display"]
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略
});
设置和清除富信息接口有调用频率限制,每 30s 最多各触发一次。
富信息提供了 REST API 接口。 开发者可以自行编写程序或脚本调用这些接口在服务端进行管理性质的操作。
添加好友
可以通过指定好友码添加相应玩家为好友。
- Unity
- Android
- iOS
await TDSFriends.AddFriendByShortCode(shortId);
TDSFriends.addFriendByShortCode(shortId, null, new Callback<Void>() {
@Override
public void onSuccess(Void result) {
toast("Applied or added.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to add a friend: " + error.detailMessage);
}
});
[TDSFriends addFriendWithShortCode:shortId callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Applied or added.
} else if (error) {
// Failed to add a friend.
}
}];
如果当前玩家已经在对方的好友列表中,那么对方会直接成为当前玩家的好友。 否则,会向对方发送好友申请。
添加好友时可以指定额外的属性,例如,将对方放入 coworkers
(同事)分组:
- Unity
- Android
- iOS
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriendByShortCode(shortId, attrs);
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("group", "coworkers");
TDSFriends.addFriendByShortCode(shortId, attrs, new Callback<Boolean>() {
// 略(参见上面的例子)
});
NSDictionary *attributes = @{
@"group" : @"coworkers",
};
[TDSFriends addFriendWithShortCode:shortId attributes:attributes
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
此外,也可以通过指定某个 TDSUser
的 objectId
来添加他为好友。
比如,假设 Tarara 的 objectId
是 5b0b97cf06f4fd0abc0abe35
,可以通过以下代码添加她为好友:
- Unity
- Android
- iOS
await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.addFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>() {
// 略(参见上面的例子)
});
[TDSFriends addFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35"
callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
通过 objectId
添加好友同样可以指定额外属性:
- Unity
- Android
- iOS
Dictionary<string, object> attrs = new Dictionary<string, object> {
{ "group", "coworkers" }
};
await TDSFriends.AddFriend("5b0b97cf06f4fd0abc0abe35", attrs);
Map<String, Object> attrs = new HashMap<String, Object>();
attrs.put("group", "coworkers");
TDSFriends.addFriend("5b0b97cf06f4fd0abc0abe35", attrs, new Callback<Void>() {
// 略(参见上面的例子)
});
NSDictionary *attributes = @{
@"group" : @"coworkers",
};
[TDSFriends addFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" attributes:attributes callback:^(BOOL succeeded, NSError * _Nullable error) {
// 略(参见上面的例子)
}];
删除好友
成为好友的两个玩家,之后也可以单方面删除好友。 例如,和 Tarara 成为好友后,当前玩家又改变主意,不想和 Tarara 做朋友了:
- Unity
- Android
- iOS
await TDSFriends.DeleteFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.deleteFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Boolean>() {
@Override
public void onSuccess(Boolean ok) {
toast("Deleted.");
}
@Override
public void onFail(TDSFriendError error) {
toast("Failed to delete a friend: " + error.detailMessage);
}
});
[TDSFriends deleteFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// Deleted.
} else if (error) {
// Failed to delete a friend.
}
}];
拉黑
添加黑名单用户
将用户加入黑名单,无论双方是否是好友,都可以进行该操作。拉黑后,双方之间进行中的好友申请都会被删除,且双方无法再发起以及接受对方的好友申请。查询好友列表时也无法查到已在黑名单中的好友,黑名单用户最多 100 人。
假设 Tarara 的 objectId 是 5b0b97cf06f4fd0abc0abe35
,可以这样将 Tarara 加到黑名单:
- Unity
- Android
- iOS
await TDSFriends.BlockFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.blockFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>(){
@Override
public void onSuccess(Void result) {
// block user succeed.
}
@Override
public void onFail(TDSFriendError error) {
// Failed to block.
}
});
[TDSFriends blockFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// block user succeed.
} else if (error) {
// Failed to block.
}
}];
移除黑名单用户
从黑名单移除用户,如果目标用户曾经是当前用户的好友,则恢复进入当前用户好友列表。
- Unity
- Android
- iOS
await TDSFriends.UnblockFriend("5b0b97cf06f4fd0abc0abe35");
TDSFriends.unblockFriend("5b0b97cf06f4fd0abc0abe35", new Callback<Void>() {
@Override
public void onSuccess(Void result) {
// unblock succeed.
}
@Override
public void onFail(TDSFriendError error) {
// Failed to unblock.
}
});
[TDSFriends unblockFriendWithUserId:@"5b0b97cf06f4fd0abc0abe35" callback:^(BOOL succeeded, NSError * _Nullable error) {
if (succeeded) {
// unblock succeed.
} else if (error) {
// Failed to unblock.
}
}];
查询黑名单列表
分页查询黑名单用户列表。
- Unity
- Android
- iOS
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
为每页获取数据的数量。
TDSFriends.queryBlockList(0, 10, new ListCallback<TDSFriendInfo>() {
@Override
public void onSuccess(List<TDSFriendInfo> result) {
System.out.println("query blockList data, data = " + result);
}
@Override
public void onFail(TDSFriendError error) {
System.out.println("query blockList failed, error = " + error);
}
});
其中:
from
为获取列表的起始位置,第一页为 0,下一页为上一次获取数据的总数量。limit
为每页获取数据的数量。callback
为异步处理回调,包含黑名单用户列表的数据信息。
TDSFriendQueryOption *option = [TDSFriendQueryOption new];
option.from = 0;
option.limit = 100;
[TDSFriends queryBlockListWithOption:option
callback:^(NSArray<TDSFriendInfo *> * _Nullable friendInfos, NSError * _Nullable error) {
if (friendInfos) {
for (TDSFriendInfo *info in friendInfos) {
// 玩 家信息
TDSUser *user = info.user;
// 富信息数据
NSDictionary *richPresence = info.richPresence;
// 好友是否在线
BOOL online = info.online;
}
} else if (error) {
// 处理错误
}
}];