feat: 掉线重连后自动恢复扩地任务(autoResumeAfterReconnect)
本服会周期性把机器人踢下线(实测约 1~6 分钟一次,踢出原因是 "An internal error occurred in your connection"),每次都会走到「世界已退出,任务停止」。 原来的行为是就此停住 —— 机器人虽然能被原点自救送回真实世界(实测 4/4 成功), 却再也不会继续扩地,于是永远停在原地。 现在世界退出时把本次任务的配置记下来(resumeConfig), 重新进入世界后自动 start() 接上;状态文案改为「世界已退出,等待重连后自动恢复」, 并打印「已重新进入世界,自动恢复扩地任务」。 只有因世界退出而停的那次会登记:手动停止 / 到开垦时段外 / 耐久保护停机 都会在 stop() 里清空 resumeConfig,不会被重连重新拉起。 开关 autoResumeAfterReconnect 默认开启,可关。 测试 470 → 473。
这个提交包含在:
@@ -128,6 +128,15 @@ class ExpansionController {
|
||||
|
||||
/** 等待开拓时段自动开始:不在时段时点击开始会暂存配置(null 表示无等待任务) */
|
||||
this.pendingStart = null;
|
||||
/**
|
||||
* 被「世界退出」打断的任务配置:重连进入世界后用它自动恢复。
|
||||
*
|
||||
* 本服会周期性把机器人踢下线(实测约 1~6 分钟一次),而每次掉线都会走到
|
||||
* 「世界已退出,任务停止」。没有这个字段的话,机器人虽然能被原点自救送回
|
||||
* 真实世界,任务却再也不会继续 —— 扩地永远跑不长。
|
||||
* 手动停止 / 到时段外 / 耐久保护停机都不会写入它。
|
||||
*/
|
||||
this.resumeConfig = null;
|
||||
/** 连续寻路超时累计时长(毫秒) */
|
||||
this.consecutiveTimeoutMillis = 0;
|
||||
/** 发送回城指令的时间戳 */
|
||||
@@ -228,6 +237,8 @@ class ExpansionController {
|
||||
return false;
|
||||
}
|
||||
this.config = requestedConfig;
|
||||
// 显式启动的任务优先于「掉线待恢复」的那一次
|
||||
this.resumeConfig = null;
|
||||
// 现实时间限制:不在允许时段时登记「等待自动开始」,进入时段后由 tick() 自动启动
|
||||
if (!this.isWithinClaimTime()) {
|
||||
this.pendingStart = requestedConfig;
|
||||
@@ -308,6 +319,8 @@ class ExpansionController {
|
||||
/** 手动停止任务 */
|
||||
stop() {
|
||||
const bm = this.botManager;
|
||||
// 任何显式停止都作废「掉线待恢复」——只有 tick() 里因世界退出而停的那次会重新登记
|
||||
this.resumeConfig = null;
|
||||
if (this.pendingStart) {
|
||||
this.pendingStart = null;
|
||||
this.setState(State.IDLE, '已取消自动开始');
|
||||
@@ -335,11 +348,26 @@ class ExpansionController {
|
||||
if (!this.config) return; // 尚未启动过任务,没有可驱动的状态
|
||||
if (!bm.isSpawned()) {
|
||||
if (this.isRunning()) {
|
||||
// 先记下这次任务的配置:本服会周期性把机器人踢下线,重连回来时若没人管,
|
||||
// 任务就永远停在这里。stop() 会清空 resumeConfig,所以要在它之后重新登记。
|
||||
const interrupted = this.config;
|
||||
this.stop();
|
||||
this.status = '世界已退出,任务停止';
|
||||
this.status = '世界已退出,等待重连后自动恢复';
|
||||
if (interrupted && interrupted.autoResumeAfterReconnect !== false) {
|
||||
this.resumeConfig = interrupted;
|
||||
this._log('世界已退出,任务已暂停;重新进入世界后会自动恢复');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 重新进入世界:把被掉线打断的任务接上
|
||||
if (this.resumeConfig && !this.isRunning()) {
|
||||
const resume = this.resumeConfig;
|
||||
this.resumeConfig = null;
|
||||
this._log('已重新进入世界,自动恢复扩地任务');
|
||||
this.start(resume).catch((err) => this._log('自动恢复任务失败:' + err.message, 'error'));
|
||||
return;
|
||||
}
|
||||
this.playerChunk = this._playerChunk();
|
||||
// 续租当前目标:长距离寻路可能要走几分钟,不能让租约中途过期被别人抢走
|
||||
if (this.isRunning()) this._renewTargetLease();
|
||||
|
||||
在新工单中引用
屏蔽一个用户