本文按当前服务端实现说明 CDK 的生成、兑换、数据库位置、奖励配置和常见日志排查。
当前 CDK 主脚本:
tlbb/services/scripts/Reward/CDK.lua
脚本注册:
900067 -> scripts.Reward.CDK
888899 -> scripts.event.prize.eprize
客户端入口:
NewbieCardActivation
当前服务端兑换链路:
客户端输入卡号
-> CGAskPrize
-> 888899.OpenCard
-> 900067.ReceiveCdkAward_bff
-> CDK:redeem_code
两种 CDK
当前服务端支持两种 CDK。
| 类型 |
GM 命令 |
数据表 |
主字段 |
用途 |
| 通用 CDK |
!!createcdk |
money_card |
cardguid |
当前推荐使用,2006 和 20100118 输入框均可兑换 |
| 礼包 CDK |
!!createitemcdk |
cdk_250328_design |
docindex |
旧礼包码方案,当前也可在同一输入框兑换 |
服务端现在统一由 CDK:redeem_code 判断卡号类型:
- 如果卡号长度是 15 位,并且存在于
money_card.cardguid,按通用 CDK 兑换。
- 如果卡号存在于
cdk_250328_design.docindex,按礼包 CDK 兑换。
- 如果卡号存在于
cdk_250328_design_claimed.docindex,提示已领取。
- 都不存在时,提示
CDK不存在。
生成命令
生成通用 CDK
推荐命令:
!!createcdk count=1
等价写法:
!!createcdk 1
!!addcdk 1
!!新增CDK count=1
生成结果写入:
.char_db.money_card
关键字段:
| 字段 |
说明 |
docindex |
固定为 moneycard |
cardguid |
实际 CDK 字符串 |
playerguid |
未领取为 0,领取后写角色 GUID |
playername |
领取角色名 |
awardtimer |
第一次激活时间 |
awardtimer_two |
预留字段 |
awardinfo |
尚未激活 / 已激活 |
通用 CDK 当前生成格式:
2 个 6位数字段 + 3 个单字母段
因此总长度为 15 位,例如:
Ek615630467820Go
生成礼包 CDK
推荐命令:
!!createitemcdk count=1
等价写法:
!!createitemcdk 1
!!additemcdk 1
!!createlegacycdk 1
!!新增礼包CDK count=1
生成结果写入:
.char_db.cdk_250328_design
领取后归档到:
.char_db.cdk_250328_design_claimed
礼包 CDK 当前生成格式:
2 个 6位数字段 + 4 个单字母段
因此总长度通常为 16 位,例如:
bE495082187908Er
w710168181203iST
注意:当前 count 参数已经精确生效。!!createitemcdk count=1 就生成 1 条礼包 CDK。
兑换入口
玩家/测试人员兑换
大理 NPC 当前打开的是 CDK 激活界面:
20100118
该界面对应客户端 NewbieCardActivation,服务端会统一接收 CGAskPrize。
当前同一个输入框可以兑换:
!!createcdk 生成的通用 CDK
!!createitemcdk 生成的礼包 CDK
2006 和 20100118
客户端 NewbieCardActivation 也支持 2006:
if tonumber(arg0) == 2006
or tonumber(arg0) == 20100118
客户端脚本语义不同:
| UI 命令 |
客户端语义 |
提交参数 |
2006 |
物品卡 |
NewUserCard(cardNum, g_cardId, 0) |
20100118 |
财富卡 |
NewUserCard(cardNum, g_cardId, 1) |
服务端当前只按最终收到的 CDK 字符串兑换,不区分这个客户端类型参数。只要客户端发出 CGAskPrize,服务端就能按统一逻辑处理。
当前实测 2006 和 20100118 都可以兑换。文档和测试口径统一称为 CDK 输入框,不再把 !!createcdk 归类为原生财富卡。
奖励配置
通用 CDK 奖励
通用 CDK 奖励配置在:
CDK.AwardInfo = {
Titleid = 1073,
TitleName = "称号:竹涧轻觞会知交",
TitleFlag = -1,
{ itemid = 10124519, count = 1, isbind = true },
{ itemid = 10142793, count = 1, isbind = true },
{ itemid = 38003055, count = 1, isbind = true },
{ itemid = 20310168, count = 666, isbind = true },
}
字段说明:
| 字段 |
说明 |
itemid |
道具 ID |
count |
数量 |
isbind |
是否绑定 |
Titleid |
称号 ID |
TitleName |
提示用称号名 |
TitleFlag |
-1 表示走 char_title_new.txt 称号 |
BindYuanBao |
可选,配置后发绑定元宝 |
第二重奖励预留:
CDK.AwardInfoTwo = {
}
当前 AwardInfoTwo 为空。如果同一角色已经激活过通用 CDK,再兑换第二张通用 CDK,会提示:
该CDK没有配置奖励,请联系管理员。
如果要开放第二重奖励,需要在 AwardInfoTwo 中配置至少一种奖励。
礼包 CDK 奖励
礼包 CDK 奖励配置在:
CDK.create_cdk_ini = {
{ item_id = 20310167, item_num = 20, cdk_price = 50 },
{ item_id = 20310168, item_num = 20, cdk_price = 50 },
{ item_id = 38002397, item_num = 20, cdk_price = 50 },
{ item_id = 38002499, item_num = 20, cdk_price = 50 },
{ item_id = 20600003, item_num = 5, cdk_price = 50 },
{ item_id = 38003055, item_num = 5, cdk_price = 50 },
{ item_id = 38003158, item_num = 2, cdk_price = 50 },
}
字段说明:
| 字段 |
说明 |
item_id |
礼包 CDK 兑换后发放的道具 |
item_num |
发放数量 |
cdk_price |
价格/充值记录用途 |
礼包 CDK 生成时会按配置列表循环选择奖励。例如 count=10,会从第一行开始循环生成 10 条。
数据库查询
以下命令以 Mongo shell 为例,库名按实际部署填写。
查询通用 CDK
查询未领取/已激活状态:
db.money_card.findOne({cardguid:"完整CDK"})
查看最近生成的通用 CDK:
db.money_card.find(
{},
{_id:0, cardguid:1, playerguid:1, playername:1, awardtimer:1, awardinfo:1}
).limit(20)
导出通用 CDK:
mongoexport \
--db tlbb \
--collection money_card \
--type=csv \
--fields cardguid,playerguid,playername,awardtimer,awardinfo,createtimer \
--out money_card.csv
查询礼包 CDK
查询未领取:
db.cdk_250328_design.findOne({docindex:"完整CDK"})
查询已领取:
db.cdk_250328_design_claimed.findOne({docindex:"完整CDK"})
查看最近未领取礼包码:
db.cdk_250328_design.find(
{},
{_id:0, docindex:1, item_id:1, item_name:1, item_num:1, cdk_price:1, createtimer:1}
).limit(20)
导出未领取礼包 CDK:
mongoexport \
--db tlbb \
--collection cdk_250328_design \
--type=csv \
--fields docindex,item_id,item_name,item_num,cdk_price,createtimer \
--out cdk_250328_design.csv
导出已领取礼包 CDK:
mongoexport \
--db tlbb \
--collection cdk_250328_design_claimed \
--type=csv \
--fields docindex,item_id,item_name,item_num,playerguid,playername,accountname,serverid,claim_time \
--out cdk_250328_design_claimed.csv
兑换流程
通用 CDK 流程
ReceiveCdkAward_bff
-> redeem_code
-> get_money_card_record
-> redeem_money_card
-> 检查是否已激活
-> 选择 AwardInfo / AwardInfoTwo
-> 检查背包
-> 发道具
-> 更新 money_card
-> 发称号/绑定元宝
-> 全服公告
礼包 CDK 流程
ReceiveCdkAward_bff 或 ReceiveCdkAward
-> redeem_code
-> get_legacy_claimed_record
-> get_legacy_record
-> redeem_legacy_card
-> 检查内测开关/是否领取/推广卡限制/背包
-> 写入 cdk_250328_design_claimed
-> 删除 cdk_250328_design
-> 发道具
-> 写充值记录或推广标记
已领取表 cdk_250328_design_claimed 是旧礼包码的领取状态权威来源。删除未领取表失败不会再错误阻断已归档的兑换状态。
常见提示与日志
| 提示/日志结果 |
含义 |
处理 |
ok |
兑换成功 |
正常 |
invalid_format |
卡号格式不合法,通常有空格以外的特殊字符或参数异常 |
检查复制的 CDK |
not_found |
通用 CDK 表、旧礼包未领取表、旧礼包已领取表都没有这条码 |
检查是否生成到正确库/表 |
claimed |
已经领取过 |
查 money_card 或 cdk_250328_design_claimed |
claimed_by_player |
通用 CDK 记录已有领取玩家 |
不允许其他玩家领取 |
cooldown |
1 秒内重复点击 |
等 1 秒后再试 |
bag_full |
背包空间不足 |
清理背包 |
empty_award |
奖励配置为空 |
检查 AwardInfoTwo 或奖励配置 |
archive_insert_failed |
旧礼包 CDK 写入已领取表失败 |
查 Mongo 写入状态/唯一键/数据库连接 |
update_failed |
通用 CDK 更新领取状态后校验失败 |
查 money_card 记录和数据库更新 |
服务端日志示例:
[CGAskPrize] guid=200001 code=bE495082187908Er result=claimed
说明这条旧礼包 CDK 已在已领取表中,不应该再次发奖。
测试步骤
测试通用 CDK
- 生成 1 条通用 CDK:
!!createcdk count=1
- 从
money_card.cardguid 取出卡号。
- 打开大理 CDK 激活入口。
- 输入卡号兑换。
- 查询数据库确认:
db.money_card.findOne({cardguid:"完整CDK"})
应看到 playerguid、playername、awardtimer 已更新。
测试礼包 CDK
- 生成 1 条礼包 CDK:
!!createitemcdk count=1
- 从
cdk_250328_design.docindex 取出卡号。
- 打开大理 CDK 激活入口。
- 输入卡号兑换。
- 查询数据库确认:
db.cdk_250328_design.findOne({docindex:"完整CDK"})
db.cdk_250328_design_claimed.findOne({docindex:"完整CDK"})
正确结果:
cdk_250328_design 查不到。
cdk_250328_design_claimed 查得到,并有 playerguid、playername、claim_time。
修改奖励配置后的生效方式
修改以下文件后,需要重载/重启对应服务端脚本环境:
tlbb/services/scripts/Reward/CDK.lua
如果涉及包解析或 CGAskPrize 链路,还需要确保 msgagent 相关服务已重启或热更到最新代码。
注意事项
2006 和 20100118 都可以兑换,只要客户端能发出 CGAskPrize。
!!createcdk 生成通用 CDK,!!createitemcdk 生成旧礼包 CDK,不要混淆数据库表。
- 旧礼包 CDK 领取状态以
cdk_250328_design_claimed 为准。
- 通用 CDK 领取状态以
money_card.playerguid 和 money_card.awardtimer 为准。
AwardInfoTwo 当前为空,第二次通用 CDK 兑换会提示奖励未配置。
- 如果测试时出现
not_found,先同时查三张表:money_card、cdk_250328_design、cdk_250328_design_claimed。
- 如果测试时出现
claimed,说明服务端已经认为这条码被领取,不应再次发奖。