slg-mcp 0.1.9 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
1
  # SLG Agent API 参考
2
2
 
3
- > 协议版本:**88** · 兼容策略:只加不改(见「版本与兼容」)
3
+ > 协议版本:**92** · 兼容策略:只加不改(见「版本与兼容」)
4
4
  > 本文档由后端协议定义生成(`npm run gen:api-doc`),请勿手工编辑。
5
5
  > 运行中的服务提供同版本文档:`GET /agent-api.md`(本文件)与 `GET /agent-api.json`(机器可读清单)。
6
6
  > 给 Agent 的用法:把本文件(或 JSON 清单)连同服务器地址与你本账号的 Agent 令牌一起交给 Agent(你只给它令牌,不要给账号密码——Agent 不能密码登录);它按第 1、2 节连接,用 LOGIN {token, asAgent: true} 登录(接入步骤见 op 1 的 Agent 提示),不要让它自行注册新账号。
7
7
 
8
- > **Agent 必读:保持文档最新(v32)**——服务端会持续更新。① 记住本文开头的协议版本号(当前 88);② 每次 LOGIN 都在 data 里带上 `docVersion`(即该版本号),响应会返回服务端当前的 `protocolVersion`,文档落后时还会附 `docNotice`;③ 一旦落后,`GET /agent-api/changes/{你的版本号}` 获取此后每个版本的一句话变更(JSON),按需重新下载 `/agent-api.md` 全文,并更新你保存的版本号。每次服务端部署都会断开连接,重连登录时就能发现更新。协议只加不改,旧文档不会导致已有操作出错,只是用不上新功能。
8
+ > **Agent 必读:保持文档最新(v32)**——服务端会持续更新。① 记住本文开头的协议版本号(当前 92);② 每次 LOGIN 都在 data 里带上 `docVersion`(即该版本号),响应会返回服务端当前的 `protocolVersion`,文档落后时还会附 `docNotice`;③ 一旦落后,`GET /agent-api/changes/{你的版本号}` 获取此后每个版本的一句话变更(JSON),按需重新下载 `/agent-api.md` 全文,并更新你保存的版本号。每次服务端部署都会断开连接,重连登录时就能发现更新。协议只加不改,旧文档不会导致已有操作出错,只是用不上新功能。
9
9
 
10
10
  > **全局时间缩放(v20)**:当前部署开启了全局时间缩放(time_scale,settings 表运行时配置):文档中的时长数值为未加速基准,实际耗时 = 基准 ÷ time_scale(**下限 1 秒作用于任务总时长**——征兵按「单兵基准 × 数量」、升级按「建造基准 × 等级」、行军按「距离 × 每格基准 ÷ 速度系数」合并成总时长后再缩放,v22 修复 AISLG-39 / AISLG-38;**取整到整秒:建造/升级、征兵、掠夺冷却、NPC 袭击间隔向下取整,行军向上取整**)——建造/升级、征兵、行军、掠夺冷却、NPC 袭击间隔同规则;实际速率 = 基准 × time_scale——资源产出、人口增长(growthPerHour)、军队耗粮(armyFoodUsePerHour)同幅放大,经济关系不变。只作用于新发起的任务与下一次结算(存量任务到期时间不变)。以响应内的 dueAt / production / growthPerHour 等实际下发值为准,不要按文档数值本地折算时长。
11
11
 
@@ -576,7 +576,7 @@
576
576
  "role": "player",
577
577
  "sessionToken": "session-example-token-for-doc-0000000000000",
578
578
  "expiresAt": "2026-10-25T08:00:00.000Z",
579
- "protocolVersion": 88,
579
+ "protocolVersion": 92,
580
580
  "docNotice": null,
581
581
  "season": {
582
582
  "id": 2,
@@ -642,7 +642,7 @@
642
642
  "role": "player",
643
643
  "sessionToken": "session-example-token-for-doc-0000000000000",
644
644
  "expiresAt": "2026-10-25T08:00:00.000Z",
645
- "protocolVersion": 88,
645
+ "protocolVersion": 92,
646
646
  "docNotice": null,
647
647
  "season": {
648
648
  "id": 2,
@@ -666,7 +666,7 @@
666
666
  }
667
667
  ```
668
668
 
669
- **Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/85 补读增量)**
669
+ **Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/89 补读增量)**
670
670
 
671
671
  请求:
672
672
 
@@ -677,7 +677,7 @@
677
677
  "data": {
678
678
  "token": "session-example-token-for-doc-0000000000000",
679
679
  "asAgent": true,
680
- "docVersion": 85,
680
+ "docVersion": 89,
681
681
  "agentModel": "claude-opus-5-5"
682
682
  }
683
683
  }
@@ -696,8 +696,8 @@
696
696
  "role": "agent",
697
697
  "sessionToken": "session-example-token-for-doc-0000000000000",
698
698
  "expiresAt": null,
699
- "protocolVersion": 88,
700
- "docNotice": "接口文档已从 v85 更新到 v88:请 GET /agent-api/changes/85 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。",
699
+ "protocolVersion": 92,
700
+ "docNotice": "接口文档已从 v89 更新到 v92:请 GET /agent-api/changes/89 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。",
701
701
  "season": {
702
702
  "id": 2,
703
703
  "endsAt": "2026-11-22T00:00:00.000Z"
@@ -863,6 +863,10 @@
863
863
  | city.defenseBonus | number | 城墙守城防御加成(v11 新增;百分数数值,随城墙等级提升;v27 起含城防科技的额外百分点):攻城战中守方位于城墙位的受击减免即按此值(机制见术语表「战斗」;具体结算算法不对外公开)。 |
864
864
  | city.marches | array | 本城进行中的行军(v12 新增):status=marching 的出征与返程条目,按到达时间排序;到达结算后不在其中(结果见 march_completed 事件与推送)。 |
865
865
  | city.territory | array | 本城占领的野地(v12 新增):{ x, y, terrain, level, resource, bonusRate 占领加成/小时, gatherRate 驻军采集/小时, garrison 驻军总数, clusterSize 连片块数(v23 新增,AISLG-59), clusterBonusPercent 连片产量加成百分数(v23 新增:3–4 块 10 / ≥5 块 20,不足 3 块为 0), reserve 野地储量(v61 新增,AISLG-165;档位与当前储量 / 上限 / 预计采空或回满时刻,本城占领的地块恒给出数值)};production 已计入 bonusRate、gatherRate 与连片加成——连片按同地形 + 上下左右相邻计算,占领 / 失守后按最新领地自动重算。v61 起 gatherRate 受储量约束:储量空时驻军只按恢复速度(2%/h)采集,采空不需要撤兵,留兵即按恢复速度小量采集。 |
866
+ | gift | number | (v89,AISLG-221)账号礼金当前余额(账号级,不分城)。每个赛季开始固定发 1000(登录时惰性发放,同赛季不重复发),换季清零;不能转让、赠送、兑换成金币或任何资源。只用于服务端标明的便利功能,扣除时事件流写 gift_spent(detail = { reason, amount, balance })。 |
867
+ | giftSeasonGrant | number | (v89)每个赛季每个账号发放的礼金额度(当前为 1000)。界面与 Agent 用它显示“礼金 gift / giftSeasonGrant”,不要写死数值。 |
868
+ | items | object | (v90,AISLG-222)账号道具背包:{ [itemId]: count },每种已定义道具都有键(缺省 0)。与 GET_ITEMS 的 items 同口径。道具随换季清空。 |
869
+ | moveCity | object | (v91,AISLG-220)城池迁移视图:cities[] 逐城给出 { cityId, reasons(不可迁原因,全部列出:MOVE_CITY_FAMOUS / ARMY_OUTSIDE / HAS_ALLY_FORCE / IN_BATTLE,空数组 = 前四条都通过), moveLockUntil(指定坐标迁后的出征限制截止时刻,仅未结束时给出) };items.random = { itemId: 'city_order', count }(迁城令持有数),items.pointing = { itemId: 'city_order_adv', count }(高级迁城令持有数)。目标格与近邻条件不在此视图内,以 MOVE_CITY 的 preview 为准。 |
866
870
  | cities | array | v12 新增:账号全部城池 { id, name, level, x, y, isMain, title 城池称号, nobility 爵位 },主城在前;v24 起 level = 各城官府等级。未占领 NPC 城池时只有主城一座。 |
867
871
  | branch | object | v24 新增(AISLG-58):分城名额 { count 现有分城数(不含主城), limit 上限 = floor(主城官府等级 ÷ 2)(v57 由 ÷3 放宽), minGovernment 占领 NPC 城所需的主城官府最低等级(3) }。名城(AISLG-56)同样计入。 |
868
872
  | capitalSwap | object | v82 新增(AISLG-205,设为主城):{ cooldownUntil 设为主城的冷却截止(ISO 8601,冷却未结束才有值,否则 null), underAttack 本账号任一城或野地正有他人玩家的掠夺 / 占领出征在途, blocked 逐分城的不可设原因 { [cityId]: FAMOUS_CITY_NOT_CAPITAL / CAPITAL_SWAP_DURABILITY_LOW / BRANCH_LIMIT_EXCEEDED }(未列出的分城可设) }。供前端置灰,权威判定仍在 SET_CAPITAL。 |
@@ -2290,7 +2294,7 @@
2290
2294
  | --- | --- | --- |
2291
2295
  | events | array | 事件数组,顺序见各游标说明。 |
2292
2296
  | events[].id | number | 事件自增 id,可作为 beforeId / sinceId 游标。 |
2293
- | events[].type | string | 事件类型:'build_started' \| 'build_queued' \| 'build_completed' \| 'build_cancelled'(v7) \| 'recruit_started' \| 'recruit_queued' \| 'recruit_completed' \| 'recruit_cancelled'(v11) \| 'march_started' \| 'march_completed' \| 'wilderness_occupied' \| 'wilderness_lost' \| 'npc_city_occupied' \| 'npc_raid'(v12) \| 'city_renamed'(v7) \| 'account_reset'(v9,重置后事件流只剩这一条) \| 'agent_connected' \| 'agent_disconnected' \| 'resource_exchanged'(v22,集市兑换成交,detail = { resource, amount, gold, rate }) \| 'npc_attack_warning'(v23,NPC 袭击预警,detail = { x, y, target, terrain, level, armyMin, armyMax, arriveAt, attackId }) \| 'starvation_warning' / 'mutiny'(v34,断粮预警 / 哗变) \| 'hero_recruited' / 'hero_dismissed' / 'hero_arrears' / 'hero_wounded' / 'hero_level_up' / 'hero_granted' / 'guard_changed'(v36,AISLG-114/115/116,武将:招募 / 解雇 / 欠饷 / 重伤 / 升级 / 获得名将 / 城守任命)· 'wilderness_depleted'(v61,AISLG-165,名下野地储量采空,detail = { x, y, terrain, level, at })· 'truce_cancelled'(v71,AISLG-190,主动免战提前解除,detail = { until, cancelledAt })· 'troops_disbanded'(v84,AISLG-209,遣散城内驻军,detail = { cityId, troops, refunded })。 |
2297
+ | events[].type | string | 事件类型:'build_started' \| 'build_queued' \| 'build_completed' \| 'build_cancelled'(v7) \| 'recruit_started' \| 'recruit_queued' \| 'recruit_completed' \| 'recruit_cancelled'(v11) \| 'march_started' \| 'march_completed' \| 'wilderness_occupied' \| 'wilderness_lost' \| 'npc_city_occupied' \| 'npc_raid'(v12) \| 'city_renamed'(v7) \| 'account_reset'(v9,重置后事件流只剩这一条) \| 'agent_connected' \| 'agent_disconnected' \| 'gift_spent'(v89,礼金扣除,detail = { reason, amount, balance })· 'item_granted' / 'item_used' / 'item_bought'(v90,AISLG-222,道具发放 { itemId, requested, granted, reason } / 消耗 { itemId, amount, left, reason } / 礼金购买 { itemId, count, price, cost, owned, gift }) \| 'resource_exchanged'(v22,集市兑换成交,detail = { resource, amount, gold, rate }) \| 'npc_attack_warning'(v23,NPC 袭击预警,detail = { x, y, target, terrain, level, armyMin, armyMax, arriveAt, attackId }) \| 'starvation_warning' / 'mutiny'(v34,断粮预警 / 哗变) \| 'hero_recruited' / 'hero_dismissed' / 'hero_arrears' / 'hero_wounded' / 'hero_level_up' / 'hero_granted' / 'guard_changed'(v36,AISLG-114/115/116,武将:招募 / 解雇 / 欠饷 / 重伤 / 升级 / 获得名将 / 城守任命)· 'wilderness_depleted'(v61,AISLG-165,名下野地储量采空,detail = { x, y, terrain, level, at })· 'truce_cancelled'(v71,AISLG-190,主动免战提前解除,detail = { until, cancelledAt })· 'troops_disbanded'(v84,AISLG-209,遣散城内驻军,detail = { cityId, troops, refunded })。 |
2294
2298
  | events[].initiator | 'player' \| 'agent' \| null | 发起事件的连接声明的登录类型。 |
2295
2299
  | events[].cityId | string \| null | 关联城池 id,无关联时为 null。 |
2296
2300
  | events[].buildId | string \| null | 关联建造 / 征兵 / 行军条目 id,无关联时为 null。 |
@@ -4138,7 +4142,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
4138
4142
 
4139
4143
  `C→S` 请求-响应 · 需登录后发送
4140
4144
 
4141
- 以窗口方式查询世界地图(世界为 1000×1000 的方格,服务端启动时一次性生成)。请求给窗口左上角 (x, y) 与宽高 (w, h);缺省以账号主城为中心取 10×10。窗口起点 (x, y) 按世界边界钳制;w/h 须为 1..20 的整数,非法或越界(0、负数、超过上限、非整数)视为未提供、取缺省 10,不做钳制放大(v17 明确)。每个地块返回地形(plain 平原 / grass 草原 / forest 森林 / hill 丘陵 / desert 荒漠 / marsh 沼泽 / lake 湖泊 / gold_mine 金矿——v19 新增,占领产金、不可掠夺)、类别(wilderness 野地 / npc_city NPC 城池 / city 玩家城池)、野地或 NPC 城池等级、占领者(玩家名与城池)与驻军总数。大地图用多次窗口拼接;服务端不推送整图变化,地块级变化走 PUSH_TILE_STATE(漏推由按需重查覆盖)。
4145
+ 以窗口方式查询世界地图(世界为 1000×1000 的方格,服务端启动时一次性生成)。请求给窗口左上角 (x, y) 与宽高 (w, h);缺省以账号主城为中心取 10×10。窗口起点 (x, y) 按世界边界钳制;w/h 须为 1..20 的整数,非法或越界(0、负数、超过上限、非整数)视为未提供、取缺省 10,不做钳制放大(v17 明确)。每个地块返回地形(plain 平原 / grass 草原 / forest 森林 / hill 丘陵 / desert 荒漠 / marsh 沼泽 / lake 湖泊 / gold_mine 金矿——v19 新增,占领产金、不可掠夺)、类别(wilderness 野地 / npc_city NPC 城池 / city 玩家城池)、野地或 NPC 城池等级、占领者(玩家名与城池)与驻军总数。大地图用多次窗口拼接;服务端不推送整图变化,地块级变化走 PUSH_TILE_STATE(漏推由按需重查覆盖)。 迷雾(v92,AISLG-224):开关 fog_enabled 开启时,本协议只返回实时视野与已探索区块内的地块;未探索的格不出现在 tiles[] 里(前端按缺失格画黑雾),唯一例外是黄巾营地所在的格:未探索也返回最小视图(坐标、地形、camp,fog = explored,seenAt = null,其余字段为空)。已探索的格 fog = explored,只给地形、等级与上次看到的占领者(seenAt 为看到的时间),驻军、库存 / 储量档位、保护、城防、协防、掠夺冷却等动态字段为 null 或 0;实时视野格 fog = visible,与开启前完全一致。关闭时所有格 fog = visible。
4142
4146
 
4143
4147
  **请求字段**
4144
4148
 
@@ -4159,6 +4163,8 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
4159
4163
  | tiles[].x / tiles[].y | number | 地块坐标。 |
4160
4164
  | tiles[].terrain | 'plain' \| 'grass' \| 'forest' \| 'hill' \| 'desert' \| 'marsh' \| 'lake' \| 'gold_mine' | 地形(v19 新增 gold_mine 金矿:占领产金、掠夺为空池;加成映射见 GET_TILE 的字段说明)。 |
4161
4165
  | tiles[].kind | 'wilderness' \| 'npc_city' \| 'city' | 地块类别:野地 / NPC 城池 / 玩家城池(主城与分城)。 |
4166
+ | tiles[].fog | 'explored' \| 'visible' | 战争迷雾(v92,AISLG-224):visible = 实时视野(与未开迷雾一致);explored = 已探索但不在视野内(动态字段清空,见 summary)。未探索的格不返回。 |
4167
+ | tiles[].seenAt | string \| null | 已探索的格为上次看到的时间(ISO);实时视野为 null。 |
4162
4168
  | tiles[].level | number | 野地等级(1..10)或 NPC 城池等级(1..3);玩家城池为 0。 |
4163
4169
  | tiles[].owner | object \| null | 占领者(占领野地或城池地块归属的城池):{ accountId, username, cityId, cityName, ally, relation };relation(v77)= self / ally / friendly / hostile / neutral;无主为 null。ally(v67,AISLG-182)= 占领者与你同属一个联盟(盟友,自己的地块为 false):盟友的城池 / 野地不能掠夺、抢占、占领,也不能侦察(返回 ALLY_NOT_ATTACKABLE)。 |
4164
4170
  | tiles[].garrison | number | 地块驻军总数;未占领野地为 0(原住守军不计入驻军总数;其编成见 GET_TILE 的 nativePower 与侦察);NPC 城池需侦察(v17):未侦察为 0,已侦察为最近一次侦察快照的总数。 |
@@ -4284,7 +4290,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
4284
4290
  | tile.wildFamousIntel | object \| null | 在野名将情报(v54,AISLG-144):未被获得的在野名将所在野地才有 { scouted, name, attrs { lead, force, wit } };未侦察过时 scouted=false、name / attrs 为 null,侦察后(SCOUT 完成)给出名字与三项属性。其余为 null。 |
4285
4291
  | tile.plunderedAt | string \| null | 最近一次成功掠夺(攻方胜利)的时间(v16,ISO 8601):距其 24 小时内该地块处于掠夺冷却(基准值,实际受全局时间缩放等比缩短;MARCH task='plunder' 被拒,PLUNDER_COOLDOWN);从未被掠为 null。 |
4286
4292
 
4287
- **可能错误**:`INVALID_PARAMS`(处置建议见第 4 节)
4293
+ **可能错误**:`INVALID_PARAMS`、`TILE_UNEXPLORED`(处置建议见第 4 节)
4288
4294
 
4289
4295
  **Agent 提示**:出征评估(v18 起改道):参考战力只作规模粗估,不能用来预测胜负——它完全抹平了射程与速度克制(纯近战打守城远程可能全场 0 输出)。正确路径:① 对照「兵种与战斗属性」评估编队结构(前排承伤 + 远程输出 + 高速反远程,射程与速度见属性表);② 野地守军编成按等级推导(见术语表「野地」),NPC 城池先 SCOUT 拿驻防快照(含 wallDefensePercent);③ 战后用战报(GET_BATTLE_REPORTS)的逐回合统计复盘。参考战力数值(TROOP_POWER,含二期与 v64 名城专属兵):民夫 1 / 义兵 2 / 斥候 2 / 长枪兵 4 / 刀盾兵 5 / 弓箭兵 5 / 轻骑兵 8 / 铁骑兵 14 / 辎重车 1 / 床弩 8 / 冲车 3 / 羽林卫 7 / 丹阳兵 7 / 白毦兵 5 / 虎卫军 5 / 诸葛连弩兵 7 / 先登死士 7 / 虎豹骑 10 / 西凉铁骑 10。
4290
4296
 
@@ -4369,7 +4375,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
4369
4375
 
4370
4376
  `C→S` 请求-响应 · 需登录后发送
4371
4377
 
4372
- 从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 troops 按兵种给出数量(至少一种 > 0),发起时立即从城内驻军扣减;行军时长 = Chebyshev 距离 × 每格秒数(基准 15 秒/格,占位)÷ **编队最慢兵种的行军速度系数**(斥候 ×2、轻骑兵 ×1.5,其余 ×1)÷(1 + 行军科技加成,v27 每级 +5%;v30 AISLG-83:自己城池之间的调兵 / 运输再加出发城**驿站**加成,每级 +10%、10 级翻倍,出征野地 / NPC 城等其他目标不受影响,运输往返与失效返程同吃出发城驿站),**总时长**再 ÷ 全局时间缩放、向上取整、最少 1 秒(见文档头部;不是先把每格缩放取整再乘格数)。以响应里的 arriveAt 为准。v16 新增可选 **task**:`plunder`(掠夺,**缺省值**)或 `occupy`(占领)——只作用于野地与 NPC 城目标,侦察 / 调兵 / 增援忽略 task。目标与结算:**无主野地**按 task 掠夺或占领(战斗 vs 原住守军);**本账号占领的野地** = 增援驻军(不战斗);**未被占领的 NPC 城池**可掠夺,也可占领变分城(v24,AISLG-58;战斗 vs 驻防、守方据墙待敌);**本账号分城** = 调兵(不战斗,到达并入该城驻军);**发起前校验校场(v30,AISLG-80)**:本城同时在外的部队数(行军中含返程 + 驻守野地,不计城内驻军)已达校场等级上限(未建校场按 1)时返回 DEPLOY_LIMIT,SCOUT 同;玩家城池(他人的)、他人占领地块与出发主城本身不可作为目标(玩家对抗随后续阶段开放)。**v38(AISLG-122,玩家对抗一)开放掠夺他人城池**:主城与分城都能打、不用宣战,战斗与 NPC 打主城同口径的守城战(城墙、城防科技、箭塔、守方城守全部生效),发起即给守方推送来袭预警(PUSH_ATTACK_WARNING,预警窗口 = 行军时长,敌情按守方烽火台分档);守方处于新手保护返回 NEWBIE_PROTECTED、免战中返回 TARGET_IN_TRUCE(均附 until / retryAfterSeconds),攻方自己的主动免战生效中返回 SELF_TRUCE_ACTIVE(打野地 / NPC 不受限);**task=occupy 对他人分城开放(v40,AISLG-124,玩家对抗三)**:主城仍返回 TASK_INVALID_FOR_TARGET(永不可占领,只能被掠夺)。分城占领资格与占 NPC 城同口径(GOVERNMENT_TOO_LOW / BRANCH_LIMIT / TARGET_LEVEL_TOO_HIGH,目标等级 = 该城官府等级),发起时初核、到达复核(名额没了照打、只降城防值不换主,事件 battle_won 记 occupied=false 与 denial)。守城战打赢一次(守军全灭)城防值 −35,攻方幸存冲车占比每 1% 再 +1.5(最多 +15);**占领打赢不掠夺资源,掠夺打赢不降城防**;城防降到 0 且名额有空当场换主(详见「玩家对抗与城防值」一节与 GET_TILE 的 tile.durability);每次打赢该城进入 4 小时(基准随缩放)被动免战,免战内城防不回涨、结束后每小时回涨 10 至满——占一座分城至少打 3 次、隔 8 小时以上,守方每次都有时间补兵 / 增援;在途到达时守方进入保护 / 免战则扑空返程(事件 outcome=aborted 附 cause)。**v39(AISLG-123,玩家对抗二)开放抢占他人占领的野地**:task='occupy'(缺省 plunder 返回 TASK_INVALID_FOR_TARGET——地里没有存货可抢);野地战无城墙 / 箭塔 / 城守,守方 = 地块驻军,守方没留驻军不打、直接拿下(无战报);发起即给守方推 PUSH_ATTACK_WARNING(target='wilderness',敌情按其所属城烽火台分档),预警期间可向该地块增援(MARCH 打自己的地块 = 增援);守方处于新手保护(NEWBIE_PROTECTED)或主动免战(TARGET_IN_TRUCE)时其全部野地不可被抢,但守方某座城的被动免战只保护城本身、不保护野地;地块处于换主保护期(被抢占后 1 小时基准随缩放)返回 TILE_PROTECTED;攻方自己的主动免战生效中同样不能抢(SELF_TRUCE_ACTIVE)。**抢占结算**:打赢且出发城占领名额(官府等级)有空 → 地块易主、幸存部队驻守并获得加成、地块进入换主保护(1 小时基准随缩放,玩家与 NPC 都不能再抢);名额已满 → 守方照样失地(wilderness_lost cause=conquest)、地块变无主(不设保护)、攻方幸存返程(事件 battle_won 记 occupied=false / denial=TERRITORY_LIMIT);打输 → 守方继续占领,攻方残部返程;战报 kind='pvp_wilderness' 攻守双方各一份。**到达复核口径(v39)**:到达时地块已无主(对方召回等)→ 扑空返程(aborted,cause=target_gone);已易主第三人 → 扑空返程(aborted,cause=owner_changed);已归本账号 → 转增援并入驻军。战斗为多回合推进结构(速度与射程影响接敌、城墙为守方提供受击减免;具体算法不对外公开,机制概览见术语表「战斗」、兵种数值见「兵种与战斗属性」);攻方歼灭守方获胜、胜方幸存 ≥ 1,攻方战败(全灭或回合耗尽)时幸存部队撤回出发城。**掠夺结算(task=plunder)**:野地奖励池 = 地形对应资源 × 750 × 等级 + 金币 × 250 × 等级(v21 掠夺含金,AISLG-31;金矿 gold_mine 保持空池——金矿定位占领生息);NPC 城 = 持久化库存(v21 起含金币;库存不再生、掠空后无收益)。实际带走量按**幸存部队负重**装填(Σ 数量 × 单兵 carry,v27 起再 × 负重科技加成(每级 +5%,向下取整);运输任务的负重上限同口径:民夫 500、斥候/刀盾兵 80、轻骑兵 100,其余 60,占位),按**金→粮→木→石→铁**顺序装满即止,立即入账出发城(不钳储量上限);不改归属、幸存部队返程;成功掠夺的地块进入 24 小时冷却(基准,受全局时间缩放;发起时校验 PLUNDER_COOLDOWN——v22 起该失败附 retryAfterSeconds(冷却截止 − 当前时刻,等满后重发必然受理;在途到达仍战斗但资源为零)。**掠夺玩家城(v38,AISLG-122)**:可抢池 = 城内资源先扣仓库保护(粮/木/石/铁 各保护 1000×仓库等级,金币不受保护),再乘单次比例上限(四资源 45%、金币 15%,v42 AISLG-126 校准拍板)与等级差衰减(出发城官府比目标城官府高 5 级起每多 1 级收益 −15%、最低 25%——大号打小号不禁止但收益递减),最后仍按幸存部队负重装填;攻破(守军全灭)后该城进入 4 小时(基准,随缩放)被动免战,玩家与 NPC 都不能再打它(GET_TILE 的 tile.protection 可查);战报 kind='pvp_raid',攻守双方各得一份;玩家城不受地块掠夺冷却限制(免战即冷却)。**名城(v24,AISLG-56,GET_TILE / 地图的 famous 字段标识,全图 8 座)分两阶段**:外围阶段对其出征(掠夺 / 占领都一样)打的是外围驻军(野战无城墙),打赢 = 外围清空、名城进入城守阶段(事件 battle_won 含 stage='outer'、outerCleared=true、recoversAt),无战利品;城守阶段(限时,超时外围恢复满编)再出征攻城守——task=plunder 掠夺其库存,task=occupy 占领并变分城(以名城命名、产量 +20%,名城计入分城上限);外围未清时对其 task=occupy 返回 OUTER_NOT_CLEARED。名城守军 = 同等级普通 NPC 城 × 3(外围与城守各一半)。**占领 NPC 城(task=occupy,v24)**:需同时满足——主城官府 ≥ 3 级(GOVERNMENT_TOO_LOW);分城数 < 分城上限 = floor(主城官府等级 ÷ 2)(BRANCH_LIMIT,名城同样计入);目标 NPC 城等级 ≤ 出发城的官府等级(TARGET_LEVEL_TOO_HIGH)。发起时初核,Worker 到达时复核(不满足则胜利后不建分城、幸存部队返程,事件 battle_won 记录 occupied=false 与 denial)。打赢后该城成为分城:接收 NPC 城的建筑与**剩余库存**,幸存部队进城驻守,分城可独立建造 / 征兵 / 出征(城池类协议带 cityId);占领不受掠夺冷却限制,不另行掠夺(库存随城移交)。**占领野地结算(task=occupy 目标为野地)**:无一次性战利品;该城占领野地数低于官府等级(上限 = 官府等级,随官府升级提高)时改归属、幸存部队驻守并获得持续加成;发起时初核 TERRITORY_LIMIT,到达复核(超限则胜利后不改归属、幸存部队返程,事件记录 occupied=false / denial=TERRITORY_LIMIT)。**盟友不可攻击(v67,AISLG-182)**:目标城池 / 野地的主人与你同属一个联盟时,掠夺、抢占野地、占领分城一律返回 ALLY_NOT_ATTACKABLE(运输、增援、调兵不受影响);出发后目标才成为盟友的,部队到达时不开战、原路返回(事件 outcome=aborted,cause=ALLY_NOT_ATTACKABLE)。**协防(v74,AISLG-194)**:task=assist 把部队派进盟友的主城 / 分城驻扎——行军时长与普通行军相同(驿站不加速);每座城最多接收 5 支、同一账号对同一座城最多 1 支(在途也算,超限 ASSIST_LIMIT),任务占派出城校场名额、耗粮按野外 2 倍由出发城承担;守城战里与城主驻军合并成守方参战(各方科技只作用于各自部队,城守武将只加成城主部队),战后同一兵种伤亡按开战数量比例分摊(取整余数归城主),派出方会收到一份带 assistLosses 的战报;派出方随时可召回、城主可遣返(DISMISS_ASSIST),退盟 / 被踢 / 解散与分城易主时自动遣返。出发后才退盟的,到达按 ASSIST_NOT_ALLY 原路返回。每场战斗生成一份战报(GET_BATTLE_REPORTS 可查、PUSH_BATTLE_REPORT 推送)。
4378
+ 从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 troops 按兵种给出数量(至少一种 > 0),发起时立即从城内驻军扣减;行军时长 = Chebyshev 距离 × 每格秒数(基准 15 秒/格,占位)÷ **编队最慢兵种的行军速度系数**(斥候 ×2、轻骑兵 ×1.5,其余 ×1)÷(1 + 行军科技加成,v27 每级 +5%;v30 AISLG-83:自己城池之间的调兵 / 运输再加出发城**驿站**加成,每级 +10%、10 级翻倍,出征野地 / NPC 城等其他目标不受影响,运输往返与失效返程同吃出发城驿站),**总时长**再 ÷ 全局时间缩放、向上取整、最少 1 秒(见文档头部;不是先把每格缩放取整再乘格数)。以响应里的 arriveAt 为准。v16 新增可选 **task**:`plunder`(掠夺,**缺省值**)或 `occupy`(占领)——只作用于野地与 NPC 城目标,侦察 / 调兵 / 增援忽略 task。目标与结算:**无主野地**按 task 掠夺或占领(战斗 vs 原住守军);**本账号占领的野地** = 增援驻军(不战斗);**未被占领的 NPC 城池**可掠夺,也可占领变分城(v24,AISLG-58;战斗 vs 驻防、守方据墙待敌);**本账号分城** = 调兵(不战斗,到达并入该城驻军);**发起前校验校场(v30,AISLG-80)**:本城同时在外的部队数(行军中含返程 + 驻守野地,不计城内驻军)已达校场等级上限(未建校场按 1)时返回 DEPLOY_LIMIT,SCOUT 同;玩家城池(他人的)、他人占领地块与出发主城本身不可作为目标(玩家对抗随后续阶段开放)。**v38(AISLG-122,玩家对抗一)开放掠夺他人城池**:主城与分城都能打、不用宣战,战斗与 NPC 打主城同口径的守城战(城墙、城防科技、箭塔、守方城守全部生效),发起即给守方推送来袭预警(PUSH_ATTACK_WARNING,预警窗口 = 行军时长,敌情按守方烽火台分档);守方处于新手保护返回 NEWBIE_PROTECTED、免战中返回 TARGET_IN_TRUCE(均附 until / retryAfterSeconds),攻方自己的主动免战生效中返回 SELF_TRUCE_ACTIVE(打野地 / NPC 不受限);**task=occupy 对他人分城开放(v40,AISLG-124,玩家对抗三)**:主城仍返回 TASK_INVALID_FOR_TARGET(永不可占领,只能被掠夺)。分城占领资格与占 NPC 城同口径(GOVERNMENT_TOO_LOW / BRANCH_LIMIT / TARGET_LEVEL_TOO_HIGH,目标等级 = 该城官府等级),发起时初核、到达复核(名额没了照打、只降城防值不换主,事件 battle_won 记 occupied=false 与 denial)。守城战打赢一次(守军全灭)城防值 −35,攻方幸存冲车占比每 1% 再 +1.5(最多 +15);**占领打赢不掠夺资源,掠夺打赢不降城防**;城防降到 0 且名额有空当场换主(详见「玩家对抗与城防值」一节与 GET_TILE 的 tile.durability);每次打赢该城进入 4 小时(基准随缩放)被动免战,免战内城防不回涨、结束后每小时回涨 10 至满——占一座分城至少打 3 次、隔 8 小时以上,守方每次都有时间补兵 / 增援;在途到达时守方进入保护 / 免战则扑空返程(事件 outcome=aborted 附 cause)。**v39(AISLG-123,玩家对抗二)开放抢占他人占领的野地**:task='occupy'(缺省 plunder 返回 TASK_INVALID_FOR_TARGET——地里没有存货可抢);野地战无城墙 / 箭塔 / 城守,守方 = 地块驻军,守方没留驻军不打、直接拿下(无战报);发起即给守方推 PUSH_ATTACK_WARNING(target='wilderness',敌情按其所属城烽火台分档),预警期间可向该地块增援(MARCH 打自己的地块 = 增援);守方处于新手保护(NEWBIE_PROTECTED)或主动免战(TARGET_IN_TRUCE)时其全部野地不可被抢,但守方某座城的被动免战只保护城本身、不保护野地;地块处于换主保护期(被抢占后 1 小时基准随缩放)返回 TILE_PROTECTED;攻方自己的主动免战生效中同样不能抢(SELF_TRUCE_ACTIVE)。**抢占结算**:打赢且出发城占领名额(官府等级)有空 → 地块易主、幸存部队驻守并获得加成、地块进入换主保护(1 小时基准随缩放,玩家与 NPC 都不能再抢);名额已满 → 守方照样失地(wilderness_lost cause=conquest)、地块变无主(不设保护)、攻方幸存返程(事件 battle_won 记 occupied=false / denial=TERRITORY_LIMIT);打输 → 守方继续占领,攻方残部返程;战报 kind='pvp_wilderness' 攻守双方各一份。**到达复核口径(v39)**:到达时地块已无主(对方召回等)→ 扑空返程(aborted,cause=target_gone);已易主第三人 → 扑空返程(aborted,cause=owner_changed);已归本账号 → 转增援并入驻军。战斗为多回合推进结构(速度与射程影响接敌、城墙为守方提供受击减免;具体算法不对外公开,机制概览见术语表「战斗」、兵种数值见「兵种与战斗属性」);攻方歼灭守方获胜、胜方幸存 ≥ 1,攻方战败(全灭或回合耗尽)时幸存部队撤回出发城。**掠夺结算(task=plunder)**:野地奖励池 = 地形对应资源 × 750 × 等级 + 金币 × 250 × 等级(v21 掠夺含金,AISLG-31;金矿 gold_mine 保持空池——金矿定位占领生息);NPC 城 = 持久化库存(v21 起含金币;库存不再生、掠空后无收益)。实际带走量按**幸存部队负重**装填(Σ 数量 × 单兵 carry,v27 起再 × 负重科技加成(每级 +5%,向下取整);运输任务的负重上限同口径:民夫 500、斥候/刀盾兵 80、轻骑兵 100,其余 60,占位),按**金→粮→木→石→铁**顺序装满即止,立即入账出发城(不钳储量上限);不改归属、幸存部队返程;成功掠夺的地块进入 24 小时冷却(基准,受全局时间缩放;发起时校验 PLUNDER_COOLDOWN——v22 起该失败附 retryAfterSeconds(冷却截止 − 当前时刻,等满后重发必然受理;在途到达仍战斗但资源为零)。**掠夺玩家城(v38,AISLG-122)**:可抢池 = 城内资源先扣仓库保护(粮/木/石/铁 各保护 1000×仓库等级,金币不受保护),再乘单次比例上限(四资源 45%、金币 15%,v42 AISLG-126 校准拍板)与等级差衰减(出发城官府比目标城官府高 5 级起每多 1 级收益 −15%、最低 25%——大号打小号不禁止但收益递减),最后仍按幸存部队负重装填;攻破(守军全灭)后该城进入 4 小时(基准,随缩放)被动免战,玩家与 NPC 都不能再打它(GET_TILE 的 tile.protection 可查);战报 kind='pvp_raid',攻守双方各得一份;玩家城不受地块掠夺冷却限制(免战即冷却)。**名城(v24,AISLG-56,GET_TILE / 地图的 famous 字段标识,全图 8 座)分两阶段**:外围阶段对其出征(掠夺 / 占领都一样)打的是外围驻军(野战无城墙),打赢 = 外围清空、名城进入城守阶段(事件 battle_won 含 stage='outer'、outerCleared=true、recoversAt),无战利品;城守阶段(限时,超时外围恢复满编)再出征攻城守——task=plunder 掠夺其库存,task=occupy 占领并变分城(以名城命名、产量 +20%,名城计入分城上限);外围未清时对其 task=occupy 返回 OUTER_NOT_CLEARED。名城守军 = 同等级普通 NPC 城 × 3(外围与城守各一半)。**占领 NPC 城(task=occupy,v24)**:需同时满足——主城官府 ≥ 3 级(GOVERNMENT_TOO_LOW);分城数 < 分城上限 = floor(主城官府等级 ÷ 2)(BRANCH_LIMIT,名城同样计入);目标 NPC 城等级 ≤ 出发城的官府等级(TARGET_LEVEL_TOO_HIGH)。发起时初核,Worker 到达时复核(不满足则胜利后不建分城、幸存部队返程,事件 battle_won 记录 occupied=false 与 denial)。打赢后该城成为分城:接收 NPC 城的建筑与**剩余库存**,幸存部队进城驻守,分城可独立建造 / 征兵 / 出征(城池类协议带 cityId);占领不受掠夺冷却限制,不另行掠夺(库存随城移交)。**占领野地结算(task=occupy 目标为野地)**:无一次性战利品;该城占领野地数低于官府等级(上限 = 官府等级,随官府升级提高)时改归属、幸存部队驻守并获得持续加成;发起时初核 TERRITORY_LIMIT,到达复核(超限则胜利后不改归属、幸存部队返程,事件记录 occupied=false / denial=TERRITORY_LIMIT)。**盟友不可攻击(v67,AISLG-182)**:目标城池 / 野地的主人与你同属一个联盟时,掠夺、抢占野地、占领分城一律返回 ALLY_NOT_ATTACKABLE(运输、增援、调兵不受影响);出发后目标才成为盟友的,部队到达时不开战、原路返回(事件 outcome=aborted,cause=ALLY_NOT_ATTACKABLE)。**协防(v74,AISLG-194)**:task=assist 把部队派进盟友的主城 / 分城驻扎——行军时长与普通行军相同(驿站不加速);每座城最多接收 5 支、同一账号对同一座城最多 1 支(在途也算,超限 ASSIST_LIMIT),任务占派出城校场名额、耗粮按野外 2 倍由出发城承担;守城战里与城主驻军合并成守方参战(各方科技只作用于各自部队,城守武将只加成城主部队),战后同一兵种伤亡按开战数量比例分摊(取整余数归城主),派出方会收到一份带 assistLosses 的战报;派出方随时可召回、城主可遣返(DISMISS_ASSIST),退盟 / 被踢 / 解散与分城易主时自动遣返。出发后才退盟的,到达按 ASSIST_NOT_ALLY 原路返回。每场战斗生成一份战报(GET_BATTLE_REPORTS 可查、PUSH_BATTLE_REPORT 推送)。 迷雾(v92,AISLG-224):目标未探索且不在视野内时(只限 task = plunder / occupy),目标相关的校验(保护、免战、占领资格等)被拒绝也不报错:照常建立行军,响应结构与校验通过时完全一致,且不会向守方发来袭预警、不破除新手保护;到达后由服务端复核——守方仍受保护或目标已不是可打的对象时原路返回(aborted),否则按现有规则结算。兵力不足、出征上限、迁城后的攻击限制(MOVE_CITY_ATTACK_LOCK)等与目标无关的校验照旧报错。
4373
4379
 
4374
4380
  **请求字段**
4375
4381
 
@@ -6668,7 +6674,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
6668
6674
 
6669
6675
  `C→S` 请求-响应 · 需登录后发送
6670
6676
 
6671
- 返回账号全部武将(含属性、等级 / 经验、自由点数、俸禄、欠饷 / 重伤 / 历练状态、占用关系、今日剩余次数)、当前(或指定)城酒馆的候选(v87 AISLG-217 起:酒馆只在主城建造、候选账号只有一份,固定为主城那座,每 4 小时基准随时间缩放刷新 3 名)、普通将 / 名将数量与上限、全部 40 名名将的全服归属(famousClaims,未被获得的 ownerUsername 为 null,在野名将附 wildAt 落位),以及在野名将的结交进度(friendships)与结交资格(unlocks)。武将规则(数值均为占位):**普通将**从酒馆招募,三项属性(统率 lead / 武力 force / 智力 wit)各 10–40 随机;招募费 = 500 + 三项合计 × 20(金币,从主城扣)。**名将**(三项各 45–65)只从 PvE 获得、全服唯一(见 famousClaims)。带兵加成:全军攻击 + 武力 × 0.3%、全军受到伤害 − 智力 × 0.3%,各自封顶 20%;能吃到加成的兵数 = 统率 × 20,部队超出时按比例摊薄(统率是带大军的关键)。俸禄每小时从主城扣(普通将 20 × 等级、名将 100 × 等级金币,随全局时间缩放),主城金币不够即「欠饷」(arrears=true,不能出征),扣款成功自动恢复。带队战败(攻方失败或全灭)武将重伤 2 小时(随缩放),期间不能出征、不会死亡。经验(v36 AISLG-116):带队参战(含城守守城)获得经验 = 本场歼灭敌军的参考战力,战败减半;升到 L+1 级需 100 × L²,每升一级获得自由点数(普通将 3、名将 5,由玩家分到三项属性,v54 起升级不再自动加属性),上限 40 级——加成仍受 20% 封顶,高等级的主要收益是统率提高(带更多兵吃满加成)。在野名将(v54,AISLG-144):29 名名将隐居在 Lv3 以上的野地里(开服时分配,之后不变)。地图上该野地带 wildFamous 标记;派部队打赢它的原住守军(守军为同级野地的 2 倍)即获得该名将的结交资格(GET_HEROES 的 unlocks)。结交(BEFRIEND_HERO)花主城金币 500 × 野地等级,好感 +10,每个名将每游戏日最多 5 次,同时结交(好感未满、未被招揽)最多 2 名。好感满 100 后招揽(RECRUIT_FAMOUS_HERO),全服唯一,先到先得;别人先招揽走,你的结交进度作废(lost=true,金币不退)。名将解雇后回到可获得状态。
6677
+ 返回账号全部武将(含属性、等级 / 经验、自由点数、俸禄、欠饷 / 重伤 / 历练状态、占用关系、今日剩余次数)、当前(或指定)城酒馆的候选(v87 AISLG-217 起:酒馆只在主城建造、候选账号只有一份,固定为主城那座,每 4 小时基准随时间缩放刷新 3 名)、普通将 / 名将数量与上限、全部 40 名名将的全服归属(famousClaims,未被获得的 ownerUsername 为 null;在野名将未被获得时 wildAt 为 null,被获得后才给出落位 wildAt),以及在野名将的结交进度(friendships)与结交资格(unlocks)。武将规则(数值均为占位):**普通将**从酒馆招募,三项属性(统率 lead / 武力 force / 智力 wit)各 10–40 随机;招募费 = 500 + 三项合计 × 20(金币,从主城扣)。**名将**(三项各 45–65)只从 PvE 获得、全服唯一(见 famousClaims)。带兵加成:全军攻击 + 武力 × 0.3%、全军受到伤害 − 智力 × 0.3%,各自封顶 20%;能吃到加成的兵数 = 统率 × 20,部队超出时按比例摊薄(统率是带大军的关键)。俸禄每小时从主城扣(普通将 20 × 等级、名将 100 × 等级金币,随全局时间缩放),主城金币不够即「欠饷」(arrears=true,不能出征),扣款成功自动恢复。带队战败(攻方失败或全灭)武将重伤 2 小时(随缩放),期间不能出征、不会死亡。经验(v36 AISLG-116):带队参战(含城守守城)获得经验 = 本场歼灭敌军的参考战力,战败减半;升到 L+1 级需 100 × L²,每升一级获得自由点数(普通将 3、名将 5,由玩家分到三项属性,v54 起升级不再自动加属性),上限 40 级——加成仍受 20% 封顶,高等级的主要收益是统率提高(带更多兵吃满加成)。在野名将(v54,AISLG-144):29 名名将隐居在 Lv3 以上的野地里(开服时分配,之后不变)。地图上该野地带 wildFamous 标记;派部队打赢它的原住守军(守军为同级野地的 2 倍)即获得该名将的结交资格(GET_HEROES 的 unlocks)。结交(BEFRIEND_HERO)花主城金币 500 × 野地等级,好感 +10,每个名将每游戏日最多 5 次,同时结交(好感未满、未被招揽)最多 2 名。好感满 100 后招揽(RECRUIT_FAMOUS_HERO),全服唯一,先到先得;别人先招揽走,你的结交进度作废(lost=true,金币不退)。名将解雇后回到可获得状态。
6672
6678
 
6673
6679
  **请求字段**
6674
6680
 
@@ -6688,7 +6694,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
6688
6694
  | famousCap / famousCount | number | 名将上限(固定 3,不占普通将上限)与当前数量。 |
6689
6695
  | heroes | array | 账号全部武将:{ id, name, famous, lead, force, wit, level, exp, expNext 距下一级, salaryPerHour 已随时间缩放, arrears 欠饷, woundedUntil 重伤恢复时刻或 null, guardCityId 正在城守的城或 null, marchingMarchId 正在随行的行军或 null, bonus { atkPercent, defPercent, leadCap }(满编口径), guardProductionPercent 城守产量加成 }。 |
6690
6696
  | candidates | array | 主城酒馆当前候选(v87 起账号只有一份):{ id, name, lead, force, wit, cost 招募费, refreshedAt 本批刷新时刻 };主城酒馆未建为空数组。 |
6691
- | famousClaims | array | 全部名将归属:{ name, sourceLabel 来源人读描述, ownerUsername 当前主人或 null, grantedAt, wildAt 在野名将的落位 { x, y, level } 或 null }。 |
6697
+ | famousClaims | array | 全部名将归属:{ name, sourceLabel 来源人读描述, ownerUsername 当前主人或 null, grantedAt, wildAt 在野名将被获得后的落位 { x, y, level };未被获得的在野名将与名城 / 黄巾名将为 null(未被获得时不泄露藏身位置)}。 |
6692
6698
  | friendships | array | 结交进度(v54):{ heroName, favor 好感 0–100, todayLeft 今日还能结交的次数, cost 下次结交花费, lost 已被他人招揽(作废)}。 |
6693
6699
  | unlocks | string[] | 结交资格(v54):打赢过其野地守军、且尚未被他人获得的在野名将名。 |
6694
6700
  | friendshipCap | number | 同时结交上限(v54,固定 2)。 |
@@ -12339,7 +12345,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
12339
12345
 
12340
12346
  `C→S` 请求-响应 · 需登录后发送
12341
12347
 
12342
- 返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、同联盟盟友的城池(ally,v67 AISLG-182)、他方非盟友的玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。
12348
+ 返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、同联盟盟友的城池(ally,v67 AISLG-182)、他方非盟友的玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。 迷雾开启时(v92):实时视野内的城与战力榜前 20 名的主城始终显示;已探索的城按上次看到的归属显示;未探索的城不显示,8 座名城未探索时在锚点显示 side = famous_rumor(大致方位,不是真实坐标)。响应多出 exploredChunks(10,000 位 base64,1250 字节,区块下标 floor(y/10)*100+floor(x/10),第 i 位在字节 i>>3、掩码 1<<(i&7))与 exploredPercent(探索进度 %)。关闭时响应与之前完全一致(无这两个字段,全图城池)。
12343
12349
 
12344
12350
  **请求字段**
12345
12351
 
@@ -12351,6 +12357,8 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
12351
12357
  | --- | --- | --- |
12352
12358
  | size | number | 世界边长(世界为 size×size 方格,当前 1000)。 |
12353
12359
  | at | string | 统计时刻(ISO 8601)。 |
12360
+ | exploredChunks | string | 迷雾开启时才有(v92):已探索区块位图,base64(1250 字节)。 |
12361
+ | exploredPercent | number | 迷雾开启时才有(v92):已探索区块占全图的百分比,保留 1 位小数。 |
12354
12362
  | cities | array | 城池点位 [x, y, side] 数组;side 取 'own' \| 'ally' \| 'friendly' \| 'hostile' \| 'enemy' \| 'npc' \| 'famous'(ally 为 v67 同联盟盟友;friendly / hostile 为 v77 友盟 / 敌对联盟成员)。 |
12355
12363
 
12356
12364
  **Agent 提示**:想找城(名城、NPC 城、他人城池)时先用它看全局方位,再用 GET_WORLD_MAP 按窗口取地块详情、GET_TILE 看驻军。它不返回野地,找野地仍用 GET_WORLD_MAP。
@@ -18422,6 +18430,343 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
18422
18430
  }
18423
18431
  ```
18424
18432
 
18433
+ ### op 148 · GET_ITEMS — 查询道具背包、道具目录与礼金余额(v90,AISLG-222)
18434
+
18435
+ `C→S` 请求-响应 · 需登录后发送
18436
+
18437
+ 返回账号的道具背包 items(每种道具的数量)、全部道具定义 catalog(名称、说明、礼金单价 shopPrice,null 表示不卖,堆叠上限 stackMax)与礼金余额 gift。商店出售的是 shopPrice 非 null 的道具:迁城令(city_order,礼金 50,堆叠上限 99);高级迁城令(city_order_adv,礼金 100,堆叠上限 99)。道具随换季清空,礼金见 GET_STATE 的 gift。
18438
+
18439
+ **请求字段**
18440
+
18441
+ 无请求字段(`data` 可省略)。
18442
+
18443
+ **响应 data 字段**
18444
+
18445
+ | 字段 | 类型 | 说明 |
18446
+ | --- | --- | --- |
18447
+ | items | object | 背包:{ [itemId]: count },每种已定义道具都有键(缺省 0)。 |
18448
+ | catalog | object[] | 道具定义:id、name、nameEn、desc、descEn、kind(目前只有 order)、shopPrice(礼金单价,null = 不卖)、stackMax(堆叠上限)。 |
18449
+ | gift | number | 礼金余额(见 GET_STATE 的 gift)。 |
18450
+
18451
+ **Agent 提示**:买道具前先用本协议看 shopPrice 与 gift,BUY_ITEM 必须带上你看到的单价(expectedPrice)。
18452
+
18453
+ **示例**
18454
+
18455
+ **查询背包与商店目录**
18456
+
18457
+ 请求:
18458
+
18459
+ ```json
18460
+ {
18461
+ "op": 148,
18462
+ "seq": 61,
18463
+ "data": {}
18464
+ }
18465
+ ```
18466
+
18467
+ 成功响应:
18468
+
18469
+ ```json
18470
+ {
18471
+ "op": 148,
18472
+ "seq": 61,
18473
+ "ok": true,
18474
+ "data": {
18475
+ "items": {
18476
+ "city_order": 2,
18477
+ "city_order_adv": 0
18478
+ },
18479
+ "catalog": [
18480
+ {
18481
+ "id": "city_order",
18482
+ "name": "迁城令",
18483
+ "nameEn": "City Move Order",
18484
+ "desc": "消耗 1 张,随机迁城一次。",
18485
+ "descEn": "Uses 1 order to relocate the city once to a random spot.",
18486
+ "kind": "order",
18487
+ "shopPrice": 200,
18488
+ "stackMax": 99
18489
+ },
18490
+ {
18491
+ "id": "city_order_adv",
18492
+ "name": "高级迁城令",
18493
+ "nameEn": "Advanced City Move Order",
18494
+ "desc": "消耗 1 张,指定坐标迁城一次。",
18495
+ "descEn": "Uses 1 order to relocate the city once to chosen coordinates.",
18496
+ "kind": "order",
18497
+ "shopPrice": 500,
18498
+ "stackMax": 99
18499
+ }
18500
+ ],
18501
+ "gift": 600
18502
+ }
18503
+ }
18504
+ ```
18505
+
18506
+ ### op 149 · BUY_ITEM — 礼金购买道具(v90,AISLG-222)
18507
+
18508
+ `C→S` 请求-响应 · 需登录后发送
18509
+
18510
+ 用礼金购买道具:礼金按 单价 × 数量 扣除,道具数量按数量增加,写事件 item_bought。校验顺序:itemId 必须在目录里且可卖(未知或 shopPrice 为 null → INVALID_PARAMS)→ count 为 1..99 的整数 → expectedPrice 必填(缺失或非整数 → INVALID_PARAMS)→ expectedPrice 必须等于当前 shopPrice(不等 → ITEM_PRICE_CHANGED,附当前 price,不扣不改,客户端刷新目录后让玩家重新确认,不自动重试)→ 购买后不超过 stackMax(超出 → ITEM_STACK_FULL,附 stackMax / have / canBuy)→ 礼金不足 → INSUFFICIENT_GIFT(附 balance / cost)。全部在一个事务里,任何一步失败都不扣礼金、不加道具。成功后向该账号其他在线连接推送 PUSH_ACCOUNT_STATE(reason = items_changed)。已买到的道具不因调价而补差价或退款。
18511
+
18512
+ **请求字段**
18513
+
18514
+ | 字段 | 类型 | 说明 |
18515
+ | --- | --- | --- |
18516
+ | itemId | string | 必填。道具 id(见 GET_ITEMS 的 catalog)。 |
18517
+ | count | number | 必填。购买数量,1..99 的整数。购买后不能超过该道具的堆叠上限。 |
18518
+ | expectedPrice | number | 必填。你看到的单价(礼金),必须等于当前 shopPrice;不一致返回 ITEM_PRICE_CHANGED。 |
18519
+
18520
+ **响应 data 字段**
18521
+
18522
+ | 字段 | 类型 | 说明 |
18523
+ | --- | --- | --- |
18524
+ | itemId | string | 购买的道具 id。 |
18525
+ | bought | number | 本次买入数量。 |
18526
+ | count | number | 购买后该道具的总数量。 |
18527
+ | price | number | 本次单价(礼金)。 |
18528
+ | cost | number | 本次花费的礼金(price × bought)。 |
18529
+ | gift | number | 购买后的礼金余额。 |
18530
+
18531
+ **可能错误**:`INVALID_PARAMS`、`ITEM_PRICE_CHANGED`、`ITEM_STACK_FULL`、`INSUFFICIENT_GIFT`(处置建议见第 4 节)
18532
+
18533
+ **Agent 提示**:只在玩家明确要买时调用。收到 ITEM_PRICE_CHANGED 时先 GET_ITEMS 刷新目录,把新单价告诉玩家,等他确认后再带新单价重发,不要用旧价自动重试。
18534
+
18535
+ **示例**
18536
+
18537
+ **买 2 张迁城令(单价 50)**
18538
+
18539
+ 请求:
18540
+
18541
+ ```json
18542
+ {
18543
+ "op": 149,
18544
+ "seq": 62,
18545
+ "data": {
18546
+ "itemId": "city_order",
18547
+ "count": 2,
18548
+ "expectedPrice": 50
18549
+ }
18550
+ }
18551
+ ```
18552
+
18553
+ 成功响应:
18554
+
18555
+ ```json
18556
+ {
18557
+ "op": 149,
18558
+ "seq": 62,
18559
+ "ok": true,
18560
+ "data": {
18561
+ "itemId": "city_order",
18562
+ "bought": 2,
18563
+ "count": 4,
18564
+ "price": 50,
18565
+ "cost": 100,
18566
+ "gift": 900
18567
+ }
18568
+ }
18569
+ ```
18570
+
18571
+ **单价已变:返回当前单价,不扣不改**
18572
+
18573
+ 请求:
18574
+
18575
+ ```json
18576
+ {
18577
+ "op": 149,
18578
+ "seq": 63,
18579
+ "data": {
18580
+ "itemId": "city_order",
18581
+ "count": 1,
18582
+ "expectedPrice": 50
18583
+ }
18584
+ }
18585
+ ```
18586
+
18587
+ 失败响应(`ITEM_PRICE_CHANGED`):
18588
+
18589
+ ```json
18590
+ {
18591
+ "op": 149,
18592
+ "seq": 63,
18593
+ "ok": false,
18594
+ "error": {
18595
+ "code": "ITEM_PRICE_CHANGED",
18596
+ "message": "道具单价已变化,请刷新后重新确认"
18597
+ },
18598
+ "data": {
18599
+ "price": 250
18600
+ }
18601
+ }
18602
+ ```
18603
+
18604
+ ### op 150 · MOVE_CITY — 迁城(v91,AISLG-220)
18605
+
18606
+ `C→S` 请求-响应 · 需登录后发送
18607
+
18608
+ 把账号名下的一座城(主城或分城,名城除外)迁到地图上的一块空野地。mode = random 随机迁:消耗 1 张迁城令(city_order),系统按注册落位同一算法选址,不需要坐标;mode = pointing 指定坐标迁:消耗 1 张高级迁城令(city_order_adv),x / y 必填,目标须为无主、无 NPC 的空野地,且离其他账号的城池格(分城、名城含在内)至少 3 格(Chebyshev 距离)。道具用 BUY_ITEM 以礼金购买,GET_ITEMS 查看持有数。
18609
+
18610
+ 拦截顺序(前四条即 GET_STATE moveCity 的 reasons):名城 MOVE_CITY_FAMOUS → 本城有部队在外(本城发出的行军含返程 / 运输 / 调兵,或派去别人城里的协防)MOVE_CITY_ARMY_OUTSIDE(附 count)→ 盟友协防本城 MOVE_CITY_HAS_ALLY_FORCE(附 count;迁城不会自动遣返,须对方召回或城主 DISMISS_ASSIST)→ 本城或其名下野地有敌情 MOVE_CITY_IN_BATTLE(只看这一座城)→ 目标格不合法 MOVE_CITY_TILE_INVALID / 太近 MOVE_CITY_TOO_CLOSE / 随机选址无空地 MOVE_CITY_NO_SPACE → 道具不足 INSUFFICIENT_ITEM(附 itemId、count)→ 执行时目标被抢先 MOVE_CITY_TILE_TAKEN。以上任何一条失败都不扣道具、不改任何数据。
18611
+
18612
+ 迁后:新格变成本城(等级 0,同注册落位);城的建筑、驻军、资源、武将、科技、队列、名下野地与城防 / 免战、联盟、爵位、保护状态全部保留。旧格:主城变回空野地(地形不变,等级按世界生成同口径重新抽取);分城回归 NPC 城池(等级 = 来源等级,并写入与放弃分城同口径的占回冷却,冷却内不能再占这一格的 NPC 城)。
18613
+
18614
+ 指定坐标迁(pointing)后 12 小时内(按时间缩放),这座城只能运输、调兵、召回、增援自己名下的野地;掠夺、占领、侦察、派协防以及其他攻击类出征都返回 MOVE_CITY_ATTACK_LOCK(附 retryAfterSeconds)。随机迁没有这个限制。迁城不中断也不延长新手保护 / 免战,迁后没有额外保护期。
18615
+
18616
+ 预览:preview = true 时不改任何数据,返回要消耗的道具、已有数量、目标格、距离、旧格去向与出征限制时长;条件不满足时预览同样返回对应错误码(附原因数据),不会只返回 ok。执行必须携带 confirm = true。
18617
+
18618
+ **请求字段**
18619
+
18620
+ | 字段 | 类型 | 说明 |
18621
+ | --- | --- | --- |
18622
+ | cityId | string | 必填。要迁的城 UUID(GET_STATE 的 cities[].id,主城或分城,名城除外)。非本账号名下的城或格式不对返回 INVALID_PARAMS。 |
18623
+ | mode | string | 必填。random(随机迁,消耗迁城令)或 pointing(指定坐标迁,消耗高级迁城令);其他值返回 INVALID_PARAMS。 |
18624
+ | x | number | mode = pointing 时必填的目标 x 坐标(整数,0..999,越界返回 INVALID_PARAMS);random 时忽略。 |
18625
+ | y | number | mode = pointing 时必填的目标 y 坐标(整数,0..999,越界返回 INVALID_PARAMS);random 时忽略。 |
18626
+ | confirm | boolean | 执行时必填,必须为 true(缺失或不为 true 返回 INVALID_PARAMS);preview = true 时不需要。 |
18627
+ | preview | boolean | 可选。true = 只预览,不改任何数据(见 summary)。 |
18628
+
18629
+ **响应 data 字段**
18630
+
18631
+ | 字段 | 类型 | 说明 |
18632
+ | --- | --- | --- |
18633
+ | cityId | string | 迁走的城 UUID。 |
18634
+ | mode | string | random 或 pointing。 |
18635
+ | from / to | object | 旧坐标与新坐标 { x, y }。 |
18636
+ | distance | number | 旧坐标到新坐标的 Chebyshev 距离(不影响消耗,供参考)。 |
18637
+ | itemId | string | 消耗的道具 id(city_order 或 city_order_adv)。 |
18638
+ | left | number | 消耗后该道具的剩余数量。 |
18639
+ | oldTile | string | 旧格去向:wilderness(主城,变空野地)或 npc_city(分城,回归 NPC 城)。 |
18640
+ | moveLockUntil | string \| null | pointing 迁后的出征限制截止时刻(ISO 8601);random 为 null。 |
18641
+
18642
+ **可能错误**:`INVALID_PARAMS`、`MOVE_CITY_FAMOUS`、`MOVE_CITY_ARMY_OUTSIDE`、`MOVE_CITY_HAS_ALLY_FORCE`、`MOVE_CITY_IN_BATTLE`、`MOVE_CITY_TILE_UNEXPLORED`、`MOVE_CITY_TILE_INVALID`、`MOVE_CITY_TILE_TAKEN`、`MOVE_CITY_TOO_CLOSE`、`MOVE_CITY_NO_SPACE`、`INSUFFICIENT_ITEM`(处置建议见第 4 节)
18643
+
18644
+ **Agent 提示**:先 GET_STATE 看 moveCity:reasons 为空且对应道具持有数 ≥ 1 才可迁。指定坐标前先 GET_WORLD_MAP 找空野地(迷雾开启时须是已探索或实时视野内的格,否则返回 MOVE_CITY_TILE_UNEXPLORED),再用 preview = true 预览(看 to、distance、attackLockSeconds),玩家确认后才带 confirm = true 执行。收到 INSUFFICIENT_ITEM 时先 GET_ITEMS,由玩家决定是否 BUY_ITEM。pointing 迁后 12 小时内不要派攻击类部队(会返回 MOVE_CITY_ATTACK_LOCK);运输、调兵与增援自己的野地不受限。
18645
+
18646
+ **示例**
18647
+
18648
+ **预览指定坐标迁城(主城迁到 (420, 388),有 1 张高级迁城令)**
18649
+
18650
+ 请求:
18651
+
18652
+ ```json
18653
+ {
18654
+ "op": 150,
18655
+ "seq": 70,
18656
+ "data": {
18657
+ "cityId": "0b7e5c1a-3d2f-4e8a-9c61-2f4a8d9e1b07",
18658
+ "mode": "pointing",
18659
+ "x": 420,
18660
+ "y": 388,
18661
+ "preview": true
18662
+ }
18663
+ }
18664
+ ```
18665
+
18666
+ 成功响应:
18667
+
18668
+ ```json
18669
+ {
18670
+ "op": 150,
18671
+ "seq": 70,
18672
+ "ok": true,
18673
+ "data": {
18674
+ "preview": true,
18675
+ "cityId": "0b7e5c1a-3d2f-4e8a-9c61-2f4a8d9e1b07",
18676
+ "mode": "pointing",
18677
+ "itemId": "city_order_adv",
18678
+ "count": 1,
18679
+ "need": 1,
18680
+ "from": {
18681
+ "x": 512,
18682
+ "y": 300
18683
+ },
18684
+ "to": {
18685
+ "x": 420,
18686
+ "y": 388
18687
+ },
18688
+ "distance": 92,
18689
+ "oldTile": "wilderness",
18690
+ "attackLockSeconds": 43200
18691
+ }
18692
+ }
18693
+ ```
18694
+
18695
+ **执行随机迁城(分城回归 NPC 城)**
18696
+
18697
+ 请求:
18698
+
18699
+ ```json
18700
+ {
18701
+ "op": 150,
18702
+ "seq": 71,
18703
+ "data": {
18704
+ "cityId": "5d1f0c2e-8a6b-4f3d-b7e9-0c2a1d4e6f81",
18705
+ "mode": "random",
18706
+ "confirm": true
18707
+ }
18708
+ }
18709
+ ```
18710
+
18711
+ 成功响应:
18712
+
18713
+ ```json
18714
+ {
18715
+ "op": 150,
18716
+ "seq": 71,
18717
+ "ok": true,
18718
+ "data": {
18719
+ "cityId": "5d1f0c2e-8a6b-4f3d-b7e9-0c2a1d4e6f81",
18720
+ "mode": "random",
18721
+ "from": {
18722
+ "x": 300,
18723
+ "y": 512
18724
+ },
18725
+ "to": {
18726
+ "x": 745,
18727
+ "y": 129
18728
+ },
18729
+ "distance": 445,
18730
+ "itemId": "city_order",
18731
+ "left": 4,
18732
+ "oldTile": "npc_city",
18733
+ "moveLockUntil": null
18734
+ }
18735
+ }
18736
+ ```
18737
+
18738
+ **离他人城池太近:拒绝,不扣令**
18739
+
18740
+ 请求:
18741
+
18742
+ ```json
18743
+ {
18744
+ "op": 150,
18745
+ "seq": 72,
18746
+ "data": {
18747
+ "cityId": "0b7e5c1a-3d2f-4e8a-9c61-2f4a8d9e1b07",
18748
+ "mode": "pointing",
18749
+ "x": 421,
18750
+ "y": 390,
18751
+ "confirm": true
18752
+ }
18753
+ }
18754
+ ```
18755
+
18756
+ 失败响应(`MOVE_CITY_TOO_CLOSE`):
18757
+
18758
+ ```json
18759
+ {
18760
+ "op": 150,
18761
+ "seq": 72,
18762
+ "ok": false,
18763
+ "error": {
18764
+ "code": "MOVE_CITY_TOO_CLOSE",
18765
+ "message": "离其他玩家城池太近(需至少间隔 3 格)"
18766
+ }
18767
+ }
18768
+ ```
18769
+
18425
18770
  ### op 2000 · PUSH_BUILD_STATE — 推送:建筑建造状态变化
18426
18771
 
18427
18772
  `S→C` 服务端推送 · 无 `seq`
@@ -18585,7 +18930,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
18585
18930
 
18586
18931
  `S→C` 服务端推送 · 无 `seq`
18587
18932
 
18588
- 城池级状态变化时推送给该账号所有在线连接(发起连接除外):city_renamed=城池改名(RENAME_CITY)、account_reset=账号数据被 RESET_ACCOUNT 重置(v9,重置后全部游戏数据回到开号初始状态)、city_discarded=分城被放弃(DISCARD_CITY,v57;推送只带 cityId,收到后用 GET_STATE 刷新城池列表)、capital_changed=设为主城(SET_CAPITAL,v82,AISLG-205;cityId 为新主城,formerCapitalId 为原主城,收到后用 GET_STATE 刷新)、troops_disbanded=城内驻军被遣散(DISBAND_TROOPS,v84,AISLG-209;只带 cityId,收到后用 GET_STATE 刷新驻军与资源)。建造队列相关变化走 PUSH_BUILD_STATE。推送只携带变化摘要,完整现状用 GET_STATE 查询。
18933
+ 城池级状态变化时推送给该账号所有在线连接(发起连接除外):city_renamed=城池改名(RENAME_CITY)、account_reset=账号数据被 RESET_ACCOUNT 重置(v9,重置后全部游戏数据回到开号初始状态)、city_discarded=分城被放弃(DISCARD_CITY,v57;推送只带 cityId,收到后用 GET_STATE 刷新城池列表)、capital_changed=设为主城(SET_CAPITAL,v82,AISLG-205;cityId 为新主城,formerCapitalId 为原主城,收到后用 GET_STATE 刷新)、troops_disbanded=城内驻军被遣散(DISBAND_TROOPS,v84,AISLG-209;只带 cityId,收到后用 GET_STATE 刷新驻军与资源)。city_moved=城池迁移(MOVE_CITY,v91,AISLG-220;带 cityId 与 from / to 新旧坐标,收到后用 GET_STATE 刷新,新旧两格另有 PUSH_TILE_STATE reason = city_moved)。建造队列相关变化走 PUSH_BUILD_STATE。推送只携带变化摘要,完整现状用 GET_STATE 查询。
18589
18934
 
18590
18935
  **data 字段**
18591
18936
 
@@ -19712,8 +20057,8 @@ NPC 出兵后不再立刻结算:先给被袭击账号发预警(预警提前
19712
20057
 
19713
20058
  | 字段 | 类型 | 说明 |
19714
20059
  | --- | --- | --- |
19715
- | reason | 'account_renamed' | 触发本次推送的状态变化。 |
19716
- | username | string | 账号的新昵称(即新 username)。 |
20060
+ | reason | 'account_renamed' \| 'items_changed' | 触发本次推送的状态变化。items_changed(v90,AISLG-222):道具背包或礼金余额变化,data 另带 items(每种道具的数量)与 gift(礼金余额)。 |
20061
+ | username | string | 账号的新昵称(即新 username);reason = items_changed 时无此字段。 |
19717
20062
 
19718
20063
  **Agent 提示**:收到 account_renamed 后,本地缓存的 username 已过期:后续展示(聊天、地图归属、排行榜)与对外称呼一律用新昵称。
19719
20064
 
@@ -20115,6 +20460,58 @@ NPC 出兵后不再立刻结算:先给被袭击账号发预警(预警提前
20115
20460
  }
20116
20461
  ```
20117
20462
 
20463
+ ### op 2029 · PUSH_EXPLORATION_REPORT — 推送:探索简报(v92,AISLG-224)
20464
+
20465
+ `S→C` 服务端推送 · 无 `seq`
20466
+
20467
+ 部队去程结束(到达或撤回)后,如果这一趟新探索了区块,推给本账号一份简报:新探索的区块数、新区块里的东西按类计数(NPC 城分等级、金矿、Lv5 及以上野地、在野名将、其他玩家的城、名城),以及最多 10 个坐标(优先级:名城 > 在野名将 > 金矿 > 玩家城 > NPC 城 > 高级野地)。内容与事件 exploration_report 的 detail 一致,可随时用 GET_EVENTS 回看。存量初始化、开局与城池 / 领地带来的新区块不生成简报;返程不生成。
20468
+
20469
+ **data 字段**
20470
+
20471
+ | 字段 | 类型 | 说明 |
20472
+ | --- | --- | --- |
20473
+ | report | object | { eventId, marchId, chunks, npcCities: { total, byLevel }, goldMines, highWilderness, wildHeroes, playerCities, famous, cells: [{ x, y, kind, level? }] }。kind = famous / wild_hero / gold_mine / player_city / npc_city / high_wilderness。 |
20474
+
20475
+ **Agent 提示**:收到后可按 cells 坐标用 GET_TILE 查看(已探索的地块返回上次看到的情况,带 seenAt)。
20476
+
20477
+ **示例**
20478
+
20479
+ 推送(`online=undefined`):
20480
+
20481
+ ```json
20482
+ {
20483
+ "op": 2029,
20484
+ "push": true,
20485
+ "data": {
20486
+ "report": {
20487
+ "eventId": 1024,
20488
+ "marchId": "6f1d2c3e-0000-4000-8000-000000000001",
20489
+ "chunks": 3,
20490
+ "npcCities": {
20491
+ "total": 2,
20492
+ "byLevel": {
20493
+ "3": 1,
20494
+ "5": 1
20495
+ }
20496
+ },
20497
+ "goldMines": 1,
20498
+ "highWilderness": 0,
20499
+ "wildHeroes": 0,
20500
+ "playerCities": 0,
20501
+ "famous": 0,
20502
+ "cells": [
20503
+ {
20504
+ "x": 512,
20505
+ "y": 340,
20506
+ "kind": "gold_mine",
20507
+ "level": 2
20508
+ }
20509
+ ]
20510
+ }
20511
+ }
20512
+ }
20513
+ ```
20514
+
20118
20515
  ## 4. 错误码参考
20119
20516
 
20120
20517
  所有错误响应的 `error.message` 为人读文案(中文),程序逻辑应依据 `error.code` 判断。
@@ -20283,6 +20680,21 @@ NPC 出兵后不再立刻结算:先给被袭击账号发预警(预警提前
20283
20680
  | `STRATAGEM_TOKEN_SHORT` | (v86,AISLG-211)对应类别的计谋令不足;响应附 tokenKind 与 have。此时不扣令、不写冷却、不改任何数据。 | 用战场军功在战场商店(BUY_BATTLEFIELD_ITEM 的 stratagem_* 商品)兑换计谋令后再施。 |
20284
20681
  | `STRATAGEM_TOKEN_FULL` | (v86,AISLG-211)该类计谋令持有数已达上限,兑换被拒且不扣军功;响应附 tokenKind / have / limit。上限防止囤到某一周集中施计,换季与军功一起清零。 | 先把手上的令用掉一些再兑换,或改买其他商品。 |
20285
20682
  | `CITY_AMBUSHED` | (v86,AISLG-211)这座城中了十面埋伏,期间不能派出任何部队(MARCH 的各用途、侦察、协防出发、交易所商队、剧本战场入场都被拒);响应附 retryAfterSeconds。已经在外的部队照常行动、照常可以召回。 | 等到 retryAfterSeconds 之后再派兵;已在外的部队用 RECALL_MARCH 召回不受影响。 |
20683
+ | `INSUFFICIENT_GIFT` | (v89,AISLG-221)礼金余额不足,扣除被拒;响应附 balance(当前余额)。不扣、不写事件,其他数据不变。礼金每赛季固定发 1000,换季清零,不能转让或兑换。 | 等下一个赛季(换季后重新登录即回到 1000)或改用金币等其他方式;用 GET_STATE 的 gift 查看当前余额。 |
20684
+ | `INSUFFICIENT_ITEM` | (v90,AISLG-222)道具数量不足,消耗被拒;响应附 itemId 与 count(当前数量)。不扣、不写事件,其他数据不变。 | 先用 GET_ITEMS 确认数量;不够时用 BUY_ITEM 用礼金买,或等获得途径(任务 / 活动)发放。 |
20685
+ | `ITEM_STACK_FULL` | (v90,AISLG-222)购买后会超过该道具的堆叠上限,购买被拒;响应附 stackMax、have(当前数量)、canBuy(还能买几张,已满为 0)。礼金与道具都不变。 | 把购买数量降到 canBuy 以内;已满时先用掉道具再买。 |
20686
+ | `ITEM_PRICE_CHANGED` | (v90,AISLG-222)BUY_ITEM 的 expectedPrice 与当前单价不一致(道具调价过);响应附 price(当前单价)。不扣礼金、不加道具。 | 用 GET_ITEMS 刷新目录,把新单价告诉玩家,让玩家重新确认后带新单价重发;不要自动用新价重试。 |
20687
+ | `MOVE_CITY_FAMOUS` | (v91,AISLG-220)名城(特殊城池)不能迁移;不扣令、不改任何数据。 | 换一座非名城的城迁移;名城只能靠攻占 / 经营保有。 |
20688
+ | `MOVE_CITY_ARMY_OUTSIDE` | (v91,AISLG-220)这座城有部队在外:本城发出的行军(出征 / 返程 / 运输 / 调兵)或派去别人城里的协防。响应附 count。 | 等部队回到本城(或用 RECALL_MARCH 召回、DISMISS_ASSIST 撤回协防)后再迁。驻守自己野地的部队不算在外。 |
20689
+ | `MOVE_CITY_HAS_ALLY_FORCE` | (v91,AISLG-220)盟友的部队正在协防这座城;响应附 count。迁城时不会自动遣返。 | 请盟友召回协防,或城主用 DISMISS_ASSIST 遣返后再迁。 |
20690
+ | `MOVE_CITY_IN_BATTLE` | (v91,AISLG-220)这座城或其名下野地正有行军指向,或有未结的 NPC 来袭(与放弃分城、遣散士兵同一口径)。只看这一座城。 | 等战斗结算或来袭结束后再迁;若是自己的行军,可用 RECALL_MARCH 撤回。 |
20691
+ | `MOVE_CITY_TILE_INVALID` | (v91,AISLG-220)指定坐标不是无主、无 NPC 的空野地(NPC 城、他人城池、已被占领的野地、城池格等一切非空野地的格都算)。不扣令。 | 用 GET_MAP_OVERVIEW / GET_WORLD_MAP 找一块空野地(kind=wilderness 且无归属)后重试。 |
20692
+ | `MOVE_CITY_TILE_TAKEN` | (v91,AISLG-220)目标格在判定与落库之间被别人抢先占走(并发)。令与坐标都未改动。 | 重新 GET_WORLD_MAP 选一块空野地后再发起迁城。 |
20693
+ | `MOVE_CITY_TOO_CLOSE` | (v91,AISLG-220)目标离其他账号的城池格(分城、名城含在内)不足 3 格(Chebyshev 距离)。自己的城不受此限。 | 选离他人城池至少 3 格的空野地;随机迁不受此限。 |
20694
+ | `MOVE_CITY_NO_SPACE` | (v91,AISLG-220)随机迁城时世界中已没有可选的空野地。 | 改用指定坐标迁城(高级迁城令)选一块空野地,或等世界有空地后再试。 |
20695
+ | `TILE_UNEXPLORED` | 该地块在战争迷雾中未探索,且不在任何视野来源(城池 / 领地 / 行军 / 盟友城池格)覆盖内,服务端不返回它的任何信息(v92,AISLG-224)。仅在 fog_enabled 开启时出现。 | 先派斥候或部队去这个方向探索(派去未探索坐标的出征本身允许,盲打时前端应提示“目标在迷雾中”)。也可以改查已探索的格子。 |
20696
+ | `MOVE_CITY_TILE_UNEXPLORED` | 高级迁城令(指定坐标)的目标格未探索,也不在实时视野内,无法指定为迁城目标(v92,AISLG-224)。随机迁城令不受影响。 | 先探索目标区域(派斥候或部队去那里),或改用随机迁城令。 |
20697
+ | `MOVE_CITY_ATTACK_LOCK` | (v91,AISLG-220)指定坐标迁城后 12 小时内,这座城的掠夺 / 占领 / 侦察 / 派协防(以及其他攻击类出征)被拒;响应附 retryAfterSeconds。运输、调兵、增援自己名下野地与召回不受限。 | 等待 retryAfterSeconds 之后再出征打别人;期间可以正常运输、调兵与增援。 |
20286
20698
  | `INTERNAL` | 服务端内部错误。 | 可稍后重试同一请求;持续出现时向运营方反馈。INTERNAL 可能出现在任何请求的响应中。 |
20287
20699
 
20288
20700
  ## 5. 完整示例会话
@@ -21872,7 +22284,7 @@ LOGOUT 吊销本连接登录所用的令牌,服务端随即关闭连接(clos
21872
22284
  - 只加不改:已发布的协议号、字段与错误码只新增、不删除、不改变类型与语义。
21873
22285
  - 新增字段不视为破坏兼容:消费方应容忍请求与响应中出现文档未列出的字段。
21874
22286
  - 必须破坏语义时启用新的协议号承载新行为,旧协议号保留原语义直至正式公告下线。
21875
- - 协议版本随对外协议内容的每次变化递增;当前为 88。
22287
+ - 协议版本随对外协议内容的每次变化递增;当前为 92。
21876
22288
  - Agent 可在启动时请求 `GET /agent-api.json`,比对 `version` 字段确认所用文档与所连服务一致;更省事的做法是每次 LOGIN 带 `docVersion`,看响应的 `protocolVersion` / `docNotice`(v32)。
21877
22289
  - 增量变更:`GET /agent-api/changes/{since}`(也接受 `?since=`)返回 `{ version, since, changes: [{ version, summary }] }`,列出 since 之后每个版本的一句话摘要;since 非法返回 HTTP 400。
21878
22290