
# 运营SDK排行榜接入文档

## 一、功能描述

本模块功能自运营 SDK `3.13.0` 开始提供

排行榜是用户在游戏内参与活动后产生挑战时间/分数成绩的排行  
游戏使用排行榜系统提供的 API，获取所有榜单数据、榜单排名区间数据、取角色排名数据，  
更新角色排行分数，获取当前用户头像地址、昵称等接口。


## 二、接入准备
在正式接入排行榜系统前，接入方需要确认以下流程已完善：
- 已经在 4399 平台注册好游戏，并完善了平台所要求的配置
- 已经按照一般流程引入了 4399 运营SDK，具体流程参考 [SDK 客户端接入文档](./online_java_guide.html)
- 已经设计好游戏榜单系统，并在 SDK 后台添加配置
- 游戏方根据接入方式，选择下面某一项
    - 客户端接入：已经获取接口公钥（与云存档、排行榜等其他服务同一个参数，获取一次即可）
    - 服务端接入：已经获取接口key，服务端接入方式可以参考[游戏服务-排行榜接入文档](./game_chart_guide_server.html)

### 如何获取接口公钥/key
向 SDK 开发人员提交游戏 **Game Key，和 APK 签名的 sha256摘要**，SDK 对接人员会协助填写，  
并将最后得到的公钥给游戏开发，**游戏应妥善保管此类参数**

如何获取公钥参考：[获取 Android 应用签名证书指纹](./check_developer_ca_sha256.html)

### 如何定义榜单
为定义一个榜单，游戏应提供以下信息给 SDK 对接人员：

内容	|定义	|说明
:---    |:---   |:---
排行榜名称	|榜单名称	|后台需要上传，仅作为排行ID对应的名称记录
排行榜标识	|排行榜唯一标识	|通过标识返回对应排行榜的数据（仅限数字+英文，最多100个字符）
排行榜周期	|榜单更新周期	|凌晨0点更新，仅限 日榜,周榜,月榜,季榜,年榜,无限制
排行顺序	|排行榜排序顺序	|支持 正序 或 倒序
排行策略	|排行上报数据的更新策略	|支持 累计（上报数据直接累加）、最新（只记录最新数据）、最好（只记录最好数据）

为方便接入方提交信息，可以按照 [4399 SDK 排行榜配置模板](http://sdkftp.4399doc.com/internal/operate/3.13/%E6%8E%92%E8%A1%8C%E6%A6%9C%E9%85%8D%E7%BD%AE.xls) 填写排行榜配置

## 三、接口调用

### 0、前置接口

在调用本服务相关接口前，游戏应先调用下面前置接口：
- [初始化](./online_java_guide.html)
- [登录](./online_java_guide.html)
### 1、服务初始化

`GameChart.init`，初始化公钥，在使用排行榜其他接口前，应调用此接口进行初始化

```java
/**
 * 服务初始化
 *
 * @param publicKey 接口公钥，完成游戏服务配置得到
 */
public static void init(String publicKey)
```

调用示例：
```java
//参数：publicKey，开发者后台的游戏公钥，可联系相应的运营获取
GameChart.init(publicKey);
```

### 2、获取游戏榜单数据

`GameChart.getGameChart`，获取所有榜单数据

```java
/**
 * 获取所有榜单数据
 *
 * @param listener 回调对象
 */
public static void getGameChart(OpeDataListener<List<ChartDescriptor>> listener); 
```

调用示例：
``` java
GameChart.getGameChart(new OpeDataListener<List<ChartDescriptor>>() {
    @Override
    public void onFinished(int code, String message, List<ChartDescriptor> data) {
    }
});
```

接口调用后通过接口`OpeDataListener<List<ChartDescriptor>>`返回游戏榜单列表  
`OpeDataListener`，通用泛型回调接口，接入方调用方法后通过接口方法接收并处理调用结果  
`ChartDescriptor`，排行榜描述数据模型，里面包含了游戏所定义的榜单列表信息  
*两个类的具体信息在本文档后文的 API 详情部分，接口示例中涉及的其他类也是如此*


### 3、获取榜单排名区间数据

`GameChart.getChartByRange`，获取榜单排名区间数据，区间用起始、结束值确定
```java
/**
 * 获取榜单排名区间数据
 *
 * @param rankId   榜单id，必须
 * @param serverId 区服id，未分服传0
 * @param start    榜单排名区间起始index，包括此位置值对应的项
 * @param end      榜单排名区间结束index，包括此位置值对应的项
 * @param listener 回调对象
 */
public static void getChartByRange(String rankId, int serverId,
                                   int start, int end,
                                   OpeDataListener<List<ChartItem>> listener)
```

调用示例：
```java
GameChart.getChartByRange(String rankId, int serverId, int start, int end,
    new OpeDataListener<List<ChartItem>>() {
        @Override
        public void onFinished(int code, String message, List<ChartItem> data) {
    }
});
```

### 4、获取角色附近排名数据

`GameChart.getChartAroundRole`，获取角色附近排名数据，角色附近的范围，通过指定本角色之前多少位、之后多少位确定

```java
/**
 * 获取角色排名数据
 *
 * @param rankId   榜单id，必须
 * @param serverId 区服id，未分服传0
 * @param roleId   游戏角色id, 游戏不分角色传字符串0
 * @param before   当前角色前几名，包括此位置值对应的项
 * @param after    当前角色后几名，包括此位置值对应的项
 * @param listener 回调对象
 */
public static void getChartAroundRole(String rankId, int serverId, String roleId,
                                      int before, int after,
                                      OpeDataListener<List<ChartItem>> listener);
```

调用示例：
```java
GameChart.getChartAroundRole(String rankId, int serverId, String roleId,
    int before,int after, new OpeDataListener<List<ChartItem>>() {
        @Override
        public void onFinished(int code, String message, List<ChartItem> data) {
        }
});
```

### 5、更新角色排行数据

`GameChart.updateByRole`，更新角色排行数据

```java
/**
 * 更新角色排行分数
 *
 * @param rankId    排行榜id
 * @param serverId  区服id，未分服传0
 * @param roleId    游戏角色id，游戏不分角色传字符串0
 * @param roleAvatar 头像地址，无头像或不需要时，可传null
 * @param roleName  角色名/昵称，无角色名/昵称或不需要时，可传null
 * @param score     排名数值
 * @param listener  回调对象
 */
public static void updateByRole(String rankId, int serverId, String roleId,
                                String roleAvatar, String roleName, float score,
                                OpeDataListener<Boolean> listener) 
```

调用示例：
```java
GameChart.updateByRole(String rankId, int serverId, String roleId, String avatar,
    String roleName,float score, new OpeDataListener<Boolean>() {
        @Override
        public void onFinished(int code, String message, Boolean data) {
        //data为true代表更新角色分数成功,反之为更新失败
        }
});
```

### 6、获取当前用户在平台的信息

`GameChart.getPtUser`，获取当前已登录用户在平台的信息，这些信息是对登录后的用户信息的补充


```java
/**
 * 获取当前用户头像地址、昵称
 */
public static PtUser getPtUser()
```

**何时使用接口**：如果游戏在排行榜中展示角色头像、昵称等信息，但是游戏本身没有相关信息，  
则可以获取用户平台信息，并通过`GameChart.updateByRole`更新到排行数据中

调用示例：
```java
PtUser ptUser = GameChart.getPtUser();
```

## API 详情

### OpeDataListener

```java

/**
 * 数据监听器
 */
public interface OpeDataListener<T> {
    /**
     * @param code    0为请求成功，并返回数据, 其他code均为失败，失败时数据可能为空
     * @param message 说明文案
     * @param data    返回数据
     */
    void onFinished(int code, @Nullable String message, @Nullable T data);
}
```

#### code 列表

| code | 含义 |
| ----------- | ---------- |
| 0 | 成功 |
| 1 | 取消 |
| 2 | 处理中，可能是延迟 |
| 3 | 失败，可从message中了解更多信息 |
| 4 | 接口返回超时 |
| 5 | 数据加密解密错误 |

### ChartDescriptor
```java
/**
 * 排行榜描述信息，游戏可能有多个排行榜
 */
public class ChartDescriptor {
    /** 排行榜ID */
    public final String rankId;
    /** 排行榜名称 */
    public final String rankName;
    /** 游戏key */
    public final String gameKey;
    /** 排行周期 */
    public final String interval;
    /** 排行策略 */
    public final String strategy;
    /** 排行顺序 */
    public final String order;
    /** 当前版本 */
    public final String version;
    /** 是否维护，1为维护中 */
    public final String maintain;
    /** 排行榜过期时间 */
    public final String expiredAt;
    /** 排行榜激活时间 */
    public final String activatedAt;
}
```

### ChartItem
```java
/**
 * 一个排行榜中某一项的信息
 */
public class ChartItem {
    /** 排名 */
    public final String rank;
    /** 角色头像地址 */
    public final String roleAvatar;
    /** 角色ID */
    public final String roleId;
    /** 角色名 */
    public final String roleName;
    /** 成绩 */
    public final float score;
}
```

### PtUser

```java
/**
 * 平台用户信息，作为登录信息的补充
 */
public class PtUser {

  /** 平台用户 id */
  public final String ptUid;

  /** 头像地址 */
  public final String sFace;

  /** 昵称 */
  public final String nick;
}
```
