1.简介
1.1.适用范围
TapDB提供一套SDK,游戏开发者可以将其集成到游戏中,系统会收集玩家数据,并进行分析,最终形成数据报表,帮助游戏开发者分析玩家行为并优化游戏。
适用于Unity开发的游戏,Android支持2.2及以上的系统,iOS支持5.0及以上的系统。
1.2.名词解释
名词 | 含义 |
---|---|
玩家 | 对应一个玩家账户,需要一个唯一的标识符。玩家是统计系统的数据统计基本单位 |
设备 | 安装了对应游戏的设备 |
付费 | 玩家使用真实货币换取游戏虚拟币或游戏道具 |
分包渠道 | 标识游戏安装包渠道来源,需要在代码中设置 |
2.接入方式
2.1.申请应用
在TapDB控制台中注册一个游戏,获得游戏对应的APP ID,这是一个16位的字符串,iOS和Android可共用一个APP ID。
2.2.向工程中导入SDK
在TapDB网站上下载最新的SDK,其中包含一个 TapDB.unitypackage 文件,在 Unity3D 编译器中选择 Assets --> Import Package --> Custom Package 找到 TapDB.unitypackage 文件,点击"打开按钮"即可导入成功。其中demo.cs仅是示例代码,不是SDK所需的代码。
2.3.添加Android支持库
添加Android v4支持库到项目中,Android v4支持库的版本必须不低于23.0.0,否则可能导致闪退。
如果使用gradle依赖安装版本高于24.2.0版本的v4支持库,可以仅安装support-compat模块,参见文档: https://developer.android.com/topic/libraries/support-library/setup.html 、 https://developer.android.com/topic/libraries/support-library/features.html 。
如果不方便使用gradle进行自动化依赖安装,之前也没有使用到v4支持库,可以使用此处提供的support-compat模块的jar文件, https://static.tapdb.net/web/res/file/upload/2017/0926/android-support-v4.jar 。
2.4.Android添加需要的权限
需要为工程中的AndroidManifest.xml添加下列权限。当AndroidManifest.xml中配置的targetSdkVersion大于等于23,同时在初始化函数中设置requestPermission为true,并且运行在Android 6以上的设备时,TapDB SDK会主动提示用户进行可选权限授权。
权限 | 是否必须 | 用途 |
---|---|---|
android.permission.INTERNET | 必选 | 使用网络的权限 |
android.permission.ACCESS_NETWORK_STATE | 必选 | 获取手机网络连接状态 |
android.permission.READ_PHONE_STATE | 可选 | 获取用户的设备编号用于广告渠道追踪,若不具备此权限,无法进行广点通等广告渠道的追踪 |
android.permission.WRITE_EXTERNAL_STORAGE | 可选 | 使用SD卡辅助存储设备标识等信息,若不具备此权限,有一部分设备无法进行很好的设备跟踪 |
2.5.iOS引入依赖的框架
需要为iOS导出的Xcode工程引入下列依赖的框架或库
框架或库 | 用途 |
---|---|
CoreTelephony.framework | 用来获取运营商标识 |
AdSupport.framework | 用来获取设备广告标识,跟踪设备 |
Security.framework | 用来进行更好的持久化存储 |
2.6.调用统计接口
在需要调用统计接口的代码中引入类TapDB,并按照后面的接口介绍调用统计接口。
3.接口说明
TapDB类中定义了TGTUserType/TGTUserSex两个枚举类型。TapDB包含的都是静态方法,直接用类名调用即可。TGTUserType表示玩家类型,TGTUserSex表示玩家性别。
3.1.初始化
初始化统计系统SDK,调用这个接口是使用其它接口的先决条件,需要尽早调用。一般建议在Unity里的Start()里面调用。
public static void onStart(string appId, string channel, string gameVersion, bool requestPermission)
字段 | 可为空 | 说明 |
---|---|---|
appId | 否 | 注册游戏时获得的APP ID |
channel | 是 | 分包渠道,1.2.名词解释中有介绍 |
gameVersion | 是 | 游戏版本,为空时,自动获取游戏安装包的版本(Android是AndroidManifest.xml中的versionName,iOS是Xcode配置中的Version) |
requestPermission | 否 | 在Android上是否由TapDB SDK来申请上述可选权限。当AndroidManifest.xml中配置的targetSdkVersion大于等于23,同时该参数为true,并且运行在Android 6以上的设备时,TapDB SDK会主动申请APP申明的上述可选权限。 |
3.2.Android处理用户授权回调
为主activity实现android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback接口,实现其中的onRequestPermissionsResult方法,并且直接在方法中调用TapDB的onRequestPermissionsResult方法并传递收到的参数即可,若IDE报错,可以使用@SuppressLint("Override")忽略报错。
如果已经实现了该方法,在方法的最后加入调用代码即可。
主activity一般是继承com.unity3d.player.UnityPlayerActivity的子类,并且需要在AndroidManifest.xml中指定为主activity。
当AndroidManifest.xml中定义的targetSdkVersion大于等于23,且初始化函数中设置requestPermission为true时,必须做此处理。建议无论什么场景都加上,防止以后更改时遗忘。
// 注意一定要为当前类实现android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback接口,而不是单纯加一个方法
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
try {
Class<?> clazz = Class.forName("com.xindong.tyrantdb.TyrantdbGameTracker");
Method method = clazz.getMethod("onRequestPermissionsResult", int.class, String[].class, int[].class);
method.invoke(null, requestCode, permissions, grantResults);
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
}
由于代码中用到了反射调用,混淆代码时,请不要对com.xindong.tyrantdb.TyrantdbGameTracker进行混淆
3.3.跟踪游戏的启停
跟踪玩家游戏次数和游戏时长。可参照SDK demo中的方式进行调用。
public static void onResume()
public static void onStop()
3.4.记录一个玩家
记录一个玩家(注意是平台用户,不是游戏角色!!!),当玩家登陆时调用,如果是试玩用户,userId由游戏自己生成,但需要保证唯一性。
public static void setUser(string userId, TGTUserType userType, TGTUserSex userSex, int userAge, string userName)
字段 | 可为空 | 说明 |
---|---|---|
userId | 否 | 玩家ID(注意是平台用户ID,不是游戏角色ID!!!),不同玩家要是唯一的,不同用户平台可能存在相同的用户ID,需要想办法做区分 |
userType | 否 | 玩家类型,见类型详细定义 |
userSex | 否 | 玩家性别,见类型详细定义 |
userAge | 否 | 玩家年龄,无法获知玩家年龄直接传递0 |
userName | 是 | 玩家名称 |
3.5.玩家等级
设置玩家等级,玩家登陆时或升级时调用。
public static void setLevel(int level)
字段 | 可为空 | 说明 |
---|---|---|
level | 否 | 玩家等级 |
3.6.玩家区服
设置玩家区服,玩家登陆时或更换区服时调用。
public static void setServer(string server)
字段 | 可为空 | 说明 |
---|---|---|
server | 否 | 玩家服务器 |
3.7.发起充值请求
(推荐使用服务端充值统计接口)
当玩家发起充值请求时调用。
提醒:由于客户端行为,不可避免会有投机者尝试破解充值; 如果没有通过服务器校验,一定会造成数据不准确,强烈建议使用服务器接口进行充值数据回调。 (4.1.充值统计接口)
public static void onChargeRequest(string orderId, string product, Int32 amount, string currencyType, Int32 virtualCurrencyAmount, string payment)
字段 | 可为空 | 说明 |
---|---|---|
orderId | 否 | 订单ID |
product | 是 | 产品名称 |
amount | 否 | 充值金额(单位分,即无论什么币种,都需要乘以100) |
currencyType | 是 | 货币类型,参考:人民币 CNY,美元 USD;欧元 EUR |
virtualCurrencyAmount | 否 | 充值获得的虚拟币 |
payment | 是 | 支付方式,如:支付宝 |
3.8.充值成功
充值成功时调用,需要与充值请求成对调用
public static void onChargeSuccess(string orderId)
字段 | 可为空 | 说明 |
---|---|---|
orderId | 否 | 订单ID,与之前调用的充值请求传递的ID对应 |
3.9.充值失败
充值失败时调用,需要与充值请求成对调用
public static void onChargeFail(string orderId, string reason)
字段 | 可为空 | 说明 |
---|---|---|
orderId | 否 | 订单ID,与之前调用的充值请求传递的ID对应 |
reason | 是 | 失败原因 |
3.10.仅充值成功
当客户端无法跟踪充值请求发起,只能跟踪到充值成功的事件时,调用该接口记录充值信息
public static void onChargeOnlySuccess(string orderId, string product, Int32 amount, string currencyType, Int32 virtualCurrencyAmount, string payment)
字段 | 可为空 | 说明 |
---|---|---|
orderId | 是 | 订单ID |
product | 是 | 产品名称 |
amount | 否 | 充值金额(单位分,即无论什么币种,都需要乘以100) |
currencyType | 是 | 货币类型,参考:人民币 CNY,美元 USD;欧元 EUR |
virtualCurrencyAmount | 否 | 充值获得的虚拟币 |
payment | 是 | 支付方式,如:支付宝 |
4.服务端统计接口
4.1.充值统计接口
由于客户端接入充值统计可能会不太准确,这里提供服务端充值统计方法,需要忽略掉SDK中的相关充值统计接口
接口:https://e.tapdb.net/event
内容(注意后面还需要处理一下):
{
"module": "GameAnalysis", //固定
"ip": "8.8.8.8", //充值用户的IP,可选
"name": "charge", //固定
"index": "APPID", //APPID注意替换成TapDB的appid
"identify": "user_id", //user_id,必须和客户端的setUser接口传递的user_id一样,并且该用户已经通过SDK接口进行过统计
"properties": {
"order_id": "100000", //order_id,可选
"amount": 100, //充值金额(单位分,即无论什么币种,都需要乘以100),必传
"virtual_currency_amount": 100, //获赠虚拟币数量,必传,可为0
"currency_type": "CNY", //货币类型,可选,不传或者不是正确的货币类型,统一处理成人民币分
"product": "item1", //充值包名称,可选
"payment": "alipay" //充值途径,可选
}
}
假如游戏的appid为abcd1234,构建出json字符串后,需要去掉空格和换行符,然后再进行一次urlencode,再把结果作为post数据发过来
先替换换行符和空格,变成:
{"module":"GameAnalysis","name":"charge","index":"abcd1234","identify":"user_id","properties":{"order_id":"100000","amount":100,"virtual_currency_amount":100,"currency_type":"CNY","product":"item1","payment":"alipay"}}
然后urlencode,变成如下形式,某些版本的urlencode可能会把':'和','进行编码,不影响实际使用。
%7B%22module%22:%22GameAnalysis%22,%22name%22:%22charge%22,%22index%22:%22abcd1234%22,%22identify%22:%22user_id%22,%22properties%22:%7B%22order_id%22:%22100000%22,%22amount%22:100,%22virtual_currency_amount%22:100,%22currency_type%22:%22CNY%22,%22product%22:%22item1%22,%22payment%22:%22alipay%22%7D%7D
货币类型的格式参考汇率表
成功判断:返回的HTTP Code为200认为发送成功,否则认为失败
4.2.在线数据统计接口
由于SDK无法进行准确的在线数据统计,这里提供服务端在线数据统计接口。游戏服务端可以每隔5分钟自行统计在线人数,通过接口发送到TapDB,TapDB进行数据汇总和展现。
接口:https://se.tapdb.net/tapdb/online
方法:POST
格式:json
必须头信息:Content-Type: application/json
请求内容:
参数名 | 参数类型 | 参数说明 |
---|---|---|
appid | string | TapDB的appid |
onlines | array | 多条在线数据(最多100条) |
其中onlines数组的结构为
参数名 | 参数类型 | 参数说明 |
---|---|---|
server | string | 服务器,TapDB对同一服务器每一个自然5分钟仅接受一次数据 |
online | int | 在线人数 |
timestamp | long | 当前统计数据的时间戳(秒),TapDB会按照自然5分钟进行数据对齐 |
示例:
{
"appid":"gkjasd13bbsa1sdk",
"onlines":[{
"server":"s1",
"online":123,
"timestamp":1489739590
},{
"server":"s2",
"online":188,
"timestamp":1489739560
}]
}
成功判断:返回的HTTP Code为200认为发送成功,否则认为失败