NovaSDK 开发文档

最近接触到公司游戏聚合的项目, 突然想结合之前公司开发经验来考虑自己应该怎么从而完善设计, 从而方便其他人借鉴处理

首先这里介绍下具体的字段参考表, 需要明确规则: 传递字段必须有默认值, 不允许为 null 值

类型 默认值 取值范围 说明
string ‘’ - 字符串类型, 默认只允许为空字符串, 一般从数据库性能考虑建议字符串控制在 varchar(255) 之中
boolean 0 / 1 - 布尔类型, 一般来说建议采用数值1和0来区分(数据库采用 tinyint(1) 类型), 主要部分数据清洗或者转化成字符串, 也就是 true"true" 的问题
number 0 int64 数值类型, 数值方面建议安装 int64 范围取值(数据库采用 bigint 类型), 部分开发语言最大值需要特定 BigInt 类型
time 0 int64 时间戳类型, 推荐采用 bigint 类型保存 UTC 时间的毫秒时间戳, 因为基于0时区开始的时间戳方便直接做全球化跨时区换算, 所有开发语言都内置支持
country ‘CN’ - 字符串类型, 全球化的来源地区码(数据库采用 char(2) 类型, 入库必须强制转大写), 基于 ISO 3166-1 的地区统一标准码, 海外部分支付渠道需要支付的地区来源标识
currency ‘CNY’ - 字符串类型, 全球化的地区货币码(数据库采用 char(3) 类型, 入库必须强制转大写), 基于 ISO 4217 的地区货币标准码, 海外部分支付渠道需要支付的地区货币标识
scale 2 uint8 数值类型, 全球币种小数位(数据库采用 unsigned tinyint 类型), 大部分国家采用以 为货币单位, 而部分海外国家是没有 单位(日本/韩国最小单位为 日元/韩元), 可以通过计算换算最小货币金额

日常规范差不多是这样, 实际上可以日常动态调整部分需求

  • 有的业务系统喜欢直接采用 秒级时间戳 从而节省性能, 但是后续面向全球化还是要扩展发起的地区时区字段

  • 有的业务系统不需要货币和地区码, 可能单一国家业务不需要通过美元/日元/韩元结算金额

这部分没有什么具体定式, 都是可以按照各自业务需求来动态调整, 接下来就是表结构设计(这里是 MariaDB(MYSQL Fork的分支))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

# 首先是通用的单一用数据应用表
# 虽然工作大部分情况都在游戏公司, 但是我还是喜欢用 app 这个命令来包含游戏分类
# 这部分是我个人喜欢, 也可以按照自己需求改成 game_info 之类, 具体按照自身需求出发
create table if not exists nova_app_info
(
# 通用信息, 注意以下说明:
# 除了渠道用户之外, 还有直接官方服直接对接的情况, 这部分授权支付验证采用的这张表的 app_key 和 app_secret
# 渠道应用的 key 和 secret 是不一样的, 从而避免单一 key 和 secret 被窃取后导致全部渠道都可以绕过验证
app_id bigint not null auto_increment comment '数据主键, 用于标识递增',
app_ident varchar(32) not null comment '应用唯一标识字符串, 有时候应用不喜欢外部看到数值ID(会被爬虫遍历嗅探递增从而获取全部应用)',
app_key varchar(32) not null comment '客户端和服务端使用的授权等参数签名哈希值',
app_secret varchar(32) not null comment '服务端使用的支付等安全性高的签名哈希值',

# 基础信息
platform varchar(64) not null default '' comment '应用分配平台, android/ios/h5/pc 标识',
name varchar(64) not null comment '应用的名称, 提供给应用初始化接口的信息初始化',
title varchar(255) not null default '' comment '应用的长标题, 用于显示应用的具体标题内容',
content varchar(255) not null default '' comment '应用的详细内容, 可以用于整体应用说明, 需要内部支持富文本渲染',
language varchar(8) not null default 'en' comment '应用的默认 i18n 语言模板, 比如 en = 英文, zh-CN = 简体中文, zh-TW = 繁体中文',
orientation tinyint not null default '0' comment '屏幕方向, 0 = 默认, 1 = 横屏, 2 = 竖屏',
keyboard varchar(255) not null default '' comment '应用类型(以因为分割风格), 比如 "武侠,卡牌,MMO" 之类方便对外 SEO',


# 图标相关, 图片只需要保存相对路径即可, 方便后面上传 CDN
# 比如 https://site.example.com/static/images/test.png 就只需要保存 /static/images/test.png 路径部分
# 后面按照这部分路径保存到CDN的地址, 不建议采用过深的目录保存图片地址, 可能会导致数据长度不够被截断
icon varchar(255) not null default '' comment '小型图标图片地址, 使用 192x192 像素',
cover varchar(255) not null default '' comment '大型应用封面图片地址',
background varchar(255) not null default '' comment '大型应用背景图片地址',


# 其他创建|更新信息
status tinyint not null default '0' comment '应用状态, 默认为0代表刚创建',
create_time bigint not null comment '创建时间',
create_ip varchar(64) not null comment '创建IP',
update_time bigint not null default '0' comment '更新时间',
update_ip varchar(64) not null default '' comment '更新IP',


# 索引信息
unique key find_ident (app_ident),
primary key (app_id)
) comment '应用信息表, 这部分只需要简单的概述信息, 其他需要扩展的外部信息最好放置于大表'
engine = InnoDB
charset = utf8mb4
collate = utf8mb4_unicode_ci
auto_increment = 10000 # 从 10000 开始, 预留低于这个值的应用都是测试游戏应用
;


# 主要应用表生成之后, 就可以基于这部分应用来细分对应用户数据和渠道数据, 这里插入测试数据应用
# 这就是目前手动创建的最基础测试应用
INSERT INTO nova_app_info
VALUES (10000,
# 应用信息
'dq60xls02i',
'c33614a5d9a91580f56d09b23b4d0036',
'ebe150ff1f38d30a1cb26d956fa92b62',

# 基础信息
'h5',
'Nova游戏',
'Nova游戏 - 聚合测试应用',
'Nova游戏<br> 助力游戏聚合相关',
'zh-CN',
0,
'武侠,回合制',

# 图标相关
'/static/images/icon/bd498e9235d5a0aa15b6e7adfd43f556.png',
'/static/images/cover/a2e4119c419378698b6629ae4988d880.png',
'/static/images/background/55181431f164e657067faca4b50b8e5f.png',

# 其他创建|更新信息
1,
1780677501757,
'127.0.0.1',
0,
'');

这就是游戏应用主体表设计, 注意: 一个游戏是关联多个渠道(也包含官方服), 渠道游戏唯一关联标识 = ({渠道ID} + {游戏ID})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 聚合渠道部分也是共享表, 可以放在统一的数据库
create table if not exists nova_channel_info
(
# 通用信息
channel_id bigint not null auto_increment comment '数据主键, 用于标识递增',
channel_ident varchar(32) not null comment '渠道的唯一标识字符串, 这部分可以提供自定义, 但是只允许小写字母+数值等',

# 基础信息
name varchar(64) not null comment '渠道的展示名称, 默认设定和 channel_ident 保持一致, 后续如果想修改展示名称也方便',


# 其他创建|更新信息
status tinyint not null default '0' comment '数据状态, 默认为0代表可用, 渠道会出现多种禁用状态(后续大于 0 代表不同停用理由, 比如: 1 - 常规封禁, 100 - 合作结束停用)',
create_time bigint not null comment '创建时间',
create_ip varchar(64) not null comment '创建IP',
update_time bigint not null default '0' comment '更新时间',
update_ip varchar(64) not null default '' comment '更新IP',

unique key find_ident (channel_ident),
primary key (channel_id)
) comment '应用渠道表, 注意: 渠道表数据表绝对不能删除数据(按照 status 不展示即可), 强制删除会导致关联统计异常'
engine = InnoDB
charset = utf8mb4
collate = utf8mb4_unicode_ci
;

# 这里构建属于我们的特殊渠道
# 现在就可以准备使用我们自定义的 {APP_ID = {10000}, CHANNEL_IDENT = {novagame}} 的游戏应用
INSERT INTO nova_channel_info
VALUES (DEFAULT,
'novagame',
'novagame',
0,
1780677501757,
'127.0.0.1',
0,
'');

至此就获得自定义的 {APP_ID = {10000}, CHANNEL_IDENT = {novagame}} 的渠道专服游戏, 现在就是做进一步规划设计

聚合的游戏应用常采用类似链路设计: https://{API_URL}/business/{3RD_CHANNEL}/{METHOD}/{APP_ID}/{CHANNEL_IDENT}

  • {API_URL}: 对外开放的API服务域名

  • {3RD_CHANNEL}: 对接的第三方渠道SDK, 比如 QQ腾讯大厅/360游戏大厅/QuickSDK/百度 等对接渠道

  • {METHOD}: 调用第三方渠道 SDK 方法, 主要对接 应用初始化/验证授权/发起支付/支付回调/信息上报

  • {APP_ID}: 渠道对应的游戏应用ID, 也就是聚合系统内部的游戏ID

  • {CHANNEL_IDENT}: 聚合系统当中自己划分的特殊渠道标识

聚合系统主要目标就是对接 QQ腾讯大厅/360游戏大厅/QuickSDK/百度 等 SDK 从而集成到自己的系统