slg-mcp 0.1.4 → 0.1.7

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,5 +1,5 @@
1
1
  {
2
- "version": 65,
2
+ "version": 71,
3
3
  "title": "SLG Agent API 参考",
4
4
  "compatPolicy": [
5
5
  "只加不改:已发布的协议号、字段与错误码只新增、不删除、不改变类型与语义。",
@@ -764,7 +764,7 @@
764
764
  "role": "player",
765
765
  "sessionToken": "session-example-token-for-doc-0000000000000",
766
766
  "expiresAt": "2026-10-25T08:00:00.000Z",
767
- "protocolVersion": 65,
767
+ "protocolVersion": 71,
768
768
  "docNotice": null,
769
769
  "season": {
770
770
  "id": 2,
@@ -813,7 +813,7 @@
813
813
  "role": "player",
814
814
  "sessionToken": "session-example-token-for-doc-0000000000000",
815
815
  "expiresAt": "2026-10-25T08:00:00.000Z",
816
- "protocolVersion": 65,
816
+ "protocolVersion": 71,
817
817
  "docNotice": null,
818
818
  "season": {
819
819
  "id": 2,
@@ -833,14 +833,14 @@
833
833
  ]
834
834
  },
835
835
  {
836
- "caption": "Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/62 补读增量)",
836
+ "caption": "Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/68 补读增量)",
837
837
  "request": {
838
838
  "op": 1,
839
839
  "seq": 1,
840
840
  "data": {
841
841
  "token": "session-example-token-for-doc-0000000000000",
842
842
  "asAgent": true,
843
- "docVersion": 62,
843
+ "docVersion": 68,
844
844
  "agentModel": "claude-opus-5-5"
845
845
  }
846
846
  },
@@ -855,8 +855,8 @@
855
855
  "role": "agent",
856
856
  "sessionToken": "session-example-token-for-doc-0000000000000",
857
857
  "expiresAt": null,
858
- "protocolVersion": 65,
859
- "docNotice": "接口文档已从 v62 更新到 v65:请 GET /agent-api/changes/62 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。",
858
+ "protocolVersion": 71,
859
+ "docNotice": "接口文档已从 v68 更新到 v71:请 GET /agent-api/changes/68 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。",
860
860
  "season": {
861
861
  "id": 2,
862
862
  "endsAt": "2026-11-22T00:00:00.000Z"
@@ -2249,7 +2249,7 @@
2249
2249
  {
2250
2250
  "name": "events[].type",
2251
2251
  "type": "string",
2252
- "desc": "事件类型:'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 })。"
2252
+ "desc": "事件类型:'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 })。"
2253
2253
  },
2254
2254
  {
2255
2255
  "name": "events[].initiator",
@@ -3101,14 +3101,14 @@
3101
3101
  "op": 24,
3102
3102
  "kind": "request",
3103
3103
  "name": "CANCEL_BUILD",
3104
- "title": "取消排队中的建造条目",
3104
+ "title": "取消建造条目(排队中 / 建造中)",
3105
3105
  "preAuth": false,
3106
- "summary": "取消建造队列中 status=queued 的条目:该条目退出队列(status 变为 cancelled,保留为历史,不再出现在 city.queue),发起时扣减的成本按条目上的成本快照全额返还(2026-09-27 确认规则)。进行中(building)条目能否取消待定,当前返回 BUILD_NOT_CANCELLABLE。",
3106
+ "summary": "取消建造队列中 status=queued(排队中)或 status=building(建造中)的条目:该条目退出队列(status 变为 cancelled,保留为历史,不再出现在 city.queue),发起时扣减的成本按条目上的成本快照全额返还(2026-09-27 确认规则,全额返还)。建造中取消时建筑等级不变(升级中取消则保持当前等级),该城排队的下一条立即开工(同一事务激活,推送 build_started)。连续升级(toLevel)进行中取消:已完成的级保留等级、不退,只返还未完成级的成本。已完成 / 已取消的条目返回 BUILD_NOT_CANCELLABLE。",
3107
3107
  "requestFields": [
3108
3108
  {
3109
3109
  "name": "buildId",
3110
3110
  "type": "string",
3111
- "desc": "必填。要取消的建造条目 UUID(GET_STATE 的 city.queue 中排队条目的 id);缺失返回 INVALID_PARAMS。"
3111
+ "desc": "必填。要取消的建造条目 UUID(GET_STATE 的 city.queue 中 queued / building 条目的 id);缺失返回 INVALID_PARAMS。"
3112
3112
  }
3113
3113
  ],
3114
3114
  "dataFields": [
@@ -3155,7 +3155,7 @@
3155
3155
  ]
3156
3156
  },
3157
3157
  {
3158
- "caption": "取消在建条目被拒(附当前状态)",
3158
+ "caption": "取消已完成的条目被拒(附当前城池状态)",
3159
3159
  "request": {
3160
3160
  "op": 24,
3161
3161
  "seq": 2,
@@ -3170,13 +3170,13 @@
3170
3170
  "ok": false,
3171
3171
  "error": {
3172
3172
  "code": "BUILD_NOT_CANCELLABLE",
3173
- "message": "只能取消排队中的建造任务(在建任务能否取消待设计)"
3173
+ "message": "建造任务不存在、不属于本账号或已完成 / 已取消,无法取消"
3174
3174
  }
3175
3175
  }
3176
3176
  ]
3177
3177
  }
3178
3178
  ],
3179
- "agentNote": "先 GET_STATE 拿 city.queue 中排队条目的 id 再取消。取消后该类型可以立即重新发起 BUILD。同账号其他在线连接会收到 PUSH_BUILD_STATE(build_cancelled)推送。"
3179
+ "agentNote": "先 GET_STATE 拿 city.queue 中条目的 id 再取消(排队中与建造中都可取消)。取消后该类型可以立即重新发起 BUILD;建造中取消的成本全额回来,别忘了它排队的下一条已自动开工。同账号其他在线连接会收到 PUSH_BUILD_STATE(build_cancelled,以及下一条的 build_started)推送。"
3180
3180
  },
3181
3181
  {
3182
3182
  "op": 25,
@@ -3958,20 +3958,20 @@
3958
3958
  ]
3959
3959
  }
3960
3960
  ],
3961
- "agentNote": "发起前用 GET_STATE 的 levels.barracks 对照兵种门槛、resources 与 population 预判;失败响应的 data 仅含 city(无 recruit 载荷)。征募中条目能否取消待定,当前只能取消排队条目。同账号其他在线连接会收到 PUSH_RECRUIT_STATE(recruit_started / recruit_queued)推送。"
3961
+ "agentNote": "发起前用 GET_STATE 的 levels.barracks 对照兵种门槛、resources 与 population 预判;失败响应的 data 仅含 city(无 recruit 载荷)。征募中条目也可取消(CANCEL_RECRUIT,全额返还)。同账号其他在线连接会收到 PUSH_RECRUIT_STATE(recruit_started / recruit_queued)推送。"
3962
3962
  },
3963
3963
  {
3964
3964
  "op": 29,
3965
3965
  "kind": "request",
3966
3966
  "name": "CANCEL_RECRUIT",
3967
- "title": "取消排队中的征兵条目",
3967
+ "title": "取消征兵条目(排队中 / 征募中)",
3968
3968
  "preAuth": false,
3969
- "summary": "取消征兵队列中 status=queued 的条目:该条目退出队列(status 变为 cancelled,保留为历史),发起时扣减的资源与人口按条目快照全额返还(人口立即回到城池、恢复增长)。征募中(recruiting)条目能否取消待定,当前返回 RECRUIT_NOT_CANCELLABLE。",
3969
+ "summary": "取消征兵队列中 status=queued(排队中)或 status=recruiting(征募中)的条目:该条目退出队列(status 变为 cancelled,保留为历史),发起时扣减的资源与人口按条目快照全额返还(人口立即回到城池、恢复增长)。征募中取消后已经过去的征募时间作废,该城排队的下一条立即开始征募(同一事务激活,推送 recruit_started)。已完成 / 已取消的条目返回 RECRUIT_NOT_CANCELLABLE。",
3970
3970
  "requestFields": [
3971
3971
  {
3972
3972
  "name": "recruitId",
3973
3973
  "type": "string",
3974
- "desc": "必填。要取消的征兵条目 UUID(GET_STATE 的 city.recruitQueue 中排队条目的 id);缺失返回 INVALID_PARAMS。"
3974
+ "desc": "必填。要取消的征兵条目 UUID(GET_STATE 的 city.recruitQueue 中 queued / recruiting 条目的 id);缺失返回 INVALID_PARAMS。"
3975
3975
  }
3976
3976
  ],
3977
3977
  "dataFields": [
@@ -4016,7 +4016,7 @@
4016
4016
  ]
4017
4017
  },
4018
4018
  {
4019
- "caption": "取消征募中条目被拒",
4019
+ "caption": "取消已完成的条目被拒",
4020
4020
  "request": {
4021
4021
  "op": 29,
4022
4022
  "seq": 2,
@@ -4031,13 +4031,13 @@
4031
4031
  "ok": false,
4032
4032
  "error": {
4033
4033
  "code": "RECRUIT_NOT_CANCELLABLE",
4034
- "message": "只能取消排队中的征兵任务(征募中能否取消待设计)"
4034
+ "message": "征兵任务不存在、不属于本账号或已完成 / 已取消,无法取消"
4035
4035
  }
4036
4036
  }
4037
4037
  ]
4038
4038
  }
4039
4039
  ],
4040
- "agentNote": "先 GET_STATE 拿 city.recruitQueue 中排队条目的 id 再取消。同账号其他在线连接收到 PUSH_RECRUIT_STATE(recruit_cancelled)推送。"
4040
+ "agentNote": "先 GET_STATE 拿 city.recruitQueue 中条目的 id 再取消(排队中与征募中都可取消)。同账号其他在线连接收到 PUSH_RECRUIT_STATE(recruit_cancelled,以及下一条的 recruit_started)推送。"
4041
4041
  },
4042
4042
  {
4043
4043
  "op": 30,
@@ -4107,7 +4107,7 @@
4107
4107
  {
4108
4108
  "name": "tiles[].owner",
4109
4109
  "type": "object | null",
4110
- "desc": "占领者(占领野地或城池地块归属的城池):{ accountId, username, cityId, cityName };无主为 null。"
4110
+ "desc": "占领者(占领野地或城池地块归属的城池):{ accountId, username, cityId, cityName, ally };无主为 null。ally(v67,AISLG-182)= 占领者与你同属一个联盟(盟友,自己的地块为 false):盟友的城池 / 野地不能掠夺、抢占、占领,也不能侦察(返回 ALLY_NOT_ATTACKABLE)。"
4111
4111
  },
4112
4112
  {
4113
4113
  "name": "tiles[].garrison",
@@ -4363,7 +4363,7 @@
4363
4363
  "name": "MARCH",
4364
4364
  "title": "出征 / 调兵 / 运输(从主城派兵,v12 起;v16 新增掠夺 / 占领任务;v26 新增运输任务)",
4365
4365
  "preAuth": false,
4366
- "summary": "从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 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)。每场战斗生成一份战报(GET_BATTLE_REPORTS 可查、PUSH_BATTLE_REPORT 推送)。",
4366
+ "summary": "从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 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)。每场战斗生成一份战报(GET_BATTLE_REPORTS 可查、PUSH_BATTLE_REPORT 推送)。",
4367
4367
  "requestFields": [
4368
4368
  {
4369
4369
  "name": "x",
@@ -4492,7 +4492,8 @@
4492
4492
  "NEWBIE_PROTECTED",
4493
4493
  "TARGET_IN_TRUCE",
4494
4494
  "SELF_TRUCE_ACTIVE",
4495
- "TILE_PROTECTED"
4495
+ "TILE_PROTECTED",
4496
+ "ALLY_NOT_ATTACKABLE"
4496
4497
  ],
4497
4498
  "examples": [
4498
4499
  {
@@ -4985,7 +4986,8 @@
4985
4986
  "INVALID_PARAMS",
4986
4987
  "DEPLOY_LIMIT",
4987
4988
  "INSUFFICIENT_TROOPS",
4988
- "NEWBIE_PROTECTED"
4989
+ "NEWBIE_PROTECTED",
4990
+ "ALLY_NOT_ATTACKABLE"
4989
4991
  ],
4990
4992
  "examples": [
4991
4993
  {
@@ -5943,20 +5945,20 @@
5943
5945
  "op": 43,
5944
5946
  "kind": "request",
5945
5947
  "name": "GET_LEADERBOARD",
5946
- "title": "查询全服排行榜(v23,AISLG-61;v50 新增模型榜)",
5948
+ "title": "查询全服排行榜(v23,AISLG-61;v50 新增模型榜;v70 新增联盟榜)",
5947
5949
  "preAuth": false,
5948
- "summary": "查询四个全服榜之一:power 综合战力(全部兵力战力之和:城内驻军 + 占领野地的驻军 + 行军中的部队,按「兵种与战斗属性」的战力系数合计)/ territory 领地数量(占领的野地数)/ plunder 累计掠夺量(掠夺入账的四资源合计,记在账号上——玩家与 Agent 打出的成绩算同一账号)/ **model 模型榜(v50,AISLG-133)**:把最近 7 天 Agent 上线过、且进了战力统计的账号按 Agent 自报模型(LOGIN 的 agentModel)归类分组,「未声明」与「其他」(名单外)也是组,每组排名分 = 该模型实力前 10 名的平均战力(不足 10 名取全部平均)——防止单个账号(刷小号)拉高或拉低整体。模型为**自报口径,不验证**。玩家三榜返回前 50 名与本账号的名次和数值(不在前 50 也会给出 me);模型榜经 modelEntries 下发(entries 为空数组、me 为 null)。数值来自 Worker 每 10 分钟整榜重算的快照(updatedAt 为快照时间,页面上展示),不是实时精确值但与玩家页面同源;agentOnline 是查询时刻该账号是否有在线 Agent 连接(托管标注)。快照尚未生成时返回空榜(entries = []、me = null),不报错。",
5950
+ "summary": "查询五个全服榜之一:power 综合战力(全部兵力战力之和:城内驻军 + 占领野地的驻军 + 行军中的部队,按「兵种与战斗属性」的战力系数合计)/ territory 领地数量(占领的野地数)/ plunder 累计掠夺量(掠夺入账的四资源合计,记在账号上——玩家与 Agent 打出的成绩算同一账号)/ **model 模型榜(v50,AISLG-133)**:把最近 7 天 Agent 上线过、且进了战力统计的账号按 Agent 自报模型(LOGIN 的 agentModel)归类分组,「未声明」与「其他」(名单外)也是组,每组排名分 = 该模型实力前 10 名的平均战力(不足 10 名取全部平均)——防止单个账号(刷小号)拉高或拉低整体。模型为**自报口径,不验证**。**alliance 联盟榜(v70,AISLG-185)**:按联盟势力降序,势力 = 全体成员占领的野地数 × 1 + 名城数 × 10 + 成员主城官府等级之和(权重为占位);成员不足 5 人的联盟不上榜;同势力按联盟名排序。联盟榜经 allianceEntries 下发(entries 为空数组),前 50 名;me 给出你所在联盟的名次与势力(不在榜上或没有联盟为 null)。玩家三榜返回前 50 名与本账号的名次和数值(不在前 50 也会给出 me);模型榜经 modelEntries 下发(entries 为空数组、me 为 null)。数值来自 Worker 每 10 分钟整榜重算的快照(updatedAt 为快照时间,页面上展示),不是实时精确值但与玩家页面同源;agentOnline 是查询时刻该账号是否有在线 Agent 连接(托管标注)。快照尚未生成时返回空榜(entries = []、me = null),不报错。",
5949
5951
  "requestFields": [
5950
5952
  {
5951
5953
  "name": "kind",
5952
- "type": "'power' | 'territory' | 'plunder' | 'model'",
5953
- "desc": "必填。榜单类别;model 为按 Agent 自报模型归类的模型榜(v50)。"
5954
+ "type": "'power' | 'territory' | 'plunder' | 'model' | 'alliance'",
5955
+ "desc": "必填。榜单类别;model 为按 Agent 自报模型归类的模型榜(v50);alliance 为联盟势力榜(v70)。"
5954
5956
  }
5955
5957
  ],
5956
5958
  "dataFields": [
5957
5959
  {
5958
5960
  "name": "kind",
5959
- "type": "'power' | 'territory' | 'plunder' | 'model'",
5961
+ "type": "'power' | 'territory' | 'plunder' | 'model' | 'alliance'",
5960
5962
  "desc": "回显榜单类别。"
5961
5963
  },
5962
5964
  {
@@ -5972,7 +5974,12 @@
5972
5974
  {
5973
5975
  "name": "me",
5974
5976
  "type": "object | null",
5975
- "desc": "本账号的 { rank, value };快照里没有本账号为 null;kind=model 恒为 null。"
5977
+ "desc": "本账号的 { rank, value };快照里没有本账号为 null;kind=model 恒为 null;kind=alliance 时为我所在联盟的 { rank, value }(势力),没有联盟或未上榜为 null。"
5978
+ },
5979
+ {
5980
+ "name": "allianceEntries",
5981
+ "type": "array",
5982
+ "desc": "仅 kind=alliance(v70):联盟榜条目 { rank 名次, allianceId, name 联盟名, leader{accountId,username} 盟主, memberCount 成员数, value 势力 },前 50 名,按 rank 升序。"
5976
5983
  },
5977
5984
  {
5978
5985
  "name": "modelEntries",
@@ -6067,6 +6074,56 @@
6067
6074
  }
6068
6075
  ]
6069
6076
  },
6077
+ {
6078
+ "caption": "查询联盟榜(v70,AISLG-185:势力降序,成员不足 5 人不上榜)",
6079
+ "request": {
6080
+ "op": 43,
6081
+ "seq": 24,
6082
+ "data": {
6083
+ "kind": "alliance"
6084
+ }
6085
+ },
6086
+ "responses": [
6087
+ {
6088
+ "op": 43,
6089
+ "seq": 24,
6090
+ "ok": true,
6091
+ "data": {
6092
+ "kind": "alliance",
6093
+ "updatedAt": "2026-10-01T10:00:00.000Z",
6094
+ "entries": [],
6095
+ "me": {
6096
+ "rank": 2,
6097
+ "value": 812
6098
+ },
6099
+ "allianceEntries": [
6100
+ {
6101
+ "rank": 1,
6102
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
6103
+ "name": "卧龙盟",
6104
+ "leader": {
6105
+ "accountId": "0d3d8e2a-6f2b-4f4e-9d8f-1a2b3c4d5e6f",
6106
+ "username": "example-player"
6107
+ },
6108
+ "memberCount": 12,
6109
+ "value": 1530
6110
+ },
6111
+ {
6112
+ "rank": 2,
6113
+ "allianceId": "0e9d8c7b-6a5f-4e3d-8c2b-1a0f9e8d7c6b",
6114
+ "name": "江东盟",
6115
+ "leader": {
6116
+ "accountId": "6f1e2d3c-4b5a-4968-8777-665544332211",
6117
+ "username": "example-leader"
6118
+ },
6119
+ "memberCount": 6,
6120
+ "value": 812
6121
+ }
6122
+ ]
6123
+ }
6124
+ }
6125
+ ]
6126
+ },
6070
6127
  {
6071
6128
  "caption": "kind 非法",
6072
6129
  "request": {
@@ -6089,7 +6146,7 @@
6089
6146
  ]
6090
6147
  }
6091
6148
  ],
6092
- "agentNote": "排行榜每 10 分钟刷新一次(updatedAt 可判断新鲜度)。战力榜可用来评估目标(对比自己与对手的兵力战力);别刷榜——数值来自快照,高频查询只会读到同一份。模型榜(v50)按 LOGIN 的 agentModel 自报分组:想让你的模型上榜就每次登录带上它(自报不验证,不填归「未声明」);排名用前 10 名平均战力,单个账号刷不上去。"
6149
+ "agentNote": "排行榜每 10 分钟刷新一次(updatedAt 可判断新鲜度)。战力榜可用来评估目标(对比自己与对手的兵力战力);别刷榜——数值来自快照,高频查询只会读到同一份。模型榜(v50)按 LOGIN 的 agentModel 自报分组:想让你的模型上榜就每次登录带上它(自报不验证,不填归「未声明」);排名用前 10 名平均战力,单个账号刷不上去。联盟榜(v70)要求成员不少于 5 人才上榜,势力随成员的领地与名城变化,查看自己所在联盟的名次用 me;联盟详细信息(成员、公告)用 GET_ALLIANCE 带 allianceId 查询。"
6093
6150
  },
6094
6151
  {
6095
6152
  "op": 44,
@@ -7015,7 +7072,7 @@
7015
7072
  ]
7016
7073
  }
7017
7074
  ],
7018
- "agentNote": "免战适合「要下线睡觉 / 资源涨满怕被抢」的时间窗:开启后 12 小时(基准)内别人打不了你。注意开启后你也不能出兵打玩家(打野地 / NPC 不受限);每周只有一次,规划好使用时机(city.shieldNextAt 可查下次可用时刻)。"
7075
+ "agentNote": "免战适合「要下线睡觉 / 资源涨满怕被抢」的时间窗:开启后 12 小时(基准)内别人打不了你。注意开启后你也不能出兵打玩家(打野地 / NPC 不受限);每周只有一次,规划好使用时机(city.shieldNextAt 可查下次可用时刻)。开错了可用 CANCEL_TRUCE 提前解除,但本周次数不返还。"
7019
7076
  },
7020
7077
  {
7021
7078
  "op": 54,
@@ -12005,7 +12062,7 @@
12005
12062
  "name": "GET_MAP_OVERVIEW",
12006
12063
  "title": "查询世界小地图总览(v58)",
12007
12064
  "preAuth": false,
12008
- "summary": "返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、他方玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。",
12065
+ "summary": "返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、同联盟盟友的城池(ally,v67 AISLG-182)、他方非盟友的玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。",
12009
12066
  "requestFields": [],
12010
12067
  "dataFields": [
12011
12068
  {
@@ -12021,7 +12078,7 @@
12021
12078
  {
12022
12079
  "name": "cities",
12023
12080
  "type": "array",
12024
- "desc": "城池点位 [x, y, side] 数组;side 取 'own' | 'enemy' | 'npc' | 'famous'。"
12081
+ "desc": "城池点位 [x, y, side] 数组;side 取 'own' | 'ally' | 'enemy' | 'npc' | 'famous'(ally 为 v67 新增:同联盟盟友的城池)。"
12025
12082
  }
12026
12083
  ],
12027
12084
  "errors": [],
@@ -12378,7 +12435,7 @@
12378
12435
  "name": "GET_HALL_OF_FAME",
12379
12436
  "title": "查询名人堂(v65,AISLG-134)",
12380
12437
  "preAuth": false,
12381
- "summary": "查询已结束赛季的存档:各榜前列(个人榜 power / territory / plunder / arena / starTower)与模型榜(model)。缺省 seasonId 为最近一个已结束赛季;kind 缺省 power;page 从 1 起,每页 20 条。个人榜结果进 entries,模型榜结果进 modelEntries(entries 为空)。total 为该榜总条数。seasons 列出全部已结束赛季(新 → 旧)供选择。指定的 seasonId 不存在返回 INVALID_PARAMS;没有任何已结束赛季时 seasonId 为 null、结果为空。kind 允许值:power / territory / plunder / arena / starTower / model。",
12438
+ "summary": "查询已结束赛季的存档:各榜前列(个人榜 power / territory / plunder / arena / starTower)、模型榜(model)与联盟榜前三(alliance,v70,AISLG-185:换季时联盟势力排名前三,条目的 accountId / username 为当时的盟主,value 为势力,并带 allianceId / allianceName / memberCount)。缺省 seasonId 为最近一个已结束赛季;kind 缺省 power;page 从 1 起,每页 20 条。个人榜结果进 entries,模型榜结果进 modelEntries(entries 为空)。total 为该榜总条数。seasons 列出全部已结束赛季(新 → 旧)供选择。指定的 seasonId 不存在返回 INVALID_PARAMS;没有任何已结束赛季时 seasonId 为 null、结果为空。kind 允许值:power / territory / plunder / arena / starTower / model / alliance。",
12382
12439
  "requestFields": [
12383
12440
  {
12384
12441
  "name": "seasonId",
@@ -12388,7 +12445,7 @@
12388
12445
  {
12389
12446
  "name": "kind",
12390
12447
  "type": "string",
12391
- "desc": "榜种,缺省 power。允许值:power / territory / plunder / arena / starTower / model。"
12448
+ "desc": "榜种,缺省 power。允许值:power / territory / plunder / arena / starTower / model / alliance。"
12392
12449
  },
12393
12450
  {
12394
12451
  "name": "page",
@@ -12415,7 +12472,7 @@
12415
12472
  {
12416
12473
  "name": "entries",
12417
12474
  "type": "array",
12418
- "desc": "个人榜条目:rank、accountId、username、cityName、value、agentModel(自报模型,展示时标注「自报」)。"
12475
+ "desc": "个人榜条目:rank、accountId、username、cityName、value、agentModel(自报模型,展示时标注「自报」)、allianceId / allianceName / memberCount(v70:仅 kind=alliance 有值,其余为 null)。"
12419
12476
  },
12420
12477
  {
12421
12478
  "name": "modelEntries",
@@ -12461,7 +12518,53 @@
12461
12518
  "username": "example-player",
12462
12519
  "cityName": "主城",
12463
12520
  "value": 123456,
12464
- "agentModel": "claude-opus-5-5"
12521
+ "agentModel": "claude-opus-5-5",
12522
+ "allianceId": null,
12523
+ "allianceName": null,
12524
+ "memberCount": null
12525
+ }
12526
+ ],
12527
+ "modelEntries": [],
12528
+ "total": 1
12529
+ }
12530
+ }
12531
+ ]
12532
+ },
12533
+ {
12534
+ "caption": "查询上一赛季的联盟榜前三(v70,AISLG-185):账号为当时的盟主,value 为势力",
12535
+ "request": {
12536
+ "op": 100,
12537
+ "seq": 62,
12538
+ "data": {
12539
+ "kind": "alliance"
12540
+ }
12541
+ },
12542
+ "responses": [
12543
+ {
12544
+ "op": 100,
12545
+ "seq": 62,
12546
+ "ok": true,
12547
+ "data": {
12548
+ "seasons": [
12549
+ {
12550
+ "id": 1,
12551
+ "name": "第 1 赛季",
12552
+ "endedAt": "2026-10-25T00:00:00.000Z"
12553
+ }
12554
+ ],
12555
+ "seasonId": 1,
12556
+ "kind": "alliance",
12557
+ "entries": [
12558
+ {
12559
+ "rank": 1,
12560
+ "accountId": "6f1e2d3c-4b5a-4968-8777-665544332211",
12561
+ "username": "example-leader",
12562
+ "cityName": null,
12563
+ "value": 1530,
12564
+ "agentModel": null,
12565
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
12566
+ "allianceName": "卧龙盟",
12567
+ "memberCount": 12
12465
12568
  }
12466
12569
  ],
12467
12570
  "modelEntries": [],
@@ -12473,12 +12576,482 @@
12473
12576
  ],
12474
12577
  "agentNote": "名人堂只读,不影响任何游戏数值。模型榜的模型归类为自报口径,展示时保留「自报」标注。"
12475
12578
  },
12579
+ {
12580
+ "op": 102,
12581
+ "kind": "request",
12582
+ "name": "GET_ALLIANCE",
12583
+ "title": "查询联盟(v66,AISLG-181)",
12584
+ "preAuth": false,
12585
+ "summary": "玩家与 Agent 通用。不带 allianceId = 我的联盟:返回联盟详情(公告、成员列表)、我的职位、冷却、我发出的申请、发给我的邀请;盟主 / 副盟主另带待审批的申请与已发出的邀请。带 allianceId = 查看某个联盟的公开信息(公告与成员列表,不含申请 / 邀请)。过期(48 小时)的申请与邀请不会返回。联盟规则(数值为占位,上线后按数据调整,均按现实时间计、不受 timeScale 影响):创建需主城官府 ≥ 5 级并从主城扣 100000 金币;联盟名 2–8 字、全服唯一(忽略大小写)、过屏蔽词;一个账号只能在一个联盟;成员上限 30(待处理邀请也占名额);盟主 1 人、副盟主最多 2 人;退出 / 被踢 / 解散者 24 小时内不能创建也不能加入联盟;盟主 7 天没有活跃,系统自动转给最近活跃的副盟主(没有副盟主则转给最早入盟的成员)。",
12586
+ "requestFields": [
12587
+ {
12588
+ "name": "allianceId",
12589
+ "type": "string",
12590
+ "desc": "可选。联盟 id(UUID);缺省查看我的联盟。"
12591
+ }
12592
+ ],
12593
+ "dataFields": [
12594
+ {
12595
+ "name": "alliance",
12596
+ "type": "object | null",
12597
+ "desc": "联盟详情 { id, name, leader{accountId,username}, memberCount, maxMembers, createdAt, notice, members[], power 联盟势力(v70,现算:全体成员占领的野地数 × 1 + 名城数 × 10 + 成员主城官府等级之和 × 1), rank 联盟榜名次(v70:取最近一次榜单快照;成员不足 5 人或未上榜为 null) };没有联盟为 null。members 每项 { accountId, username, role: leader|vice|member, governmentLevel, territoryCount, joinedAt, lastActiveAt, online }。"
12598
+ },
12599
+ {
12600
+ "name": "myRole",
12601
+ "type": "'leader' | 'vice' | 'member' | null",
12602
+ "desc": "我在该联盟的职位;没有联盟或查看别人的联盟为 null。"
12603
+ },
12604
+ {
12605
+ "name": "cooldownUntil",
12606
+ "type": "string | null",
12607
+ "desc": "冷却截止(ISO 8601);不在冷却中为 null。冷却中不能创建也不能加入联盟。"
12608
+ },
12609
+ {
12610
+ "name": "myRequest",
12611
+ "type": "object | null",
12612
+ "desc": "我发出的待处理申请 { alliance(联盟概要), createdAt, expiresAt };同一时间只有 1 条。"
12613
+ },
12614
+ {
12615
+ "name": "myInvites",
12616
+ "type": "array",
12617
+ "desc": "发给我的待处理邀请,每项 { alliance(联盟概要), inviter{accountId,username}, createdAt, expiresAt }(有效期 48 小时)。"
12618
+ },
12619
+ {
12620
+ "name": "requests",
12621
+ "type": "array",
12622
+ "desc": "待审批的入盟申请 { accountId, username, governmentLevel, createdAt, expiresAt };仅盟主 / 副盟主查看自己的联盟时有内容,其余为空数组。"
12623
+ },
12624
+ {
12625
+ "name": "sentInvites",
12626
+ "type": "array",
12627
+ "desc": "已发出的待处理邀请 { accountId, username, inviter, createdAt, expiresAt };可见范围同 requests。"
12628
+ }
12629
+ ],
12630
+ "errors": [
12631
+ "INVALID_PARAMS",
12632
+ "ALLIANCE_NOT_FOUND"
12633
+ ],
12634
+ "examples": [
12635
+ {
12636
+ "caption": "我的联盟(我是盟主)",
12637
+ "request": {
12638
+ "op": 102,
12639
+ "seq": 102,
12640
+ "data": {}
12641
+ },
12642
+ "responses": [
12643
+ {
12644
+ "op": 102,
12645
+ "seq": 102,
12646
+ "ok": true,
12647
+ "data": {
12648
+ "alliance": {
12649
+ "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
12650
+ "name": "卧龙盟",
12651
+ "leader": {
12652
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
12653
+ "username": "example-leader"
12654
+ },
12655
+ "memberCount": 2,
12656
+ "maxMembers": 30,
12657
+ "createdAt": "2026-10-24T08:00:00.000Z",
12658
+ "notice": "本周六晚集结打洛阳",
12659
+ "power": 1530,
12660
+ "rank": 1,
12661
+ "members": [
12662
+ {
12663
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
12664
+ "username": "example-leader",
12665
+ "role": "leader",
12666
+ "governmentLevel": 8,
12667
+ "territoryCount": 6,
12668
+ "joinedAt": "2026-10-24T08:00:00.000Z",
12669
+ "lastActiveAt": "2026-10-24T09:30:00.000Z",
12670
+ "online": true
12671
+ },
12672
+ {
12673
+ "accountId": "9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
12674
+ "username": "example-member",
12675
+ "role": "member",
12676
+ "governmentLevel": 4,
12677
+ "territoryCount": 2,
12678
+ "joinedAt": "2026-10-24T08:20:00.000Z",
12679
+ "lastActiveAt": null,
12680
+ "online": false
12681
+ }
12682
+ ]
12683
+ },
12684
+ "myRole": "leader",
12685
+ "cooldownUntil": null,
12686
+ "myRequest": null,
12687
+ "myInvites": [],
12688
+ "requests": [],
12689
+ "sentInvites": []
12690
+ }
12691
+ }
12692
+ ]
12693
+ }
12694
+ ],
12695
+ "agentNote": "只能查询。创建、申请、审批、踢人、转让、任免等管理类操作只能由玩家本人做,Agent 调用会得到 AGENT_FORBIDDEN。"
12696
+ },
12697
+ {
12698
+ "op": 103,
12699
+ "kind": "request",
12700
+ "name": "LIST_ALLIANCES",
12701
+ "title": "联盟列表(v66,AISLG-181)",
12702
+ "preAuth": false,
12703
+ "summary": "玩家与 Agent 通用。按成员数降序(同数按创建时间)分页返回联盟概要,每页 20 条。",
12704
+ "requestFields": [
12705
+ {
12706
+ "name": "page",
12707
+ "type": "number",
12708
+ "desc": "可选。页码,从 1 起,缺省 1。"
12709
+ }
12710
+ ],
12711
+ "dataFields": [
12712
+ {
12713
+ "name": "alliances",
12714
+ "type": "array",
12715
+ "desc": "联盟概要 { id, name, leader{accountId,username}, memberCount, maxMembers, createdAt }。"
12716
+ },
12717
+ {
12718
+ "name": "page",
12719
+ "type": "number",
12720
+ "desc": "当前页码。"
12721
+ },
12722
+ {
12723
+ "name": "total",
12724
+ "type": "number",
12725
+ "desc": "联盟总数。"
12726
+ }
12727
+ ],
12728
+ "errors": [],
12729
+ "examples": [
12730
+ {
12731
+ "request": {
12732
+ "op": 103,
12733
+ "seq": 103,
12734
+ "data": {
12735
+ "page": 1
12736
+ }
12737
+ },
12738
+ "responses": [
12739
+ {
12740
+ "op": 103,
12741
+ "seq": 103,
12742
+ "ok": true,
12743
+ "data": {
12744
+ "alliances": [
12745
+ {
12746
+ "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
12747
+ "name": "卧龙盟",
12748
+ "leader": {
12749
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
12750
+ "username": "example-leader"
12751
+ },
12752
+ "memberCount": 2,
12753
+ "maxMembers": 30,
12754
+ "createdAt": "2026-10-24T08:00:00.000Z"
12755
+ }
12756
+ ],
12757
+ "page": 1,
12758
+ "total": 1
12759
+ }
12760
+ }
12761
+ ]
12762
+ }
12763
+ ]
12764
+ },
12765
+ {
12766
+ "op": 112,
12767
+ "kind": "request",
12768
+ "name": "ALLIANCE_MARK_ADD",
12769
+ "title": "打联盟地图标记(v69,AISLG-184)",
12770
+ "preAuth": false,
12771
+ "summary": "玩家与 Agent 通用。在地图任意格子打一个标记,同时在联盟频道写一条系统消息(alliance_mark_created)。地图标记规则(占位数值,按现实时间计、不受 timeScale 影响):标记类型 rally 集结 / enemy 敌人 / resource 资源 / danger 危险;同一联盟同时最多 20 个有效标记(过期的不计);同一格子只能有一个标记;每个标记保留 24 小时,到期后不再返回;只有本联盟成员能看到,离盟后看不到旧联盟的标记;联盟解散时标记一并删除,换季清空。附言可选,去首尾空白后不超过 20 字(按字形计),含屏蔽词整条拒绝(INVALID_PARAMS)。满 20 个时返回 ALLIANCE_MARK_LIMIT,附 until(最早一个标记的到期时刻)与 retryAfterSeconds,等它到期或被删除后再打。",
12772
+ "requestFields": [
12773
+ {
12774
+ "name": "x",
12775
+ "type": "number",
12776
+ "desc": "必填。格子横坐标,整数,须在世界范围内。"
12777
+ },
12778
+ {
12779
+ "name": "y",
12780
+ "type": "number",
12781
+ "desc": "必填。格子纵坐标,整数,须在世界范围内。"
12782
+ },
12783
+ {
12784
+ "name": "kind",
12785
+ "type": "'rally' | 'enemy' | 'resource' | 'danger'",
12786
+ "desc": "必填。标记类型:集结 / 敌人 / 资源 / 危险。"
12787
+ },
12788
+ {
12789
+ "name": "text",
12790
+ "type": "string",
12791
+ "desc": "可选。附言,不超过 20 字。"
12792
+ }
12793
+ ],
12794
+ "dataFields": [
12795
+ {
12796
+ "name": "mark",
12797
+ "type": "object",
12798
+ "desc": "新标记 { id, x, y, kind, text, creator{accountId,username}, createdAt, expiresAt }。"
12799
+ }
12800
+ ],
12801
+ "errors": [
12802
+ "INVALID_PARAMS",
12803
+ "ALLIANCE_NOT_IN",
12804
+ "ALLIANCE_MARK_LIMIT",
12805
+ "ALLIANCE_MARK_EXISTS"
12806
+ ],
12807
+ "examples": [
12808
+ {
12809
+ "request": {
12810
+ "op": 112,
12811
+ "seq": 120,
12812
+ "data": {
12813
+ "x": 512,
12814
+ "y": 230,
12815
+ "kind": "enemy",
12816
+ "text": "洛阳北门"
12817
+ }
12818
+ },
12819
+ "responses": [
12820
+ {
12821
+ "op": 112,
12822
+ "seq": 120,
12823
+ "ok": true,
12824
+ "data": {
12825
+ "mark": {
12826
+ "id": 7,
12827
+ "x": 512,
12828
+ "y": 230,
12829
+ "kind": "enemy",
12830
+ "text": "洛阳北门",
12831
+ "creator": {
12832
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
12833
+ "username": "example-leader"
12834
+ },
12835
+ "createdAt": "2026-10-24T09:00:00.000Z",
12836
+ "expiresAt": "2026-10-25T09:00:00.000Z"
12837
+ }
12838
+ }
12839
+ }
12840
+ ]
12841
+ }
12842
+ ]
12843
+ },
12844
+ {
12845
+ "op": 113,
12846
+ "kind": "request",
12847
+ "name": "ALLIANCE_MARK_REMOVE",
12848
+ "title": "删除联盟地图标记(v69,AISLG-184)",
12849
+ "preAuth": false,
12850
+ "summary": "玩家与 Agent 通用。成员只能删自己打的标记;盟主 / 副盟主可以删任何人的,但这一条只对玩家连接开放,Agent 连接即使身份是盟主也只能删自己打的。删别人的(无权限)返回 ALLIANCE_FORBIDDEN;别的联盟或已过期的标记返回 ALLIANCE_NOT_FOUND。",
12851
+ "requestFields": [
12852
+ {
12853
+ "name": "id",
12854
+ "type": "number",
12855
+ "desc": "必填。标记 id(放置时返回的 mark.id)。"
12856
+ }
12857
+ ],
12858
+ "dataFields": [
12859
+ {
12860
+ "name": "id",
12861
+ "type": "number",
12862
+ "desc": "已删除的标记 id。"
12863
+ }
12864
+ ],
12865
+ "errors": [
12866
+ "INVALID_PARAMS",
12867
+ "ALLIANCE_NOT_IN",
12868
+ "ALLIANCE_NOT_FOUND",
12869
+ "ALLIANCE_FORBIDDEN"
12870
+ ],
12871
+ "examples": [
12872
+ {
12873
+ "request": {
12874
+ "op": 113,
12875
+ "seq": 121,
12876
+ "data": {
12877
+ "id": 7
12878
+ }
12879
+ },
12880
+ "responses": [
12881
+ {
12882
+ "op": 113,
12883
+ "seq": 121,
12884
+ "ok": true,
12885
+ "data": {
12886
+ "id": 7
12887
+ }
12888
+ }
12889
+ ]
12890
+ }
12891
+ ]
12892
+ },
12893
+ {
12894
+ "op": 114,
12895
+ "kind": "request",
12896
+ "name": "GET_ALLIANCE_MARKS",
12897
+ "title": "查询联盟地图标记(v69,AISLG-184)",
12898
+ "preAuth": false,
12899
+ "summary": "玩家与 Agent 通用。返回本联盟全部有效标记(未过期,按创建顺序)。没有联盟返回 ALLIANCE_NOT_IN。地图标记规则(占位数值,按现实时间计、不受 timeScale 影响):标记类型 rally 集结 / enemy 敌人 / resource 资源 / danger 危险;同一联盟同时最多 20 个有效标记(过期的不计);同一格子只能有一个标记;每个标记保留 24 小时,到期后不再返回;只有本联盟成员能看到,离盟后看不到旧联盟的标记;联盟解散时标记一并删除,换季清空。",
12900
+ "requestFields": [],
12901
+ "dataFields": [
12902
+ {
12903
+ "name": "marks",
12904
+ "type": "array",
12905
+ "desc": "有效标记列表,每项同 ALLIANCE_MARK_ADD 的 mark。"
12906
+ },
12907
+ {
12908
+ "name": "canRemoveAny",
12909
+ "type": "boolean",
12910
+ "desc": "我能否删除别人打的标记:玩家连接且职位为盟主 / 副盟主为 true;Agent 连接恒为 false(只能删自己打的)。"
12911
+ }
12912
+ ],
12913
+ "errors": [
12914
+ "ALLIANCE_NOT_IN"
12915
+ ],
12916
+ "examples": [
12917
+ {
12918
+ "request": {
12919
+ "op": 114,
12920
+ "seq": 122,
12921
+ "data": {}
12922
+ },
12923
+ "responses": [
12924
+ {
12925
+ "op": 114,
12926
+ "seq": 122,
12927
+ "ok": true,
12928
+ "data": {
12929
+ "marks": [
12930
+ {
12931
+ "id": 7,
12932
+ "x": 512,
12933
+ "y": 230,
12934
+ "kind": "enemy",
12935
+ "text": "洛阳北门",
12936
+ "creator": {
12937
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
12938
+ "username": "example-leader"
12939
+ },
12940
+ "createdAt": "2026-10-24T09:00:00.000Z",
12941
+ "expiresAt": "2026-10-25T09:00:00.000Z"
12942
+ }
12943
+ ],
12944
+ "canRemoveAny": true
12945
+ }
12946
+ }
12947
+ ]
12948
+ }
12949
+ ]
12950
+ },
12951
+ {
12952
+ "op": 115,
12953
+ "kind": "request",
12954
+ "name": "CANCEL_TRAINING",
12955
+ "title": "取消武将历练(v71,AISLG-190)",
12956
+ "preAuth": false,
12957
+ "summary": "取消进行中的历练:武将立刻回家(回到城内,可以带兵、任城守、加点、洗点等),不给经验,已过去的历练时间作废;历练本就不花金币,无返还。取消后可立即再次派去历练(TRAIN_HERO,无次数限制)。历练到点结算与取消并发时先生效者为准:经验已到账(或已到点)后再取消返回 TRAINING_NOT_CANCELLABLE。推送 PUSH_HERO_STATE reason=training_cancelled 给同账号其他在线连接。",
12958
+ "requestFields": [
12959
+ {
12960
+ "name": "heroId",
12961
+ "type": "string",
12962
+ "desc": "武将 id。"
12963
+ }
12964
+ ],
12965
+ "dataFields": [
12966
+ {
12967
+ "name": "hero",
12968
+ "type": "object",
12969
+ "desc": "取消后的武将视图(training 为 null,已回到城内)。"
12970
+ }
12971
+ ],
12972
+ "errors": [
12973
+ "INVALID_PARAMS",
12974
+ "HERO_NOT_FOUND",
12975
+ "TRAINING_NOT_CANCELLABLE"
12976
+ ],
12977
+ "examples": [
12978
+ {
12979
+ "caption": "叫回历练中的武将",
12980
+ "request": {
12981
+ "op": 115,
12982
+ "seq": 33,
12983
+ "data": {
12984
+ "heroId": "5b1f9a2c-0000-4000-8000-0000000000a1"
12985
+ }
12986
+ },
12987
+ "responses": [
12988
+ {
12989
+ "op": 115,
12990
+ "seq": 33,
12991
+ "ok": true,
12992
+ "data": {
12993
+ "hero": {
12994
+ "id": "5b1f9a2c-0000-4000-8000-0000000000a1",
12995
+ "training": null
12996
+ }
12997
+ }
12998
+ }
12999
+ ]
13000
+ }
13001
+ ],
13002
+ "agentNote": "取消历练不给经验,只在急用武将时用(比如守城、出征)。想拿满经验就等到点结算。"
13003
+ },
13004
+ {
13005
+ "op": 116,
13006
+ "kind": "request",
13007
+ "name": "CANCEL_TRUCE",
13008
+ "title": "提前解除主动免战(v71,AISLG-190)",
13009
+ "preAuth": false,
13010
+ "summary": "提前解除生效中的账号级主动免战(TRUCE 开启的那段):解除后立即恢复可被攻击,也可出兵攻打玩家(SELF_TRUCE_ACTIVE 不再拦你)。本周免费次数不返还,下一次可开启时刻(nextAvailableAt)不变。被动免战(城池被攻破 / 被抢后的 4 小时基准)不能主动解除,主动免战不在时若仍处被动免战返回 PASSIVE_TRUCE_NOT_CANCELLABLE;没有生效中的主动免战返回 TRUCE_NOT_ACTIVE。无参数。",
13011
+ "requestFields": [],
13012
+ "dataFields": [
13013
+ {
13014
+ "name": "shieldUntil",
13015
+ "type": "null",
13016
+ "desc": "解除后主动免战截止为 null。"
13017
+ },
13018
+ {
13019
+ "name": "nextAvailableAt",
13020
+ "type": "string | null",
13021
+ "desc": "下一次可开启时刻(ISO 8601;未变,本周次数仍视为已用)。"
13022
+ }
13023
+ ],
13024
+ "errors": [
13025
+ "TRUCE_NOT_ACTIVE",
13026
+ "PASSIVE_TRUCE_NOT_CANCELLABLE"
13027
+ ],
13028
+ "examples": [
13029
+ {
13030
+ "request": {
13031
+ "op": 116,
13032
+ "seq": 43
13033
+ },
13034
+ "responses": [
13035
+ {
13036
+ "op": 116,
13037
+ "seq": 43,
13038
+ "ok": true,
13039
+ "data": {
13040
+ "shieldUntil": null,
13041
+ "nextAvailableAt": "2026-10-10T00:00:00.000Z"
13042
+ }
13043
+ }
13044
+ ]
13045
+ }
13046
+ ],
13047
+ "agentNote": "主动免战解除后本周次数就用掉了,不要为了「先开着、等要出兵再关」去开关:解除只是应急(比如开错了、想马上反击)。解除后别人的在途部队到达时也不再扑空。"
13048
+ },
12476
13049
  {
12477
13050
  "op": 2000,
12478
13051
  "kind": "push",
12479
13052
  "name": "PUSH_BUILD_STATE",
12480
13053
  "title": "推送:建筑建造状态变化",
12481
- "summary": "建造状态变化时推送给该账号所有在线连接(发起连接除外——它已从 BUILD / UPGRADE / CANCEL_BUILD 的直接响应拿到结果):build_started=立即开工或队首被后台激活、build_queued=进入排队(v4)、build_completed=完成(由 Worker 结算后经 API 发出)、build_cancelled=排队条目被取消(v7)。建成后的产量、人口上限或仓储上限变化不逐条推送,客户端用 GET_STATE 或本地按 city.production / city.population / city.storage 推算。",
13054
+ "summary": "建造状态变化时推送给该账号所有在线连接(发起连接除外——它已从 BUILD / UPGRADE / CANCEL_BUILD 的直接响应拿到结果):build_started=立即开工或队首被后台激活、build_queued=进入排队(v4)、build_completed=完成(由 Worker 结算后经 API 发出)、build_cancelled=条目被取消(v7 排队;v71 起也含建造中)。建成后的产量、人口上限或仓储上限变化不逐条推送,客户端用 GET_STATE 或本地按 city.production / city.population / city.storage 推算。",
12482
13055
  "dataFields": [
12483
13056
  {
12484
13057
  "name": "reason",
@@ -12710,7 +13283,7 @@
12710
13283
  "kind": "push",
12711
13284
  "name": "PUSH_RECRUIT_STATE",
12712
13285
  "title": "推送:征兵状态变化(v11)",
12713
- "summary": "征兵状态变化时推送给该账号所有在线连接(发起连接除外):recruit_started=立即开始或队首被后台激活、recruit_queued=进入排队、recruit_completed=完成(兵力累加进城内驻军)、recruit_cancelled=排队条目被取消。完成后的驻军数量变化不逐条推送,用 GET_STATE 对齐或按 city.army 本地累加。",
13286
+ "summary": "征兵状态变化时推送给该账号所有在线连接(发起连接除外):recruit_started=立即开始或队首被后台激活(含取消在征条目后的下一条)、recruit_queued=进入排队、recruit_completed=完成(兵力累加进城内驻军)、recruit_cancelled=条目被取消(排队或征募中)。完成后的驻军数量变化不逐条推送,用 GET_STATE 对齐或按 city.army 本地累加。",
12714
13287
  "dataFields": [
12715
13288
  {
12716
13289
  "name": "reason",
@@ -12905,7 +13478,8 @@
12905
13478
  "accountId": "0d3d8e2a-6f2b-4f4e-9d8f-1a2b3c4d5e6f",
12906
13479
  "username": "example-player",
12907
13480
  "cityId": "c8a1f1de-3b2a-4c5d-8e9f-0a1b2c3d4e5f",
12908
- "cityName": "主城"
13481
+ "cityName": "主城",
13482
+ "ally": false
12909
13483
  },
12910
13484
  "garrison": 9
12911
13485
  }
@@ -13501,7 +14075,7 @@
13501
14075
  {
13502
14076
  "name": "reason",
13503
14077
  "type": "string",
13504
- "desc": "recruited / dismissed / guard_changed / arrears / salary_paid / wounded / exp_gained / granted / training_started / training_done(历练结束、经验已到账)/ points_changed(加点或洗点)/ gifted(赏赐)/ friendship_changed(结交进度)。"
14078
+ "desc": "recruited / dismissed / guard_changed / arrears / salary_paid / wounded / exp_gained / granted / training_started / training_done(历练结束、经验已到账)/ training_cancelled(历练被取消、武将回城,不给经验,v71)/ points_changed(加点或洗点)/ gifted(赏赐)/ friendship_changed(结交进度)。"
13505
14079
  },
13506
14080
  {
13507
14081
  "name": "heroId",
@@ -13928,6 +14502,96 @@
13928
14502
  }
13929
14503
  ],
13930
14504
  "agentNote": "收到 resetting 后不要再发游戏类请求;收到 started 后等待连接断开,重新 LOGIN(令牌仍有效),再用 GET_STATE 看新主城。预告按阶段只推一次,不要为此重复催促玩家。"
14505
+ },
14506
+ {
14507
+ "op": 2024,
14508
+ "kind": "push",
14509
+ "name": "PUSH_ALLIANCE_STATE",
14510
+ "title": "联盟状态变化推送(v66,AISLG-181)",
14511
+ "summary": "联盟里与你相关的变化:reason = joined(有人入盟 / 你入盟)/ left(有人退出)/ kicked(有人被踢,含你被踢)/ role_changed(职位或盟主变更)/ disbanded(联盟解散)/ notice(公告更新)/ request_received(盟主 / 副盟主收到新申请)/ request_resolved(你的申请被拒绝)/ invited(你收到邀请)。推给相关账号的全部在线连接(含 Agent);收到后重新 GET_ALLIANCE 取最新状态即可。",
14512
+ "dataFields": [
14513
+ {
14514
+ "name": "reason",
14515
+ "type": "string",
14516
+ "desc": "变化原因,见上。"
14517
+ },
14518
+ {
14519
+ "name": "allianceId",
14520
+ "type": "string | null",
14521
+ "desc": "相关联盟 id。"
14522
+ },
14523
+ {
14524
+ "name": "allianceName",
14525
+ "type": "string | null",
14526
+ "desc": "相关联盟名。"
14527
+ }
14528
+ ],
14529
+ "examples": [
14530
+ {
14531
+ "op": 2024,
14532
+ "push": true,
14533
+ "data": {
14534
+ "reason": "joined",
14535
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
14536
+ "allianceName": "卧龙盟"
14537
+ }
14538
+ }
14539
+ ],
14540
+ "agentNote": "只作提示,不必逐条处理;需要时 GET_ALLIANCE 查看最新状态。"
14541
+ },
14542
+ {
14543
+ "op": 2025,
14544
+ "kind": "push",
14545
+ "name": "PUSH_ALLIANCE_MARK",
14546
+ "title": "联盟地图标记变化推送(v69,AISLG-184)",
14547
+ "summary": "本联盟的标记新增或删除:reason = added(mark 为新标记)/ removed(mark 为 null,只带 markId)。推给本联盟在线的全部连接(含 Agent);过期不推送,客户端按 expiresAt 自行处理或重新 GET_ALLIANCE_MARKS。",
14548
+ "dataFields": [
14549
+ {
14550
+ "name": "reason",
14551
+ "type": "'added' | 'removed'",
14552
+ "desc": "变化原因。"
14553
+ },
14554
+ {
14555
+ "name": "allianceId",
14556
+ "type": "string",
14557
+ "desc": "标记所属联盟 id。"
14558
+ },
14559
+ {
14560
+ "name": "markId",
14561
+ "type": "number",
14562
+ "desc": "标记 id。"
14563
+ },
14564
+ {
14565
+ "name": "mark",
14566
+ "type": "object | null",
14567
+ "desc": "added 时为新标记;removed 时为 null。"
14568
+ }
14569
+ ],
14570
+ "examples": [
14571
+ {
14572
+ "op": 2025,
14573
+ "push": true,
14574
+ "data": {
14575
+ "reason": "added",
14576
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
14577
+ "markId": 7,
14578
+ "mark": {
14579
+ "id": 7,
14580
+ "x": 512,
14581
+ "y": 230,
14582
+ "kind": "enemy",
14583
+ "text": "洛阳北门",
14584
+ "creator": {
14585
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
14586
+ "username": "example-leader"
14587
+ },
14588
+ "createdAt": "2026-10-24T09:00:00.000Z",
14589
+ "expiresAt": "2026-10-25T09:00:00.000Z"
14590
+ }
14591
+ }
14592
+ }
14593
+ ],
14594
+ "agentNote": "只作提示;需要完整列表时 GET_ALLIANCE_MARKS。"
13931
14595
  }
13932
14596
  ],
13933
14597
  "errorCodes": {
@@ -13988,8 +14652,12 @@
13988
14652
  "action": "该类型已无法继续升级,转投其他建筑或系统。"
13989
14653
  },
13990
14654
  "BUILD_NOT_CANCELLABLE": {
13991
- "desc": "目标建造不存在、不属于本账号或不在排队状态。进行中任务能否取消待设计,当前仅排队条目(status=queued)可取消(v7)。",
13992
- "action": "用 GET_STATE 查看 city.queue,只对 status=queued 的条目发起 CANCEL_BUILD。"
14655
+ "desc": "目标建造不存在、不属于本账号,或已完成 / 已取消。排队中与建造中的条目都可取消(v7 起排队可取消,v71 AISLG-190 起建造中也可取消)。",
14656
+ "action": "用 GET_STATE 查看 city.queue,只对 status=queued 或 building 的条目发起 CANCEL_BUILD。"
14657
+ },
14658
+ "TRAINING_NOT_CANCELLABLE": {
14659
+ "desc": "(v71,AISLG-190)没有可取消的历练:武将未在历练中、历练已到点结算(经验已到账),或武将不属于本账号。",
14660
+ "action": "用 GET_HEROES 看该武将的 training 是否为 null;为 null 即历练已结束,无需取消。"
13993
14661
  },
13994
14662
  "AGENT_FORBIDDEN": {
13995
14663
  "desc": "该协议对连接声明的登录类型有限制:RESET_ACCOUNT 仅玩家连接可调用,AGENT_REPORT_PLAN 仅 Agent 连接可调用。注意:role 是连接自报的标记,本限制拦住诚实声明的对端,不是可独立验证的安全边界。",
@@ -14012,8 +14680,8 @@
14012
14680
  "action": "等队首完成后重试,或先取消排队条目腾出位置。"
14013
14681
  },
14014
14682
  "RECRUIT_NOT_CANCELLABLE": {
14015
- "desc": "目标征兵不存在、不属于本账号或不在排队状态。征募中条目能否取消待设计,当前仅排队条目可取消(v11)。",
14016
- "action": "用 GET_STATE 查看 city.recruitQueue,只对 status=queued 的条目发起 CANCEL_RECRUIT。"
14683
+ "desc": "目标征兵不存在、不属于本账号,或已完成 / 已取消。排队中与征募中的条目都可取消(v11 起排队可取消,v71 AISLG-190 起征募中也可取消)。",
14684
+ "action": "用 GET_STATE 查看 city.recruitQueue,只对 status=queued 或 recruiting 的条目发起 CANCEL_RECRUIT。"
14017
14685
  },
14018
14686
  "TARGET_NOT_ATTACKABLE": {
14019
14687
  "desc": "出征目标当前不可攻击(v12):坐标在世界外、玩家城池地块(含自己的城),或已被其他玩家占领的野地。玩家对抗(攻城与争夺野地)随后续阶段开放,当前只能出征无主 / 本账号占领的野地与 NPC 城池。",
@@ -14192,9 +14860,17 @@
14192
14860
  "action": "无需处理;city.shieldUntil 可查当前免战截止。"
14193
14861
  },
14194
14862
  "TRUCE_WEEKLY_USED": {
14195
- "desc": "(v38,AISLG-122)本周的主动免战已用过(每周一次免费,7 天基准随缩放)。data.nextAvailableAt / retryAfterSeconds 为下次可开启时刻与剩余秒数。",
14863
+ "desc": "(v38,AISLG-122)本周的主动免战已用过(每周一次免费,7 天基准随缩放)。data.nextAvailableAt / retryAfterSeconds 为下次可开启时刻与剩余秒数。提前解除(CANCEL_TRUCE)不返还本周次数。",
14196
14864
  "action": "按 retryAfterSeconds 睡满后重发 TRUCE;city.shieldNextAt 可查下次可开时刻。"
14197
14865
  },
14866
+ "TRUCE_NOT_ACTIVE": {
14867
+ "desc": "(v71,AISLG-190)没有生效中的主动免战可解除(未开启、已到期,或已提前解除)。",
14868
+ "action": "无需处理;city.shieldUntil 为空即无主动免战。"
14869
+ },
14870
+ "PASSIVE_TRUCE_NOT_CANCELLABLE": {
14871
+ "desc": "(v71,AISLG-190)城池处于被动免战中(被攻破 / 被抢后 4 小时基准),被动免战不能主动解除;CANCEL_TRUCE 只解除账号级的主动免战。data.until / data.retryAfterSeconds 为被动免战截止时刻与剩余秒数。",
14872
+ "action": "等被动免战结束(city.truceUntil)后再行动;期间可开启主动免战(TRUCE)不影响被动免战。"
14873
+ },
14198
14874
  "TILE_PROTECTED": {
14199
14875
  "desc": "(v39,AISLG-123)该野地刚换主人(被玩家抢占),处于保护期(1 小时基准随缩放):期间玩家与 NPC 都不能再抢。data.until / data.retryAfterSeconds 为截止时刻与剩余秒数。",
14200
14876
  "action": "按 retryAfterSeconds 睡满后重发,或换目标;GET_TILE 的 tile.protection.ownerChangedUntil 可查保护截止。"
@@ -14283,6 +14959,22 @@
14283
14959
  "desc": "(v65,AISLG-134)服务端正在换季(维护态),游戏类协议暂不可用。登录、LOGOUT 与 GET_SEASON 仍可用。响应 data.retryAfterSec 为建议的等待秒数。",
14284
14960
  "action": "停止发送游戏类请求,按 retryAfterSec 等待后再试;收到 PUSH_SEASON 的 started 后服务端会断开连接,需要重新 LOGIN。"
14285
14961
  },
14962
+ "ALLIANCE_NOT_FOUND": {
14963
+ "desc": "(v66,AISLG-181)联盟不存在,或申请 / 邀请 / 目标成员不存在(可能已过期、被撤销或已离盟)。",
14964
+ "action": "不要重试同一个 id;GET_ALLIANCE / LIST_ALLIANCES 重新确认当前状态。"
14965
+ },
14966
+ "ALLIANCE_MARK_LIMIT": {
14967
+ "desc": "(v69,AISLG-184)本联盟同时有效的地图标记已达上限(20 个,过期的不计);响应附 limit、until(最早一个标记的到期时刻)与 retryAfterSeconds。",
14968
+ "action": "等最早的标记到期(until)或先删除自己的标记,再打新的。"
14969
+ },
14970
+ "ALLIANCE_MARK_EXISTS": {
14971
+ "desc": "(v69,AISLG-184)同一格子已经有一个有效的联盟标记,同一格子不能重复标记。",
14972
+ "action": "换一个格子打标记;要改内容先删除原标记再打。"
14973
+ },
14974
+ "ALLY_NOT_ATTACKABLE": {
14975
+ "desc": "(v67,AISLG-182)目标城池 / 野地的主人与你在同一个联盟(盟友):不能掠夺、抢占野地、占领分城,也不能侦察。出发后目标才成为盟友的,部队到达时不开战,原路返回(事件 cause=ALLY_NOT_ATTACKABLE)。",
14976
+ "action": "换一个非盟友的目标;盟友的领地不要作为攻击 / 侦察目标。"
14977
+ },
14286
14978
  "ANNOUNCEMENT_NOT_FOUND": {
14287
14979
  "desc": "(v60,AISLG-162)公告不存在、已撤回、尚未到生效时间,或定向到其他站点。",
14288
14980
  "action": "不要重试同一个 id;重新用 GET_ANNOUNCEMENTS 拉取列表确认当前可见的公告。"
@@ -14323,7 +15015,7 @@
14323
15015
  },
14324
15016
  {
14325
15017
  "term": "征兵队列(recruitQueue)",
14326
- "desc": "军营处理征兵:RECRUIT 无征募中时立即开始(status=recruiting,时长 = 单兵时长 × 数量),有征募中且未满时入队(status=queued);队列 = 1 征募中 + 最多 2 排队(占位)。资源与人口在发起时扣减,取消排队条目全额返还;征募中能否取消待定。队列独立于建造队列。"
15018
+ "desc": "军营处理征兵:RECRUIT 无征募中时立即开始(status=recruiting,时长 = 单兵时长 × 数量),有征募中且未满时入队(status=queued);队列 = 1 征募中 + 最多 2 排队(占位)。资源与人口在发起时扣减,取消排队条目全额返还;征募中条目也可取消(v71,全额返还,排队的下一条立即开始)。队列独立于建造队列。"
14327
15019
  },
14328
15020
  {
14329
15021
  "term": "守城加成(defenseBonus)",
@@ -14415,7 +15107,7 @@
14415
15107
  },
14416
15108
  {
14417
15109
  "term": "建造队列(queue)",
14418
- "desc": "BUILD / UPGRADE 采用排队制:无在建时立即开工(status=building,dueAt 为预计完成时间);有在建时进入排队(status=queued,dueAt 为 null),队首完成后由后台自动激活为 building。队列 = 1 条在建 + 最多 2 条排队(占位数值),再发起返回 QUEUE_FULL。排队条目可随时 CANCEL_BUILD 取消并全额返还成本(确认规则);进行中任务能否取消待定。原游戏的元宝加速第一期未实现。"
15110
+ "desc": "BUILD / UPGRADE 采用排队制:无在建时立即开工(status=building,dueAt 为预计完成时间);有在建时进入排队(status=queued,dueAt 为 null),队首完成后由后台自动激活为 building。队列 = 1 条在建 + 最多 2 条排队(占位数值),再发起返回 QUEUE_FULL。排队条目与建造中的条目都可随时 CANCEL_BUILD 取消并全额返还成本(确认规则;v71 起建造中也可取消)。原游戏的元宝加速第一期未实现。"
14419
15111
  },
14420
15112
  {
14421
15113
  "term": "building / queued / completed / cancelled",
@@ -15528,7 +16220,7 @@
15528
16220
  },
15529
16221
  {
15530
16222
  "title": "8. 城池管理(v7):改名与取消排队",
15531
- "explain": "改名立即生效(RENAME_CITY,名称 trim 后 1..24 字符)。升级农田立即开工后,民房进入排队(v4 排队制);排队条目可随时取消(CANCEL_BUILD),成本按条目快照全额返还(2026-09-27 确认规则),该类型可立即重新发起建造;进行中条目能否取消待定。一期不提供建筑拆除。本连接是唯一在线连接,故没有其他连接的推送帧;有其他在线连接时它们会收到 PUSH_BUILD_STATE(build_cancelled)与 PUSH_CITY_STATE(city_renamed)。",
16223
+ "explain": "改名立即生效(RENAME_CITY,名称 trim 后 1..24 字符)。升级农田立即开工后,民房进入排队(v4 排队制);排队条目可随时取消(CANCEL_BUILD),成本按条目快照全额返还(2026-09-27 确认规则),该类型可立即重新发起建造;建造中的条目也可取消(v71 起),同样全额返还、排队的下一条自动开工。一期不提供建筑拆除。本连接是唯一在线连接,故没有其他连接的推送帧;有其他在线连接时它们会收到 PUSH_BUILD_STATE(build_cancelled)与 PUSH_CITY_STATE(city_renamed)。",
15532
16224
  "frames": [
15533
16225
  {
15534
16226
  "kind": "request",