一、文档用途
本文档说明当前 Temp_Release_v0-85-8130 版本的 Billing 服务定位、配置、协议、数据链路、容量边界、日志、启动停止和验收方法。
权威顺序:
- 085 参考端 Server.i64、Login.i64、World.i64 的 IDA 结构和伪代码;
- 当前 Server 源码中的协议和生命周期实现;
- billing_go-master_参考源码仅用于补充参考端没有公开业务实现的后台逻辑。
二、服务定位
BillingServer 只处理 LoginServer、WorldServer 发来的 Billing 内部协议,不接受客户端直接登录。典型链路如下:
Client -> LoginServer -> BillingServer -> WorldServer -> BillingServer
Billing 负责:
- 账号密码校验、账号状态校验和自动注册结果;
- 角色进入/退出计费状态以及在线状态清理;
- 点数查询、点数兑换和订单幂等;
- 经典奖品、卡类、注册和账号操作内部协议;
- Billing 与 Login/World 连接断开后的用户状态清理。
三、运行目录与数据库
服务端运行目录固定为:
H:\TLBB\Temp_Release_v0-85-8130\resources\Server
Billing 配置文件:
H:\TLBB\Temp_Release_v0-85-8130\resources\Server\Config\BillingInfo.ini
0.85 数据库分工:
- web:Billing 账号、点数、支付和奖品相关数据;
- tlbbdb:角色、场景和服务端游戏数据。
Billing 当前使用 32 位 ODBC DSN web,配置中的 DBName 必须为 web。
数据库账号必须具有创建 Billing 幂等表和读写 account 表的权限。启动时
UserDBManager 会确保以下表存在:
- billing_point_order:点数兑换订单唯一约束;
- billing_prize_order:奖品序列号唯一约束;
- account_prize:经典账号奖品领取状态。
四、配置规则
4.1 BillingInfo.ini
当前运行配置(不含密码):
[System]
DBIP=127.0.0.1
DBPort=3306
DBName=web
DBUser=tlbbdb
DBPassword=***
[Access]
AllowIPCount=1
AllowIP0=127.0.0.1
[Limit]
MaxClientCount=500
PcMaxClientCount=3
字段说明:
- DBIP、DBPort:Billing 连接 MySQL 的地址和端口;
- DBName:必须使用 web;
- DBUser、DBPassword:数据库凭据;实际值仅保存在 BillingInfo.ini 和版本根目录
的 服务器信息.txt,不得复制到本说明、日志或提交记录;
- AllowIPCount:允许连接 Billing 的服务端 IP 数量;
- AllowIP0 至 AllowIP15:允许的来源 IP;
- AllowIPCount=0:不启用来源 IP 限制;
- MaxClientCount:同时通过 A2 登录的账号总数;0 表示无上限;
- PcMaxClientCount:同一有效 MAC 同时登录的账号数;0 表示无上限。
MaxClientCount 统计已经通过 A2、尚未进入场景的 LoginUsers 和已经进入
游戏的 OnlineUsers,避免登录排队阶段绕过总量限制。PcMaxClientCount
使用 A2 中固定 32 字节 MAC/MD5 字段;MAC 为空时不参与单机计数。
4.2 ServerInfo.ini
Billing 的监听端口由 ServerInfo.ini 的 Billing 区域 Port0 提供:
[Billing]
Port0=10101
当前 BillingInfo.ini 只包含数据库、来源 IP 和登录限制配置;不要在该文件
中新增另一套 Billing 端口配置。Billing 的 AutoRegister 选项按当前 0.85
工程规则读取 ServerInfo.ini 的 Billing 区域。
4.3 限制返回
达到 MaxClientCount 或 PcMaxClientCount 时,A2 返回经典的其它错误结果
0x06,并在 Billing 日志中记录 result_name=SERVER_LIMIT、限制类型、当前
计数和配置上限。密码不会写入日志。
五、Billing 协议
所有 Billing 包使用 AA55 帧头、BE16 数据长度、1 字节 OpType、BE16
MsgID、Payload、55AA 帧尾。响应必须回显请求 MsgID。
OpType 请求 响应 作用
0xA0 LBConnect BLRetConnect 服务端连接握手
0xA1 LBKeepLive BLRetKeepLive 服务端心跳
0xA2 LBAccCheck BLRetAccCheck 账号密码校验
0xA3 LBBillingStart BLRetBillingStart 进入计费状态
0xA4 LBBillingEnd BLRetBillingEnd 退出计费状态
0xA6 LBBillingKeep BLRetBillingKeep 计费心跳
0xA9 LBKickAll BLRetKickALL 按 Zone/World 清理
0xB1 LBLOperateAcc LBLOperateAcc 封停或解封账号
0xC1 LBLAskNewUserCard LBLAskNewUserCard 新手卡入口
0xC3 LBLNewPrize LBLNewPrize 领取经典奖品
0xC4 LBPrize BLRetPrize CDKEY 入口
0xC5 LBLCostLog LBLCostLog 消费审计
0xC6 LBLCardCheckPrize LBLCardCheckPrize 卡类奖品入口
0xE1 LBAskBuy BLRetAskBuy 点数兑换
0xE2 LBAskPoint BLRetAskPoint 点数查询
0xE4 LBLNewCheckPrize LBLNewCheckPrize 查询经典奖品
0xF1 LBRegPassPort BLRetRegPassPort 账号注册
A2 请求包含账号、密码、登录 IP、等级、MiBao 字段、固定 32 字节 MAC 和
可变长度 HWID。A2 结果码:
- 0x01:成功;
- 0x02:账号不存在;
- 0x03:密码错误;
- 0x04:账号已经在线;
- 0x06:后台错误或达到服务端登录限制;
- 0x07:账号被禁止;
- 0x09:自动注册流程提示。
E2 请求为账号、IP、角色名三个 BYTE 长度字符串,返回账号和 BE32 点数。
数据库点数按 0.85 规则乘 1000 后返回。
E1 仅接受一个商品类型、商品类型 999,实际扣除量取 BE16 商品数量;订单
号唯一,重复订单不再次扣点。结果码:0 成功、1 重复订单、2 余额不足、
3 参数错误、4 后台错误。
六、账号生命周期
- Login/World 发送 A0,Billing 连接状态由 CONNECTING(400) 进入 NORMAL(401)。
- 服务端周期性发送 A1,Billing 校验 ZoneID、WorldID 和 MsgID。
- Login 发送 A2,Billing 查询 web.account 并写入 LoginUsers。
- 角色正式进场时发送 A3,Billing 将账号转入 OnlineUsers 并增加 MAC 计数。
- 在线期间发送 A6;Billing 返回剩余时间、储值点和用户点数。
- 正常退出发送 A4,Billing 删除账号并减少 MAC 计数。
- World 发送 A9,或 Billing 连接断开时,按 ZoneID/WorldID 清理残留用户。
BillingServer 的 ServerPlayer::CleanUp 会清理 LoginUsers、OnlineUsers 和
MAC 计数,防止 Login/World 异常退出后账号永久保持在线。
七、日志与故障定位
日志目录:
H:\TLBB\Temp_Release_v0-85-8130\resources\Server\Log
Billing 主要日志文件使用日期和启动标识命名,例如 Billing*.log、
Config*.log。启动时应看到:
- g_UserDBManager.Init()...OK;
- Billing access allowlist count=...;
- Billing login limits max_client_count=... pc_max_client_count=...;
- g_pServerManager->Init()...OK;
- Loop...。
A2 认证日志使用结构化格式:
AUTH event=account_check stage=billing account=... result=0x.. \
result_name=... action=... source_ip=... zone=... world=... socket=... packet=...
排查顺序:
- 先确认 Billing.exe 使用 resources\Server 作为工作目录;
- 检查 Config_*.log 是否读取 BillingInfo.ini;
- 检查 Billing_*.log 的数据库初始化、来源 IP 和限制配置;
- 检查 Login/World 是否完成 A0,状态是否为 401;
- 再检查 A2/A3/A4 的账号、MsgID 和 Zone/World;
- 出现 0x06 时区分数据库错误和 SERVER_LIMIT 日志;
- 出现断线时优先检查包长度、MsgID、A0/A1 状态和数据库连接。
使用 -nologprintf 时只关闭控制台日志输出,不关闭日志文件写入。
八、构建、部署与启动
8.1 构建
在版本根目录使用推荐脚本重建。脚本会用 VS2008 按依赖顺序构建
ShareMemory、Billing、World、Login、Server 五个服务端项目:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\build-server.ps1 -Configuration Debug -Rebuild
Billing 的 Debug 构建产物为:
H:\TLBB\Temp_Release_v0-85-8130\_Bin\Debug\Billing\Billing.exe
H:\TLBB\Temp_Release_v0-85-8130\_Bin\Debug\Billing\Billing.pdb
Release 构建时将 Debug 替换为 Release。构建清单写入版本根目录的
build-Debug-manifest.json 或 build-Release-manifest.json。
8.2 部署
部署前先停止全部服务,再使用部署脚本将同一轮构建的 EXE/PDB 复制到运行
目录,并在 resources\Server\Backup\时间戳 保留旧文件:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\stop-server.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\deploy-server.ps1 -Configuration Debug
运行目录为:
H:\TLBB\Temp_Release_v0-85-8130\resources\Server
8.3 启动与停止
实际启动顺序:
ShareMemory -> Billing -> World -> Login -> Server
启动脚本会检查 MariaDB 的 3306 端口,不存在时调用tools\database\start_mariadb_hidden.vbs,并依次等待 Billing 10101、World 777、Login 1440、GameServer 1450 端口可用。
后台启动:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\start-server.ps1
前台查看服务端窗口并启动 Debug 客户端,可执行:
resources\Run.bat
正常停止使用:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\stop-server.ps1
resources\kill.bat 是强制结束进程的兼容脚本,仅在正常停止失败时使用。
Debug 客户端启动命令为:
H:\TLBB\Temp_Release_v0-85-8130\Client085\Bin\Game.exe -fl -debug
九、容量边界
当前 Billing 代码的结构限制:
- MaxClientCount 默认配置为 500;
- MAX_BILLING_PLAYER=1024,表示 Billing 服务端连接管理容量;
- PlayerPool 预分配 1280 个 ServerPlayer;
- Windows select 使用 FD_SETSIZE=4096;
- Billing 当前只有一个 ODBC 数据库接口;
- 协议循环为单线程 select、输入、输出和命令处理。
4 核 8G 机器上,Billing 单独运行时 500 个在线账号属于当前实现的保守目标;整套 Game/World/Login/Billing/MySQL 共机时先按 300 至 500 人验收。超过 500 人前必须进行压测,不能只修改 MaxClientCount。数据库查询延迟、GameServer 场景对象数量和单线程命令队列通常比 Billing 内存更早成为瓶颈。