feat(engine): 四座自动化设施——喷灌 / 收割机 / 售货机 / 磨坊

为什么:自动化建筑只有水井和喂食器,中期以后每天的操作只剩浇水喂食
的重复劳动。新设施把"替代行动点动作"的思路推到完整流水线:
浇水(井/喷灌)→ 收割机收熟地 → 磨坊把陈粮变饲料 → 喂食器喂牲口
→ 售货机趁高价清库存,人不在也能持续产出。

- config.BUILDINGS 注册 4 座:喷灌系统 2800 金(全量浇水)、
  自动收割机 900 金 ×3(每天各收 2 块熟地,刻意不给经验——机器收的
  不算劳动,给手动玩法留价值)、自动售货机 1200 金(市价 > 基准价才
  出手、每天上限 5 份、越贵越先卖)、饲料磨坊 500 金(1 份最便宜的
  作物磨 3 份饲料)。
- engine._run_buildings 扩成六段流水线,顺序即依赖:磨坊排在喂食器前,
  早上磨的饲料当天就能喂上;收割机遇满仓停摆、作物留地(同喂食器
  缺料停摆哲学——自动系统绝不硬来,更绝不自动花钱)。
- webui / build 动作 / catalog 全部由 config.BUILDINGS 驱动,零改动。
- 测试 +6(喷灌全量浇水、收割入库且无经验、满仓停摆留作物、磨坊挑
  最便宜、磨坊→喂食器同日链路、售货机阈值与配额)。修复断言时确认
  两个既有行为:引擎自带 START_FEED=5;advance_day 末尾会把动物 fed
  复位("喂到了"的证据是 pending 累计而非 fed 本身)。
- 门禁:534 项 OK(skip 39)、ruff/pyright 全绿。
This commit is contained in:
snowy-yang committed 2026-09-25 21:05:27 +08:00
1 parent 2676927c1a
commit cb4c1e7800
7 files changed
+332 -10

No files matched your search

+32
View File
@@ -57,3 +57,35 @@
- 教训:幂等补丁脚本里 `new == ""` 时 `if new in text` 恒真,会误报 ALREADY
跳过删除类替换(这次是删全局 Enter 监听那行,靠核对输出抓回来)。
删除类编辑别走补丁脚本,直接用 Edit 工具。
## 2026-09-23(晚)「种不了东西」:中文用户名 + X-Farm-Id 头
- 用户报种不了东西。API 直发 plant 全正常、页面代码静态看着也正常,
最后用 headless Chrome(本机 Chrome + `--cdp 9333` 连接模式)真机复现:
登录"阳"后点播种→选小麦,toast 不变、地块不变,act() 抛
`TypeError: Failed to execute 'fetch': String contains non ISO-8859-1 code point`。
- **根因**:`headers()` 把用户名塞进 `X-Farm-Id` 头,HTTP 头只允许 Latin-1,
中文用户名让 fetch 在发送前就抛异常。登录时 me=null(头是 ASCII 的
default)所以能登录成功,**登录后所有走 api() 的写操作全部静默失败**
(Promise 拒绝无人接住);页面靠 SSE 照常渲染,看起来一切正常。
- 修复(webui.py,幂等补丁 6 处全中):headers() 非 ASCII 值不塞头
(登录态走 Cookie,头只是匿名脚本备用通道);api() 捕获 fetch 异常并
toast,杜绝静默失败;localStorage 裸调用加 try/catch(sandbox iframe
无 allow-same-origin 时访问即抛,启动段有三处裸调用会炸掉整个脚本)。
- 真机回归:登录阳→点播种→选小麦→toast「1 号地已种下小麦」+ 地块状态
实时更新。门禁 528 项 OK(skip 39)、ruff/pyright 全绿。提交 2676927。
- 顺带发现:上一轮遗留的调试实例用 `--tick 60` 跑了好几个小时(day 冲到
92),已用默认 40 分钟/天重启。
- **推送排障(重要环境坑)**:push 卡死 5 分钟 = **system 级
`credential.helper=helper-selector` 在等人点选择框**(进程
git-credential-helper-selector.exe)。修法:global 里放**空 helper 重置
列表**再依次挂 wincred + GCM(`!"C:/Program Files/..."` **必须带 `!` 和
引号**,否则空格截断)。GCM 路径还要 `NO_PROXY=gitea.4i.hk`——系统代理
对它 502。修完推送秒过。Chrome/Edge 直接 `--executable-path` 起不来
(exit 0 无端口),要自己 headless 起进程再 `--cdp <port>` 连。
### 教训
- HTTP 头只允许 Latin-1:任何把用户可输入内容(用户名、中文名)塞进请求头
的代码,中文输入即炸 fetch。要么不塞(走 Cookie/body),要么白名单校验。
- api() 层必须接住网络异常并可见化——静默的 Promise 拒绝让这个 bug 从
"登录功能上线"一直活到用户报障。