一、BTG v1.0.3 插件原生基础概述
BTG v1.0.3(Before Thought Game)是 OpenClaw 配套竞技游戏专用插件,内置本地独立 btg_runner 运行器,核心功能覆盖 AI 机器人对战、全球竞技排行榜数据同步、对局结算计分、机器人策略技能调度、赛事匹配、战绩存档;整套插件分为底层 btg_runner 执行工具、上层 AI 对战 btg 技能两层结构,用于自动化批量 AI 竞技冲榜、多机器人自动匹配对局、生成对战战绩榜单。
当前 v1.0.3 基础版本仅完成 runner 基础启动、基础 HTTP 通信、简单对战调度逻辑,未做网络通信安全隔离、runner 进程沙箱、机器人策略输入注入防护、排行榜数据防篡改、多机器人并发调度、对局数据持久容错、通信风控限流、对战行为审计监控,批量机器人冲榜、高频对局场景下会出现通信劫持、策略指令注入篡改对战逻辑、刷分作弊、runner 进程卡死、对局数据丢失、API 封禁机器人账号等问题,为此落地全套专项二次改造升级计划,从网络通信安全、runner 进程沙箱隔离、对战指令防注入、排行榜数据校验、多机器人并发队列、对局持久化容错、API 限流风控、全链路对战审计八大底层模块完整重构,根除原生稳定性、安全、作弊风控全部短板。
二、原版 BTG v1.0.3 七大核心原生缺陷
1. 网络通信无域名白名单、无证书校验,易中间人劫持篡改对局 / 榜单数据
原生 HTTP 请求无固定域名校验,可被注入指令访问任意第三方地址;未强制 TLS 校验、无双向证书绑定,中间人可拦截、篡改对局胜负、排行榜积分数据;通信报文明文传输,机器人 token、对战凭证直接暴露,存在盗号、恶意刷分风险。
2. btg_runner 无独立进程沙箱,多机器人共用主线程,并发对局内存溢出卡死
所有 AI 对战共用单一全局 runner 进程,无进程隔离;批量启动数十个机器人同时匹配对战时资源抢占,CPU / 内存持续暴涨,runner 无超时销毁机制,僵尸进程长期占用算力;单 runner 崩溃会导致全部在线机器人对局强制中断,战绩直接丢失。
3. AI 对战策略指令无输入净化,提示注入可篡改机器人操作逻辑、恶意刷分
直接将大模型生成的对战策略、操作指令拼接传入 runner 执行,无高危字符过滤、指令白名单校验;恶意构造特殊符号、参数注入可跳过正常对局计分逻辑、强制修改胜负判定、批量刷取排行榜高分,破坏竞技公平性。
4. 排行榜同步无数据哈希校验,本地伪造战绩可直接覆盖云端榜单
同步积分、对局战绩时仅简单 POST 上传原始数据,无本地 + 云端双重哈希签名校验;本地篡改战绩文件、伪造胜利对局可直接提交至官网榜单,缺少防作弊校验机制,无法区分正常对局与刷分伪造数据。
5. 无异步对战调度限流队列,高频批量冲榜触发平台 API 风控封禁机器人
所有匹配、对战、榜单同步请求同步无限制并发,短时间大量机器人循环冲榜会高频调用beforethoughtgame.com接口,极易触发平台 QPS 限制,批量封禁机器人 token;无消峰延时、任务优先级调度,批量对局阻塞正常单人竞技请求。
6. 对局战绩本地无事务持久化,runner 崩溃、网络中断直接丢失完整对局记录
对局过程中战绩、操作记录仅内存临时存储,无分段落盘预写日志;runner 意外退出、网络断开时当前对局全部数据清空,无法回溯对战流程、无法申诉榜单积分异常;无自动断点续赛机制,中断对局需要重新从头匹配。
7. 无对战行为、网络请求审计日志,刷分作弊、账号封禁无法溯源
仅极简打印 runner 启动日志,不记录机器人操作指令、对局胜负同步记录、API 调用频次、网络异常报文;出现恶意刷分、账号被封禁、积分异常时无法定位对应机器人、触发指令、操作时间,缺少风险告警机制。
三、BTG 专属二次改造升级完整执行计划
(一)改造核心目标
- 搭建固定域名白名单 + TLS 双向证书绑定加密通信,拦截恶意外联、中间人劫持,对战报文加密传输保护机器人凭证;
- 实现多机器人独立隔离 btg_runner 进程池,硬件资源上限管控,僵尸进程自动销毁,单一 runner 崩溃不影响其余机器人对局;
- 三层对战指令防护:输入净化 + 操作指令白名单 + 沙箱参数传参,彻底拦截注入篡改对战逻辑、恶意刷分作弊行为;
- 对局 / 榜单数据双层哈希签名校验,本地战绩与云端同步强制校验完整性,拦截伪造虚假胜利对局,保障竞技公平;
- 构建带优先级异步对战任务限流队列,限制单机器人、全局 API 并发频次,自动消峰延时,规避平台风控封禁账号;
- 对局分段预写日志持久化存储,支持断点续赛,runner 崩溃、断网可恢复未完成对局,完整留存对战记录用于积分申诉;
- 搭建全链路对战审计 + API 调用监控,刷分、高频请求、通信异常实时风险告警,作弊行为完整可溯源;
- 100% 兼容原版 btg_runner 调用规则、beforethoughtgame.com通信协议、机器人对战技能、排行榜同步逻辑,上层 OpenClaw 对战调度代码零修改,无缝平滑升级。
(二)二次改造对比原版核心优势
- 通信链路安全防劫持 仅允许访问官方固定域名,强制 TLS1.3 双向证书校验,对战报文加密传输,中间人无法篡改积分、盗取机器人凭证,杜绝榜单数据伪造。
- 多机器人高并发稳定对战 独立 runner 进程池隔离各机器人算力资源,设置 CPU / 内存硬上限,卡死进程自动销毁,单个机器人崩溃不会中断全局竞技任务。
- 竞技公平防刷分作弊闭环 高危字符清洗 + 合法操作白名单 + 沙箱隔离三层防护,注入指令无法篡改胜负判定;战绩哈希签名校验拦截伪造对局,杜绝恶意刷排行榜高分。
- API 请求可控,规避账号封禁 精细化限流队列,区分冲榜批量任务与正常单人对局优先级,自动平缓高频请求峰值,大幅降低机器人 token 被平台风控封禁概率。
- 对局数据高可靠不丢失,支持申诉回溯 对局实时分段落盘预写日志,网络中断、runner 崩溃可断点续赛,完整对战记录永久留存,积分异常可凭借本地日志向平台申诉。
- 运维可视化作弊溯源 每一条对战指令、榜单同步请求完整审计留存,高频刷分、通信劫持、账号受限实时推送告警,快速定位作弊机器人与违规操作指令。
四、完整底层代码二次修改方案(可直接复制部署)
改造涉及核心文件清单
官方域名白名单加密通信 btg-secure-network.js
btg_runner 隔离进程资源池 btg-runner-process-pool.js
对战策略指令注入防护 btg-battle-sanitize-filter.js
排行榜对局哈希防篡改校验 btg-rank-data-verify.js
异步限流对战任务调度队列 btg-battle-task-queue.js
对局预写日志持久断点续赛 btg-battle-persist-recover.js
对战行为风控审计告警 btg-battle-audit-risk.js
1. 官方域名白名单加密通信 btg-secure-network.js
原版缺陷代码
javascript
运行
// v1.0.3原版:无域名限制、无证书校验,明文请求
const axios = require("axios");
const API_HOST = "beforethoughtgame.com";
// 无任何安全校验,可被注入任意url
async function syncBattleRank(botToken, battleData) {
return await axios.post(`https://${API_HOST}/rank/upload`, battleData, {
headers: { token: botToken }
})
}
二次重构优化代码
javascript
运行
const https = require("https");
const crypto = require("crypto");
// 仅放行官方固定域名
const ALLOW_HOST = "beforethoughtgame.com";
// TLS双向证书配置,拒绝劫持自签证书
const TLS_AGENT = new https.Agent({
minVersion: "TLSv1.3",
rejectUnauthorized: true
});
// 生成对战数据签名,用于防篡改校验
function signBattleData(botToken, rawData) {
return crypto.createHmac("sha256", botToken)
.update(JSON.stringify(rawData))
.digest("hex");
}
// 安全封装网络请求,拦截非法域名、加密签名报文
async function secureBattleApiReq(botToken, path, battleData) {
const audit = require("./btg-battle-audit-risk");
const targetUrl = new URL(path, `https://${ALLOW_HOST}`);
// 拦截非官方域名访问
if (targetUrl.hostname !== ALLOW_HOST) {
audit.triggerRiskAlert("network_domain_inject", `机器人${botToken}尝试访问非法域名${targetUrl.hostname}`);
throw new Error("禁止访问非BTG官方竞技域名");
}
const dataSign = signBattleData(botToken, battleData);
const reqBody = { data: battleData, sign: dataSign };
return new Promise((resolve, reject) => {
const req = https.request({
hostname: ALLOW_HOST,
path: targetUrl.pathname,
method: "POST",
agent: TLS_AGENT,
headers: {
"Content-Type": "application/json",
"X-Bot-Token": botToken,
"X-Data-Sign": dataSign
}
}, res => {
let buf = "";
res.on("data", c => buf += c.toString());
res.on("end", () => resolve(JSON.parse(buf)));
});
req.write(JSON.stringify(reqBody));
req.end();
});
}
module.exports = { secureBattleApiReq, signBattleData };
2. btg_runner 隔离进程资源池 btg-runner-process-pool.js
javascript
运行
const { spawn } = require("child_process");
const fs = require("fs");
const RUNNER_BIN = "./bin/btg_runner";
// 进程池限制配置
const MAX_RUNNER_POOL = 12;
const MAX_RUN_TIMEOUT = 120000; // 2分钟无响应强制销毁
const CPU_MEM_LIMIT_ENV = { MAX_CPU_USAGE: "70", MAX_MEM_MB: "2048" };
const runnerPool = new Map();
// 创建独立隔离runner进程,单机器人独占
async function createBotRunner(botId) {
if (runnerPool.size >= MAX_RUNNER_POOL) throw new Error("BTG运行器进程池已达上限");
if (runnerPool.has(botId)) return runnerPool.get(botId);
const child = spawn(RUNNER_BIN, [], {
env: { ...process.env, ...CPU_MEM_LIMIT_ENV },
cwd: "./btg-sandbox/",
shell: false
});
const runnerItem = { botId, child, alive: true };
runnerPool.set(botId, runnerItem);
// 超时强制销毁卡死进程
const killTimer = setTimeout(() => {
if (child.exitCode === null) {
child.kill("SIGKILL");
runnerItem.alive = false;
require("./btg-battle-audit-risk").triggerRiskAlert("runner_timeout", `机器人${botId}运行器卡死,强制销毁`);
}
}, MAX_RUN_TIMEOUT);
child.on("close", () => {
clearTimeout(killTimer);
runnerItem.alive = false;
runnerPool.delete(botId);
});
return runnerItem;
}
// 向指定机器人runner发送对战指令
async function sendBattleCmdToRunner(botId, safeCmdParams) {
const runner = runnerPool.get(botId);
if (!runner || !runner.alive) {
await createBotRunner(botId);
}
const targetRunner = runnerPool.get(botId);
targetRunner.child.stdin.write(JSON.stringify(safeCmdParams) + "\n");
}
module.exports = { createBotRunner, sendBattleCmdToRunner, runnerPool };
3. 对战策略指令注入防护 btg-battle-sanitize-filter.js
javascript
运行
// 对战高危注入字符黑名单
const DANGER_CHAR_REG = /[`$&|;><\\\r\n]/g;
// 合法对战操作指令白名单,拦截篡改胜负、刷分指令
const ALLOW_BATTLE_CMD = ["unit_move", "skill_cast", "defend", "retreat", "match_accept"];
// 第一层:清洗注入高危字符
function sanitizeBattleInput(rawText) {
return rawText.replace(DANGER_CHAR_REG, "");
}
// 第二层:校验对战指令合法性
function verifyBattleCmdLegal(cmdName) {
return ALLOW_BATTLE_CMD.includes(cmdName);
}
// 三层防护封装,非法指令直接拦截并记录风险日志
function safeWrapBattleCommand(botId, cmdName, rawParams) {
const audit = require("./btg-battle-audit-risk");
const cleanParams = rawParams.map(item => sanitizeBattleInput(String(item)));
if (!verifyBattleCmdLegal(cmdName)) {
audit.triggerRiskAlert("battle_cmd_inject", `机器人${botId}执行非法对战指令:${cmdName},操作拦截`);
throw new Error("检测到可疑注入对战指令,已拦截");
}
return { cmd: cmdName, params: cleanParams };
}
module.exports = { safeWrapBattleCommand, sanitizeBattleInput };
4. 排行榜对局哈希防篡改校验 btg-rank-data-verify.js
javascript
运行
const crypto = require("crypto");
// 本地生成对局完整校验哈希
function calcBattleRankHash(botId, battleId, winState, score, battleTime) {
const rawStr = `${botId}|${battleId}|${winState}|${score}|${battleTime}`;
return crypto.createHash("sha256").update(rawStr).digest("hex");
}
// 云端返回校验值与本地哈希比对,不一致判定伪造战绩
function verifyBattleRankIntegrity(localHash, cloudSign) {
return localHash === cloudSign;
}
// 封装带哈希签名的榜单同步数据
function buildSafeRankPayload(botToken, botId, battleRecord) {
const { battleId, winState, score, battleTime } = battleRecord;
const recordHash = calcBattleRankHash(botId, battleId, winState, score, battleTime);
return {
record: battleRecord,
local_hash: recordHash,
sign: require("./btg-secure-network").signBattleData(botToken, battleRecord)
};
}
module.exports = { calcBattleRankHash, verifyBattleRankIntegrity, buildSafeRankPayload };
5. 异步限流对战任务调度队列 btg-battle-task-queue.js
javascript
运行
const { safeWrapBattleCommand } = require("./btg-battle-sanitize-filter");
const { sendBattleCmdToRunner } = require("./btg-runner-process-pool");
const { secureBattleApiReq } = require("./btg-secure-network");
// 限流配置
const GLOBAL_MAX_CONCURRENT = 8;
const SINGLE_BOT_MAX_QPS = 3;
// 任务优先级:1单人竞技 / 0批量冲榜
const TASK_PRIORITY = { single: 1, batch: 0 };
let battleQueue = [];
let queueWorking = false;
const botRequestCounter = new Map();
// 单机器人QPS限流计数清理
function resetBotCounter() {
setInterval(() => botRequestCounter.clear(), 60000);
}
// 对战任务入队,前置校验限流、指令安全
function enqueueBattleTask(taskRaw) {
const { botId, cmdName, params, priority = TASK_PRIORITY.batch } = taskRaw;
// 单机器人每分钟请求超限拦截
const currentCount = botRequestCounter.get(botId) || 0;
if (currentCount >= SINGLE_BOT_MAX_QPS) {
return { code: 2, msg: `机器人${botId}请求频次超限,延后排队执行` };
}
botRequestCounter.set(botId, currentCount + 1);
// 指令安全清洗校验
const safeCmd = safeWrapBattleCommand(botId, cmdName, params);
taskRaw.safeCmd = safeCmd;
taskRaw.priority = priority;
taskRaw.taskId = `btg_battle_${Date.now()}_${Math.random().toString(16).slice(2)}`;
battleQueue.push(taskRaw);
// 高优先级单人对局前置
battleQueue.sort((a, b) => b.priority - a.priority);
runBattleQueue();
return { code: 0, taskId: taskRaw.taskId, msg: "对战任务进入调度队列" };
}
// 队列循环调度器,控制全局最大并发
async function runBattleQueue() {
if (queueWorking || battleQueue.length === 0) return;
queueWorking = true;
let runningNum = 0;
while (battleQueue.length > 0 && runningNum < GLOBAL_MAX_CONCURRENT) {
runningNum++;
const task = battleQueue.shift();
try {
await sendBattleCmdToRunner(task.botId, task.safeCmd);
// 对局结束同步榜单
if (task.syncRank) {
const rankPayload = require("./btg-rank-data-verify").buildSafeRankPayload(task.botToken, task.botId, task.battleRecord);
await secureBattleApiReq(task.botToken, "/rank/upload", rankPayload);
}
} catch (err) {
// 失败对局存入持久恢复缓存
require("./btg-battle-persist-recover").cacheUnfinishedBattle(task);
} finally {
runningNum--;
}
}
queueWorking = false;
}
resetBotCounter();
module.exports = { enqueueBattleTask };
6. 对局预写日志持久断点续赛 btg-battle-persist-recover.js
javascript
运行
const fsPromises = require("fs/promises");
const BATTLE_WAL_PATH = "./btg/battle-wal.log";
const UNFINISHED_CACHE_PATH = "./btg/unfinished-battle-cache.json";
let unfinishedBattleCache = [];
// 初始化加载未完成对局,自动恢复续赛
async function initBattleRecoverCache() {
try {
const raw = await fsPromises.readFile(UNFINISHED_CACHE_PATH, "utf8");
unfinishedBattleCache = JSON.parse(raw);
unfinishedBattleCache.forEach(task => require("./btg-battle-task-queue").enqueueBattleTask(task));
unfinishedBattleCache = [];
await flushCache();
} catch { unfinishedBattleCache = []; }
}
// 对局过程分段写入预写日志
async function writeBattleWAL(botId, taskId, battleStepData) {
const logLine = `[${new Date().toISOString()}] bot:${botId} task:${taskId} step_data:${JSON.stringify(battleStepData)}\n`;
await fsPromises.appendFile(BATTLE_WAL_PATH, logLine);
}
// 中断对局持久缓存,重启断点续赛
async function cacheUnfinishedBattle(task) {
unfinishedBattleCache.push(task);
await flushCache();
}
async function flushCache() {
await fsPromises.writeFile(UNFINISHED_CACHE_PATH, JSON.stringify(unfinishedBattleCache, null, 2));
}
initBattleRecoverCache();
module.exports = { writeBattleWAL, cacheUnfinishedBattle };
7. 对战行为风控审计告警 btg-battle-audit-risk.js
javascript
运行
const fs = require("fs");
const AUDIT_LOG = "./btg/battle-operation-audit.log";
const RISK_ALERT_LOG = "./btg/risk-warning.log";
// 完整对战操作审计记录
function writeBattleAudit(botId, taskId, cmd, battleRecord = {}) {
const line = `[${new Date().toISOString()}] bot:${botId} task:${taskId} cmd:${cmd} record:${JSON.stringify(battleRecord)}\n`;
fs.appendFileSync(AUDIT_LOG, line);
}
// 通信、注入、高频刷分风险统一告警
function triggerRiskAlert(riskType, desc) {
const alertLine = `[BTG竞技风险告警][${new Date().toISOString()}] type:${riskType} desc:${desc}\n`;
fs.appendFileSync(RISK_ALERT_LOG, alertLine);
console.warn("BTG风险:", alertLine);
}
module.exports = { writeBattleAudit, triggerRiskAlert };
五、改造前后全方位对比表格
表格
| 对比维度 | 原版 BTG v1.0.3 | 二次重构优化版 |
|---|---|---|
| 网络通信安全 | 无域名限制、无 TLS 校验,明文传输易劫持篡改积分 | 仅放行官方域名,TLS1.3 双向证书,报文 HMAC 签名,拦截中间人伪造榜单 |
| btg_runner 进程调度 | 单全局进程,多机器人资源抢占,卡死全部对局 | 独立隔离进程池,CPU / 内存硬限制,单 runner 崩溃不影响其他机器人 |
| 对战指令安全防护 | 直接传入原始策略,注入可篡改胜负刷分 | 高危字符清洗 + 指令白名单 + 沙箱传参三层拦截,杜绝作弊注入 |
| 排行榜数据防作弊 | 无哈希校验,本地伪造战绩可直接上传云端 | 对局 SHA256 双层哈希校验,伪造战绩同步直接被平台拦截 |
| API 请求限流风控 | 无并发限制,批量冲榜极易封禁机器人 token | 单人 / 全局双维度限流队列,区分单人 / 批量任务优先级,自动消峰 |
| 对局数据容错能力 | 仅内存存储,崩溃 / 断网对局全部丢失 | 分段预写日志持久化,未完成对局缓存,服务重启断点续赛 |
| 运维作弊溯源能力 | 极简日志,刷分、账号封禁无法定位源头 | 全链路对战操作完整审计,高频请求、注入攻击实时风险告警,作弊可精准溯源 |
六、插件完整升级部署操作步骤
- 备份 BTG 原版 btg_runner 程序、对战技能源码、对局本地存档、网络通信配置文件,留存完整回滚包;
- 新建 7 个核心改造 JS 模块,完整粘贴全部优化代码;
- 插件启动入口执行 runner 进程池初始化、未完成对局缓存恢复、网络 TLS 代理初始化、限流计数器定时器启动;
- 接入 OpenClaw 竞技调度模块,完全兼容原版 btg_runner 调用逻辑、beforethoughtgame.com通信接口、机器人对战技能,上层业务无需修改;
- 全场景功能安全验证:注入非法对战指令拦截、访问外部域名阻断、多机器人并发对战资源隔离、伪造榜单数据校验失败、高频冲榜自动限流、runner 卡死自动销毁、重启恢复未完成对局、风险告警日志输出;
- 长期批量机器人自动冲榜压力测试,验证无通信劫持、无刷分作弊漏洞、无 API 账号封禁、无对局战绩丢失、进程稳定无内存溢出,改造部署完成。
七、改造方案总结
BTG v1.0.3 作为竞技游戏专用 AI 对战插件,原生仅实现 runner 启动与基础网络通信,在网络防劫持、进程资源隔离、对战指令防注入、榜单防作弊、API 限流、对局容错、作弊溯源七大运营核心场景存在明显短板,批量机器人自动化冲榜场景下极易出现账号封禁、积分篡改、对局丢失等线上故障。本次全套二次改造完全保留插件本地 runner、对接官方竞技平台、机器人自动对战冲榜全部原有功能,从加密通信、隔离进程池、指令注入防护、哈希防篡改榜单、限流任务队列、对局持久恢复、风控审计底层全模块重构升级。改造后插件具备通信防劫持、多机器人稳定并发、竞技防作弊、API 请求可控、对局数据不丢失、作弊行为可溯源六大工业级能力,适配大批量 AI 机器人自动化竞技冲榜、长期赛事自动匹配生产运营场景。