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,全部通过。
这个提交包含在:
+76
-3
@@ -85,7 +85,7 @@ html, body {
|
||||
/* ==================== 布局 ==================== */
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: 300px minmax(420px, 1fr) 360px;
|
||||
grid-template-columns: 320px minmax(460px, 1fr) 380px;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
align-items: start;
|
||||
@@ -140,7 +140,7 @@ html, body {
|
||||
.card-map { display: flex; flex-direction: column; }
|
||||
#mapCanvas {
|
||||
width: 100%;
|
||||
height: 380px;
|
||||
height: 440px;
|
||||
background: #05070a;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
@@ -163,13 +163,86 @@ html, body {
|
||||
.sw-target { background: #d29922; }
|
||||
.sw-player { background: #ffffff; }
|
||||
.sw-capital { background: #bc8cff; }
|
||||
.sw-bot { background: #ffd33d; }
|
||||
|
||||
.chk { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); cursor: pointer; }
|
||||
.hidden { display: none !important; }
|
||||
.inline-field { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
|
||||
.input-sm { width: auto; min-width: 110px; padding: 4px 8px; font-size: 12px; }
|
||||
.tabs-inline { margin-bottom: 0; }
|
||||
.error-text { color: var(--red); }
|
||||
|
||||
/* ==================== 机器人列表 ==================== */
|
||||
.bot-list { display: flex; flex-direction: column; gap: 6px; }
|
||||
.bot-item {
|
||||
display: grid;
|
||||
grid-template-columns: 10px 1fr auto;
|
||||
gap: 8px; align-items: center;
|
||||
padding: 7px 9px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
background: var(--panel-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
.bot-item:hover { border-color: #48505e; }
|
||||
.bot-item.active { border-color: var(--accent-2); box-shadow: 0 0 0 1px rgba(47,129,247,.35); }
|
||||
.bot-item .dot {
|
||||
width: 9px; height: 9px; border-radius: 50%; background: var(--muted);
|
||||
}
|
||||
.bot-item .dot.online { background: var(--green); }
|
||||
.bot-item .dot.connecting { background: var(--yellow); }
|
||||
.bot-item .dot.offline { background: var(--red); }
|
||||
.bot-item .dot.disabled { background: #484f58; }
|
||||
.bot-item .name { font-size: 13px; }
|
||||
.bot-item .sub { font-size: 11px; color: var(--muted); }
|
||||
.bot-item .meta { font-size: 11px; color: var(--muted); text-align: right; white-space: nowrap; }
|
||||
|
||||
/* ==================== 公屏聊天 ==================== */
|
||||
.chat-line { display: block; }
|
||||
.chat-time { color: #586069; margin-right: 6px; }
|
||||
.chat-bot { color: var(--accent-2); margin-right: 4px; }
|
||||
.chat-user { color: var(--purple); margin-right: 4px; }
|
||||
.chat-out { color: var(--green); }
|
||||
.chat-command { color: var(--yellow); }
|
||||
.chat-system { color: var(--muted); }
|
||||
.chat-action { color: #6e7681; }
|
||||
|
||||
/* ==================== 开拓日志 ==================== */
|
||||
#expView { white-space: normal; padding: 0; }
|
||||
.exp-table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
||||
.exp-table th {
|
||||
position: sticky; top: 0;
|
||||
text-align: left; color: var(--muted); font-weight: 500;
|
||||
background: #05070a; padding: 4px 6px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.exp-table td { padding: 3px 6px; border-bottom: 1px solid #12161d; white-space: nowrap; }
|
||||
.exp-table tbody tr:hover { background: #0e131a; }
|
||||
.exp-empty { color: var(--muted); }
|
||||
|
||||
.config-scope { margin-bottom: 8px; }
|
||||
|
||||
/* ==================== 登录遮罩 ==================== */
|
||||
.overlay {
|
||||
position: fixed; inset: 0; z-index: 200;
|
||||
display: grid; place-items: center;
|
||||
background: rgba(5, 7, 10, .78);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
.overlay-box {
|
||||
width: min(360px, 92vw);
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 18px;
|
||||
}
|
||||
.overlay-box h2 { font-size: 15px; margin: 0 0 6px; }
|
||||
.overlay-box .input { margin: 10px 0; }
|
||||
|
||||
/* ==================== 日志 ==================== */
|
||||
.card-log { display: flex; flex-direction: column; }
|
||||
.log-view {
|
||||
height: 260px;
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
background: #05070a;
|
||||
border: 1px solid var(--border);
|
||||
|
||||
在新工单中引用
屏蔽一个用户