feat: 支持多机器人挂机、开拓日志、公屏完整日志与大地图
多机器人(src/bot/botPool.js、src/config/botsConfig.js) - .env 用 MC_BOTS 一次配置多个账号(JSON 数组或 用户名:密码 逗号分隔),未配置时回退单机器人 - 每个机器人独立连接 / 登录 / 扩地状态机,共享一份领土数据服务与运行日志 - 密码只从 .env 读取;data/bots.json 只存启用状态、备注名、自动开始与各自的配置覆盖 - 每个机器人可覆盖全局配置(策略 / 目标邦国 / 目标数量等),未覆盖字段回退全局默认 开拓日志(src/core/expansionLog.js) - 逐条记录开拓玩家、邦国、区块、方块坐标、时间与判定来源,追加写入 data/expansion-log.jsonl - 支持按机器人 / 邦国 / 时间筛选、统计、导出带 BOM 的 CSV,超过 16MB 自动轮转 游戏公屏完整日志与聊天框(src/core/chatLog.js) - 每个机器人的全部公屏 / 系统 / 动作栏消息按机器人分文件留档,自身发出的聊天与指令同样留档 - 控制台新增公屏聊天页签与消息发送框 登录验证门禁 - 游戏侧:未完成登录验证时拒绝发送指令 / 聊天,isReady() 也不放行扩地任务; 新增 server.loginConfirmTimeoutMs 兜底,避免服务器不回提示导致永远卡在未登录 - 控制台侧:新增 WEB_PASSWORD 与 /api/login、/api/session,页面登录框验证通过才允许操作 大地图(src/core/bigMapService.js) - 爬取服务器地图站点(squaremap)的瓦片图片与领土标记,一张图上看全部机器人坐标 - 坐标系对源站实测标定并用 27 个王城交叉验证;瓦片磁盘缓存,层级 0 启动预爬取、更高层级按需穿透 - 领土按 markers.json 原始多边形绘制(预编译 Path2D,even-odd 保留孔洞),叠加王城与机器人标签 配套改造 - TerritoryModel 新增 flyingChunksOf / ownChunksOf,邦国归属改为按名称显式传入, 不再依赖全局 selfStateName(多机器人会互相覆盖) - Web 接口以 /api/bots/:id/... 为主,原单机器人接口保留为默认机器人的等价别名 - 新增 scripts/check-web-ids.js 校验前端元素引用一致性 测试从 154 增至 242,全部通过。
这个提交包含在:
+114
-15
@@ -12,12 +12,17 @@
|
||||
<span class="logo">AS</span>
|
||||
<div>
|
||||
<h1>AutoStore Bot</h1>
|
||||
<p>Minecraft 自动扩地机器人 · mineflayer · Grim 合规</p>
|
||||
<p>多机器人自动扩地 · mineflayer · Grim 合规 · 大地图</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topbar-right">
|
||||
<label class="inline-field">
|
||||
当前机器人
|
||||
<select id="botSelect" class="input input-sm"></select>
|
||||
</label>
|
||||
<span id="connBadge" class="badge badge-offline">未连接</span>
|
||||
<span id="taskBadge" class="badge badge-idle">空闲</span>
|
||||
<span id="authBadge" class="badge badge-idle" title="控制台登录状态">未登录</span>
|
||||
<button id="btnStart" class="btn btn-primary">开始扩地</button>
|
||||
<button id="btnStop" class="btn btn-danger">停止</button>
|
||||
<button id="btnReconnect" class="btn">重连</button>
|
||||
@@ -27,6 +32,17 @@
|
||||
<main class="layout">
|
||||
<!-- ==================== 左栏:状态面板 ==================== -->
|
||||
<section class="column col-left">
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h2>机器人(<span id="botCount">0</span>)</h2>
|
||||
<div class="row">
|
||||
<button id="btnStartAll" class="btn btn-sm">全部开始</button>
|
||||
<button id="btnStopAll" class="btn btn-sm">全部停止</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="botList" class="bot-list"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>连接</h2>
|
||||
<dl class="kv">
|
||||
@@ -37,8 +53,14 @@
|
||||
<dt>所在区块</dt><dd id="kChunk">-</dd>
|
||||
<dt>生命 / 饥饿</dt><dd id="kHealth">-</dd>
|
||||
<dt>状态</dt><dd id="kBotState">-</dd>
|
||||
<dt>登录验证</dt><dd id="kLogin">-</dd>
|
||||
<dt>重连次数</dt><dd id="kReconnect">0</dd>
|
||||
</dl>
|
||||
<div class="row">
|
||||
<label class="chk"><input type="checkbox" id="chkEnabled"> 启用该机器人</label>
|
||||
<label class="chk"><input type="checkbox" id="chkAutoStart"> 启动后自动扩地</label>
|
||||
<button id="btnSaveBotSetting" class="btn btn-sm">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
@@ -46,6 +68,7 @@
|
||||
<dl class="kv">
|
||||
<dt>状态机</dt><dd id="kTaskState">IDLE</dd>
|
||||
<dt>描述</dt><dd id="kTaskStatus">未启动</dd>
|
||||
<dt>开拓邦国</dt><dd id="kTaskStateName">-</dd>
|
||||
<dt>当前目标</dt><dd id="kTarget">-</dd>
|
||||
<dt>队列</dt><dd id="kQueue">0</dd>
|
||||
<dt>已完成</dt><dd id="kCompleted">0</dd>
|
||||
@@ -90,12 +113,22 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ==================== 中栏:地图 ==================== -->
|
||||
<!-- ==================== 中栏:地图与日志 ==================== -->
|
||||
<section class="column col-center">
|
||||
<div class="card card-map">
|
||||
<div class="card-head">
|
||||
<h2>领土地图</h2>
|
||||
<div class="row">
|
||||
<div class="tabs tabs-inline" id="mapTabs">
|
||||
<button class="tab active" data-view="big">大地图</button>
|
||||
<button class="tab" data-view="territory">领土地图</button>
|
||||
</div>
|
||||
<div class="row" id="bigMapControls">
|
||||
<label class="chk"><input type="checkbox" id="chkTerritory" checked> 领土标记</label>
|
||||
<label class="chk"><input type="checkbox" id="chkBotLabels" checked> 机器人名字</label>
|
||||
<button id="btnMapFitWorld" class="btn btn-sm">全世界</button>
|
||||
<button id="btnMapCenterBots" class="btn btn-sm">回到机器人</button>
|
||||
<button id="btnCrawlMap" class="btn btn-sm">爬取地图</button>
|
||||
</div>
|
||||
<div class="row hidden" id="territoryMapControls">
|
||||
<label class="chk"><input type="checkbox" id="chkFull" checked> 显示全部邦国</label>
|
||||
<label class="chk"><input type="checkbox" id="chkFlying" checked> 标出飞地</label>
|
||||
<label class="chk"><input type="checkbox" id="chkGrid" checked> 网格</label>
|
||||
@@ -105,30 +138,65 @@
|
||||
</div>
|
||||
<canvas id="mapCanvas"></canvas>
|
||||
<div class="map-legend">
|
||||
<span><i class="sw sw-self"></i>己方领土</span>
|
||||
<span><i class="sw sw-session"></i>本次占领</span>
|
||||
<span><i class="sw sw-flying"></i>飞地(疏漏)</span>
|
||||
<span><i class="sw sw-target"></i>当前目标</span>
|
||||
<span><i class="sw sw-player"></i>机器人</span>
|
||||
<span><i class="sw sw-capital"></i>王城</span>
|
||||
<span id="legendBig">
|
||||
<i class="sw sw-self"></i>己方领土
|
||||
<i class="sw sw-session"></i>本次占领
|
||||
<i class="sw sw-capital"></i>王城
|
||||
<i class="sw sw-bot"></i>机器人
|
||||
</span>
|
||||
<span id="legendTerritory" class="hidden">
|
||||
<i class="sw sw-self"></i>己方领土
|
||||
<i class="sw sw-session"></i>本次占领
|
||||
<i class="sw sw-flying"></i>飞地(疏漏)
|
||||
<i class="sw sw-target"></i>当前目标
|
||||
<i class="sw sw-player"></i>机器人
|
||||
<i class="sw sw-capital"></i>王城
|
||||
</span>
|
||||
<span id="mapInfo" class="mono small"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-log">
|
||||
<div class="card-head">
|
||||
<h2>运行日志</h2>
|
||||
<div class="row">
|
||||
<div class="tabs tabs-inline" id="logTabs">
|
||||
<button class="tab active" data-pane="log">运行日志</button>
|
||||
<button class="tab" data-pane="chat">公屏聊天</button>
|
||||
<button class="tab" data-pane="exp">开拓日志</button>
|
||||
</div>
|
||||
<div class="row" id="logControls">
|
||||
<label class="chk"><input type="checkbox" id="chkAutoScroll" checked> 自动滚动</label>
|
||||
<button id="btnClearLog" class="btn btn-sm">清屏</button>
|
||||
<button id="btnExportLog" class="btn btn-sm">导出日志</button>
|
||||
</div>
|
||||
<div class="row hidden" id="chatControls">
|
||||
<label class="chk"><input type="checkbox" id="chkChatAutoScroll" checked> 自动滚动</label>
|
||||
<label class="chk"><input type="checkbox" id="chkChatAllBots"> 全部机器人</label>
|
||||
<button id="btnClearChat" class="btn btn-sm">清屏</button>
|
||||
<button id="btnExportChat" class="btn btn-sm">导出公屏日志</button>
|
||||
</div>
|
||||
<div class="row hidden" id="expControls">
|
||||
<label class="chk">机器人
|
||||
<select id="expFilterBot" class="input input-sm"><option value="">全部</option></select>
|
||||
</label>
|
||||
<label class="chk"><input type="checkbox" id="chkExpAutoScroll" checked> 自动滚动</label>
|
||||
<button id="btnExportExp" class="btn btn-sm">导出 CSV</button>
|
||||
<button id="btnClearExp" class="btn btn-sm">清屏</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="logView" class="log-view"></div>
|
||||
<div id="chatView" class="log-view hidden"></div>
|
||||
<div id="expView" class="log-view hidden">
|
||||
<table class="exp-table">
|
||||
<thead>
|
||||
<tr><th>时间</th><th>机器人</th><th>邦国</th><th>区块</th><th>方块坐标</th><th>来源</th></tr>
|
||||
</thead>
|
||||
<tbody id="expBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ==================== 右栏:配置 ==================== -->
|
||||
<!-- ==================== 右栏:配置与控制 ==================== -->
|
||||
<section class="column col-right">
|
||||
<div class="card card-config">
|
||||
<div class="card-head">
|
||||
@@ -138,12 +206,17 @@
|
||||
<button id="btnReloadConfig" class="btn btn-sm">重新载入</button>
|
||||
</div>
|
||||
</div>
|
||||
<label class="chk config-scope">
|
||||
<input type="checkbox" id="chkBotOverride">
|
||||
仅对当前机器人生效(不勾选则写入全局默认配置)
|
||||
</label>
|
||||
<div class="tabs" id="configTabs">
|
||||
<button class="tab active" data-tab="strategy">策略</button>
|
||||
<button class="tab" data-tab="timing">超时</button>
|
||||
<button class="tab" data-tab="pathing">寻路</button>
|
||||
<button class="tab" data-tab="survival">生存</button>
|
||||
<button class="tab" data-tab="data">数据</button>
|
||||
<button class="tab" data-tab="bigmap">大地图</button>
|
||||
<button class="tab" data-tab="grim">Grim</button>
|
||||
<button class="tab" data-tab="server">服务器</button>
|
||||
</div>
|
||||
@@ -151,9 +224,17 @@
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>手动指令</h2>
|
||||
<div class="card-head">
|
||||
<h2>控制台 / 聊天框</h2>
|
||||
<span class="mono small" id="consoleTarget">-</span>
|
||||
</div>
|
||||
<p class="hint" id="consoleHint">登录验证通过后可向该机器人发送指令或公屏消息。</p>
|
||||
<div class="row">
|
||||
<input id="cmdInput" class="input" type="text" placeholder="u claimmode(不带斜杠)">
|
||||
<select id="sendMode" class="input input-sm">
|
||||
<option value="chat">公屏聊天</option>
|
||||
<option value="command">游戏指令</option>
|
||||
</select>
|
||||
<input id="cmdInput" class="input" type="text" placeholder="输入内容后回车发送">
|
||||
<button id="btnSendCmd" class="btn btn-sm">发送</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -162,10 +243,28 @@
|
||||
<button class="btn btn-sm" data-cmd="spawn">/spawn</button>
|
||||
<button class="btn btn-sm" data-cmd="list">/list</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<input id="quickChatInput" class="input" type="text" placeholder="快捷公屏消息(如:大家好)">
|
||||
<button id="btnQuickChat" class="btn btn-sm">公屏发送</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- 登录遮罩:控制台配置了 WEB_TOKEN / WEB_PASSWORD 时显示 -->
|
||||
<div id="loginOverlay" class="overlay hidden">
|
||||
<div class="overlay-box">
|
||||
<h2>控制台登录</h2>
|
||||
<p class="hint">验证通过后才允许操作各机器人的控制台、聊天框与扩地任务。</p>
|
||||
<input id="loginPassword" class="input" type="password" placeholder="控制台密码 / 令牌" autocomplete="current-password">
|
||||
<div class="row">
|
||||
<button id="btnLogin" class="btn btn-primary">登录</button>
|
||||
<button id="btnLogout" class="btn btn-sm">退出登录</button>
|
||||
</div>
|
||||
<p id="loginError" class="hint error-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toast" class="toast"></div>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
|
||||
在新工单中引用
屏蔽一个用户