跳到主要内容
版本:2.0.0

Code 验证码系统

Code 模块提供了一套完整的验证码生命周期管理方案。它不仅支持验证码的生成与校验,还内置了过期时间管理以及与系统绑定限制(Bind Limit)的集成,是实现“群服互通”账号绑定功能的核心组件。

API 参考

code 命名空间提供了以下方法:

declare namespace code {
/**
* 获取指定玩家当前有效的验证码
* @returns 验证码字符串,若不存在或已过期则返回 null
*/
function GetCode(playerName: string): string | null;

/**
* 根据验证码反查玩家名称
* @returns 玩家名称,若验证码无效则返回 null
*/
function GetUserName(code: string): string | null;

/**
* 获取玩家验证码的过期时间
* @returns 格式化时间 (yyyy-MM-dd HH:mm:ss),不存在则返回 null
*/
function GetCodeExpTime(userName: string): string | null;

/**
* 为指定玩家生成一个新的验证码
* (生成的长度与规则遵循 EasyBot 全局绑定设置)
* @returns 生成的验证码
*/
function GenCode(userName: string): string;

/**
* 标记验证码验证成功
* 注意:此操作仅会从系统中移除该验证码,不会自动操作数据库进行账号绑定
* @returns 是否标记成功
*/
function MarkSuccessByName(userName: string): boolean;

/**
* 获取系统配置中允许每个社交账号绑定的最大玩家数量
*/
function GetBindLimit(): number;
}

最佳实践:账号绑定系统

以下示例展示了如何结合 httpServerdb (数据库) 和 code 模块实现一个完整的绑定流程:

  1. 玩家在游戏内触发 API 生成验证码。
  2. 玩家在群内输入验证码。
  3. 插件校验成功后,将游戏账号与社交账号永久关联。

1. 验证码生成(服务端 API 逻辑)

通常由游戏插件(如 Minecraft 插件)调用此 HTTP 接口为玩家申请验证码。

// 存储待验证的临时状态: { QQ号: { playerName, code } }
const pendingBinds = {};

httpServer.OnPost("my_api", "/request_bind", (req, res) => {
const { name, account, key } = JSON.parse(req.body);

// 1. 安全校验与重复绑定检查
if (key !== "YOUR_SECRET_KEY") return res.status = 401;

const player = db.GetPlayerByName(name);
if (player?.SocialAccount) {
res.body = JSON.stringify({ message: "该角色已绑定账号" });
return res.status = 400;
}

// 2. 生成验证码并记录缓存
const bindCode = code.GenCode(name);
const expTime = code.GetCodeExpTime(name);

pendingBinds[account] = { playerName: name, code: bindCode };

res.status = 200;
res.body = JSON.stringify({ code: bindCode, expire: expTime });
});

2. 验证码校验(机器人消息监听)

玩家只需在群聊中直接发送验证码即可完成绑定。

bus.on("group_message_event", (event) => {
const senderId = event.SenderId;
const userMessage = event.RawMessage.trim(); // 获取用户输入的文本

// 检查该用户是否有待处理的绑定请求
const bindInfo = pendingBinds[senderId];
if (!bindInfo) return;

// 获取系统内该玩家真正的有效验证码
const validCode = code.GetCode(bindInfo.playerName);

// 校验用户输入是否匹配
if (userMessage === validCode) {
// 1. 验证成功,清除系统验证码记录
code.MarkSuccessByName(bindInfo.playerName);
delete pendingBinds[senderId];

// 2. 检查绑定上限
let socialAcc = db.GetSocialAccount(event.AdapterPlatform, senderId);
if (socialAcc && socialAcc.Users.length >= code.GetBindLimit()) {
event.Context.Reply(new MessageChain().Text("绑定失败:您的账号绑定角色数量已达上限"));
return;
}

// 3. 执行数据库持久化绑定
if (!socialAcc) {
socialAcc = db.CreateSocialAccount(event.AdapterPlatform, senderId, event.SenderNickName, null);
}

let player = db.GetPlayerByName(bindInfo.playerName)
|| db.CreatePlayer(bindInfo.playerName, null, null);

db.BindPlayerToSocialAccount(player.Id, socialAcc.Id);

// 4. 反馈结果
event.Context.Reply(new MessageChain().Text(`✅ 绑定成功!\n欢迎回来,${bindInfo.playerName}`));
}
});

开发提示

自动清理

code.MarkSuccessByName 只是删除验证码。实际的逻辑(如给玩家发奖、写入数据库)需要在你的插件代码中完成。

关于过期

code.GetCode(name) 在验证码超过系统设定的有效期后会自动返回 null,因此你不需要手动编写清理过期验证码的逻辑。

遇到麻烦了?

我们提供有偿代安装服务,解决您的环境配置烦恼。

了解详情