[!WARNING|labelVisibility:hidden|iconVisibility:hidden] 游戏服务目前仅支持游戏存档、排行榜和邮件功能,需要玩家登录游戏后才能正常使用。
1. 准备
游戏服务通过SDK服务器和Google Play Games Services两种方式保存游戏数据,如果选择使用Google Play Games Services,需要在 Google Play 管理中心(Grow > Play Games Services > Setup and management > Configuration)启用Saved Games功能并保存。
需要使用游戏服务提供的相关功能时,可以通过以下代码获取游戏服务:
SFGameService gameService = SFPlatform.getInstance().getGameService(activity);
2. 存档
存档功能提供了一种方便的方法来保存玩家退出游戏后仍需保留的游戏数据。可以保存游戏数据来记录玩家的进度,为使用同一设备的家庭成员保留单独的数据以及支持玩家在不同设备之间切换。
2.1 存档安全
为了保证玩家存档数据的安全,防止存档信息被盗用,请开发者务必在游戏中实现对存档进行加密和解密操作。
- 存档加密建议强加密,必须使用安全的对称加密算法,建议用
AES 256 CBC PKCS#7。 - 密钥不要直接保存在代码里面,也不要放在存档里面,最好可以每次加密当场现算。
- 可以使用唯一设备标识符或用户ID等信息参与密钥和IV的生成,这样不仅可以防止存档被篡改,也可以防止存档被转移。
具体实现方案可以参考防止用户作弊方案
2.2 写入存档
在游戏中需要写入存档时,可以调用该方法。代码示例如下:
gameService.writeSnapshot(fileName, data, metadata, server, new SFRequestResultListener<SFGameSnapshot>() {
@Override
public void onSuccess(SFGameSnapshot data) {
// 存档保存成功
}
@Override
public void onFailed(int code, String message) {
// 存档保存失败
}
});
参数说明:
fileName:存档名称(唯一标识)data:存档内容metadata:存档元数据(未设置的字段将保留其当前值)server:服务器存档标识(server传true时metadata可以为null)
2.3 读取存档
在游戏中需要读取存档时,可以调用该方法。代码示例如下:
gameService.readSnapshots(fileName, server, new SFRequestResultListener<SFGameSnapshot>() {
@Override
public void onSuccess(SFGameSnapshot data) {
// 存档读取成功
}
@Override
public void onFailed(int code, String message) {
// 存档读取失败
}
});
参数说明:
fileName:存档名称(唯一标识)server:服务器存档标识
2.4 删除存档
在游戏中需要删除存档时,可以调用该方法。代码示例如下:
gameService.deleteSnapshot(fileName, server, new SFRequestResultListener<String>() {
@Override
public void onSuccess(String data) {
// 存档删除成功
}
@Override
public void onFailed(int code, String message) {
// 存档删除失败
}
});
参数说明:
fileName:存档名称(唯一标识)server:服务器存档标识
2.5 数据格式
SFGameSnapshot 表示游戏存档数据,数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| playerName | String | 否 | 玩家名称 |
| uniqueName | String | 否 | 存档名称(唯一标识) |
| deviceName | String | 否 | 存档设备名称 |
| description | String | 是 | 存档描述信息 |
| lastModifiedTimestamp | long | 否 | 存档最后修改时间 |
| snapshotData | byte[] | 否 | 存档内容 |
SFSnapshotMetadata 表示Google Play游戏服务存档元数据,数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| description | String | 是 | 存档描述 |
| coverImage | Bitmap | 是 | 存档封面图像 |
| progressValue | long | 否 | 玩家游戏进度 |
| playedTimeMillis | long | 否 | 玩家游戏时间(毫秒) |
3. 排行榜
排行榜功能通过SDK服务器保存游戏排行榜数据,暂不支持通过Google Play游戏服务保存排行榜数据。
3.1 玩家排名信息
在游戏中需要查询当前玩家排名信息时,可以调用该方法。代码示例如下:
gameService.getLeaderboard(leaderboardId, new SFRequestResultListener<SFLeaderboard>() {
@Override
public void onSuccess(SFLeaderboard data) {
// 查询当前玩家排名信息成功
}
@Override
public void onFailed(int code, String message) {
// 查询当前玩家排名信息失败
}
});
参数说明:
leaderboardId:排行榜唯一标识
3.2 游戏排行榜信息
在游戏中需要查询游戏排行榜信息时,可以调用该方法。代码示例如下:
gameService.getLeaderboards(leaderboardId, maxResults, timestamp, new SFRequestResultListener<List<SFLeaderboard>>() {
@Override
public void onSuccess(List<SFLeaderboard> leaderboards) {
// 查询游戏排行榜信息成功
}
@Override
public void onFailed(int code, String message) {
// 查询游戏排行榜信息失败
}
});
在游戏中需要查询游戏排行榜信息时,并且对排行榜进行了分组,可以调用该方法并传入排行榜分组标识。代码示例如下:
gameService.getLeaderboards(leaderboardId, groupId, maxResults, timestamp, new SFRequestResultListener<List<SFLeaderboard>>() {
@Override
public void onSuccess(List<SFLeaderboard> leaderboards) {
// 查询游戏排行榜信息成功
}
@Override
public void onFailed(int code, String message) {
// 查询游戏排行榜信息失败
}
});
参数说明:
leaderboardId:排行榜唯一标识groupId:排行榜分组标识,提交玩家成绩信息时会返回分组标识maxResults:排行榜最大数量timestamp:时间戳,用于游戏控制排行榜刷新,比如System.currentTimeMillis() / 1000 / 180表示3分钟刷新一次
3.3 提交玩家成绩信息
在游戏中需要提交当前玩家成绩信息时,可以调用该方法。该方法返回最新的玩家排名信息,代码示例如下:
SFLeaderboard leaderboard = new SFLeaderboard.Builder()
.setPlayerId(playerId)
.setPlayerName(playerName)
.setPictureUrl(pictureUrl)
.setLeaderboardId(leaderboardId)
.setScore(score)
.build();
gameService.submitPlayerScore(leaderboard, new SFRequestResultListener<SFLeaderboard>() {
@Override
public void onSuccess(SFLeaderboard data) {
// 更新玩家成绩成功
}
@Override
public void onFailed(int code, String message) {
// 更新玩家成绩失败
}
});
在游戏中需要提交当前玩家成绩信息,并且需要对排行榜进行分组时,可以调用该方法并传入想要分组的玩家数量。该方法返回最新的玩家排名信息,代码示例如下:
SFLeaderboard leaderboard = new SFLeaderboard.Builder()
.setPlayerId(playerId)
.setPlayerName(playerName)
.setPictureUrl(pictureUrl)
.setLeaderboardId(leaderboardId)
.setScore(score)
.build();
gameService.submitPlayerScore(leaderboard, groupCount, new SFRequestResultListener<SFLeaderboard>() {
@Override
public void onSuccess(SFLeaderboard data) {
// 更新玩家成绩成功
}
@Override
public void onFailed(int code, String message) {
// 更新玩家成绩失败
}
});
参数说明:
leaderboard:包含玩家信息的对象groupCount:每组包含的玩家数量,需要传入大于0的数值
3.4 数据格式
SFLeaderboard 表示游戏排行榜数据,数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| playeId | String | 否 | 玩家ID |
| playerName | String | 是 | 玩家名称 |
| pictureUrl | String | 是 | 玩家头像地址 |
| groupId | String | 是 | 排行榜分组ID |
| leaderboardId | String | 否 | 排行榜ID(唯一标识) |
| score | long | 否 | 玩家成绩 |
| rank | long | 否 | 玩家排名 |
4. 邮件
邮件功能提供了一种为个人玩家和全服玩家发放奖励的方式。
4.1 查询邮件
在游戏中需要查询当前玩家的个人和全服邮件方时,可以调用该方法。该方法返回有效期内的所有全服和个人邮件,游戏需自行处理玩家领取奖励的相关逻辑,比如使用游戏存档记录玩家是否已领取奖励。代码示例如下:
gameService.getPlayerMails(new SFRequestResultListener<List<SFMailData>>() {
@Override
public void onSuccess(List<SFMailData> data) {
// 查询玩家邮件成功
}
@Override
public void onFailed(int code, String message) {
// 查询玩家邮件失败
}
});
4.2 数据格式
SFMailData 表示邮件数据,数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| type | int | 否 | 邮件类型(0-全服邮件;1-个人邮件) |
| mailId | String | 否 | 邮件编号 |
| title | String | 否 | 邮件标题 |
| content | String | 否 | 邮件正文(富文本) |
| gifts | List<SFMailGift> | 是 | 邮件奖励 |
SFMailGift 表示邮件奖励数据,数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| giftId | String | 否 | 奖励ID |
| giftNum | int | 否 | 奖励数量 |