feat: 大地图跟随机器人并支持可调图幅,新增定时消息,控制台界面重做并适配移动端

大地图跟随机器人 + 可调图幅
- 爬取与显示区域改为以机器人当前位置为中心(bigMap.followBot 默认开启),
  不再傻傻地爬世界原点周边
- 界面新增「图幅」下拉(±512/1024/2048/4096/8192/全世界)与「爬取周边」按钮,
  只爬当前图幅内的瓦片:层级 0 每张覆盖 4096 格,±4096 只需 9 张,全世界要 100 张
- POST /api/bigmap/crawl 支持 centerX/centerZ/rangeBlocks;GET /api/bigmap 支持
  rangeBlocks/bot 查询参数;启动预爬取会先等机器人进入世界再以其位置为中心

领土地图以机器人所在邦国为中心
- 之前初始视图用的是控制器的 playerChunk,而任务启动前它是 (0,0),
  导致地图永远停在世界原点附近。现在按「机器人所在区块 → 包含它的邦国 →
  该邦国王城/外接矩形」定位

定时重复发送消息(src/bot/scheduledMessenger.js)
- 每个机器人可配多条定时任务,按固定间隔重复发送同一内容,如每 300 秒 /u restore confirm
- 以 / 开头按游戏指令发送,否则按公屏消息发送
- 只在已连接且通过登录验证时发送;未就绪的周期顺延且不补发,避免重连后一次性连发
- 与指令节流队列共用,间隔下限 5 秒、单机器人最多 20 条
- 控制台新增「定时消息」卡片(新增/删除/启停 + 剩余秒数倒计时)

控制台界面重做 + 移动端适配
- 重新设计的深色主题:统一圆角、阴影、焦点态与悬停态,卡片式分层
- 响应式三档:≥1200px 三栏;≤1200px 两栏;≤820px 单栏 + 底部导航
- 移动端:触控目标 ≥36px、地图/日志高度按视口自适应、避让底部安全区、
  横屏压矮地图、尊重「减少动效」偏好、Toast 全宽
- 「添加玩家」折叠进 details;顶栏窄屏自动换行且按钮等分

修复
- POST /api/bigmap/crawl 响应把中心与图幅字段传错(实际爬取正确,返回值显示成原点)
- 定时任务保存后接口返回原始列表而非归一化结果,前端拿不到剩余秒数

测试 308 -> 325,全部通过。
这个提交包含在:
lyizai
2026-09-28 00:27:58 +08:00
父节点 fcd5fb2bd9
当前提交 a83dea9677
共修改 14 个文件,包含 1579 行新增和 343 行删除
+61 -11
查看文件
@@ -437,13 +437,59 @@ npm start
打开控制台后:
- **顶栏**:机器人下拉选择、连接 / 任务徽标、控制台登录状态、开始扩地 / 停止 / 重连
- **左栏**:机器人列表(状态 / 坐标 / 任务 / 已开拓数)、连接、任务、领土数据源、Grim 合规
- **左栏**:机器人列表、连接、任务、**定时消息**、领土数据源、Grim 合规
- **中栏**:
- 地图页签 —— **大地图**(瓦片 + 领土多边形 + 全部机器人坐标)与 **领土地图**(区块级)
- 日志页签 —— **运行日志** / **公屏聊天** / **开拓日志**
- **右栏**:8 个标签页的配置表单(可切换「仅对当前机器人生效」)+ 控制台 / 聊天框
- **右栏**:控制台 / 聊天框(含移动测试)+ 8 个标签页的配置表单
地图图层:己方领土(蓝)、本次占领(绿)、飞地疏漏(红)、当前目标(黄)、机器人(白点 / 黄点)、王城(紫)。
### 响应式与移动端
| 宽度 | 布局 |
| --- | --- |
| ≥1200px | 三栏(状态 / 地图日志 / 配置) |
| ≤1200px | 两栏,配置栏落到下方并自动分列 |
| ≤820px | 单栏 + 底部导航(状态 / 地图 / 日志 / 配置一键定位) |
移动端额外处理:触控目标放大到 ≥36px、地图与日志高度按视口自适应、
避让底部安全区(`env(safe-area-inset-bottom)`)、横屏时压矮地图高度、
尊重系统「减少动效」偏好。
### 定时重复发送消息
挂机时常需要周期性发同一条指令(例如每 300 秒 `/u restore confirm` 维持疆土民心)。
左栏「定时消息」卡片里点「+ 新增」,填内容与间隔即可;以 `/` 开头按游戏指令发送,否则按公屏消息发送。
实现上刻意**不用**朴素的 `setInterval`:
- 只在「已连接 + 已通过登录验证」时才发送;
- 未就绪的周期直接顺延,**不补发** —— 否则重连后会把漏掉的几条一次性连发出去;
- 与指令节流队列共用,不会绕过 `server.commandCooldownMs` 变成刷屏;
- 间隔下限 5 秒、单个机器人最多 20 条,防止误配置把账号玩进黑名单。
---
## 大地图
`src/core/bigMapService.js` 爬取服务器地图站点(本项目部署的是
[squaremap](https://github.com/jpenilla/squaremap))的瓦片图片与领土标记,
把所有机器人画在同一张图上。
### 以机器人为中心 + 可调图幅
大地图的用途是看**自己机器人周边**,所以默认以机器人当前位置为中心(`bigMap.followBot`)。
界面上的「图幅」下拉框决定半径:
| 图幅 | 层级 0 需要的瓦片数 |
| --- | --- |
| ±512 格 | 1 |
| ±1024 格 | 1~4 |
| ±4096 格(默认) | 9 |
| ±8192 格 | 25 |
| 全世界(±20480) | 100 |
层级 0 每张瓦片覆盖 4096 格,所以「只看周边」比「拉全世界」省一到两个数量级。
点「爬取周边」只会爬当前图幅内的瓦片;「回到机器人」把视图拉回机器人所在位置。
### REST / WebSocket 接口
@@ -456,6 +502,8 @@ npm start
| GET | `/api/bots/:id/status` | 单个机器人状态 |
| GET | `/api/bots/:id/settings` | 单个机器人的设置与生效配置 |
| POST | `/api/bots/:id/settings` | 保存备注名 / 启用 / 自动开始 / 配置覆盖 |
| GET | `/api/bots/:id/schedules` | 该机器人的定时消息列表(含距下次发送的秒数) |
| POST | `/api/bots/:id/schedules` | 整体替换该机器人的定时消息列表 |
| POST | `/api/bots/:id/task/start` | 启动该机器人的扩地(body 为配置覆盖) |
| POST | `/api/bots/:id/task/stop` | 停止该机器人的扩地 |
| POST | `/api/bots/:id/reconnect` | 重连该机器人 |
@@ -469,10 +517,10 @@ npm start
| GET | `/api/expansion-log` | 开拓日志(`limit` / `botId` / `state` / `since`)+ 统计 |
| POST | `/api/expansion-log/export` | 导出开拓日志 CSV 到 `data/` |
| POST | `/api/expansion-log/clear` | 清空内存中的开拓日志(磁盘保留) |
| GET | `/api/bigmap` | 大地图元信息(坐标系、瓦片范围、缓存进度、机器人坐标、领土标记) |
| GET | `/api/bigmap` | 大地图元信息(坐标系、图幅、瓦片范围、缓存进度、机器人坐标、领土标记);支持 `rangeBlocks` / `bot` 参数 |
| GET | `/api/bigmap/markers` | 大地图领土标记(多边形 + 王城) |
| GET | `/api/bigmap/tile/:z/:x/:y` | 瓦片代理(缓存优先,避免跨域) |
| POST | `/api/bigmap/crawl` | 手动触发批量爬取瓦片 |
| POST | `/api/bigmap/crawl` | 爬取瓦片;默认爬机器人周边,支持 `centerX` / `centerZ` / `rangeBlocks` |
| POST | `/api/bigmap/cache/clear` | 清空瓦片缓存 |
| GET | `/api/config` | 全局配置 |
| POST | `/api/config` | 保存并立即应用全局配置 |
@@ -499,8 +547,8 @@ npm start
| 寻路 | 疾跑 / 游泳 / 跳跃 / 挖方块 / 放方块、高度偏好、跑酷、搭塔、下落高度、液体代价 |
| 生存 | 自动进食、自动攻击、耐久保护、战斗筛选、水域策略、自动用船 |
| 数据 | 地图刷新间隔、SimpCore API |
| 大地图 | 开关、世界名、预爬取层级、最大层级、覆盖半径、启动预爬取、下载并发数 |
| Grim | 合规层全部阈值(见上) |
| 大地图 | 开关、世界名、预爬取层级、最大层级、**图幅半径、是否跟随机器人**、启动预爬取、下载并发数 |
| Grim | 合规层全部阈值 + 协议补包开关(见上) |
| 服务器 | 开垦模式指令、登录 / 注册模板、登录确认超时、指令节流、重连 |
---
@@ -534,9 +582,10 @@ npm run dev # 文件变更自动重启
确认兜底超时、公屏消息类型映射
- 开拓日志:字段记录、筛选、统计、JSONL 落盘与重启恢复、损坏行容错、环形缓冲、CSV 导出
- 公屏日志:按机器人隔离、类型 / 关键字过滤、分文件落盘、文件名安全化、文本导出
- 大地图:坐标系换算(含对源站实测标定的王城用例)、瓦片范围、缓存命中、批量爬取、缓存清理
- Web 控制台:地图负载、单 / 多机器人接口、聊天与开拓日志接口、瓦片代理、
令牌与登录鉴权、WebSocket 握手鉴权
- 大地图:坐标系换算(含对源站实测标定的王城用例)、**以机器人为中心的图幅换算**、瓦片范围、缓存命中、批量爬取、缓存清理
- 定时消息:内容归一化与间隔钳制、到点发送与按周期重复、未就绪时顺延不补发、多任务独立计时、整体替换重置计时
- Web 控制台:地图负载、单 / 多机器人接口、聊天与开拓日志接口、定时任务接口、
图幅与中心计算、瓦片代理、令牌与登录鉴权、WebSocket 握手鉴权
### 目录结构
@@ -561,7 +610,8 @@ src/
├── bot/
│ ├── botPool.js ★ 机器人池:同时挂多个玩家
│ ├── botManager.js 连接、登录验证、公屏留档、指令 / 聊天发送
│ ├── grimCompat.js ★ Grim 反作弊合规层
│ ├── scheduledMessenger.js ★ 定时重复发送消息 / 指令
│ ├── grimCompat.js ★ Grim 反作弊合规层 + 协议补包(player_input / tick_end)
│ ├── pathingService.js 寻路服务(替代 Baritone)
│ ├── autoCombat.js 战斗筛选与耐久检查
│ ├── autoEat.js 自动进食