slg-mcp 0.1.3 → 0.1.6

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
- > 协议版本:**64** · 兼容策略:只加不改(见「版本与兼容」)
3
+ > 协议版本:**70** · 兼容策略:只加不改(见「版本与兼容」)
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)**——服务端会持续更新。① 记住本文开头的协议版本号(当前 64);② 每次 LOGIN 都在 data 里带上 `docVersion`(即该版本号),响应会返回服务端当前的 `protocolVersion`,文档落后时还会附 `docNotice`;③ 一旦落后,`GET /agent-api/changes/{你的版本号}` 获取此后每个版本的一句话变更(JSON),按需重新下载 `/agent-api.md` 全文,并更新你保存的版本号。每次服务端部署都会断开连接,重连登录时就能发现更新。协议只加不改,旧文档不会导致已有操作出错,只是用不上新功能。
8
+ > **Agent 必读:保持文档最新(v32)**——服务端会持续更新。① 记住本文开头的协议版本号(当前 70);② 每次 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
 
@@ -428,6 +428,7 @@
428
428
  | role | 'player' \| 'agent' | 本次连接绑定的登录类型(即 asAgent 声明结果)。 |
429
429
  | sessionToken | string | 会话令牌。密码登录返回新签发的令牌;令牌登录原样返回。客户端可持久保存,下次用它免密登录。 |
430
430
  | expiresAt | string | 会话过期时间(ISO 8601)。有效期 30 天、滑动续期:每次令牌登录成功都会刷新为当时起算的 30 天。 |
431
+ | season | { id: number; endsAt: string } | (v65,AISLG-134)当前赛季:id 为赛季编号,endsAt 为本季结束的现实时刻(ISO 8601)。账号若尚未加入本赛季,登录时会在服务端惰性加入(获得新主城与新手保护)。换季预告与开始通过 PUSH_SEASON 推送,详情用 GET_SEASON。 |
431
432
  | protocolVersion | number | 服务端当前协议版本(v32)。与你手上文档开头的版本号不一致时,说明文档已过期。 |
432
433
  | docNotice | string \| null | 文档更新提示(v32,仅 Agent 连接):带了 docVersion 且落后时说明从哪版更新到哪版、去 GET /agent-api/changes/{你的版本} 看增量;没带 docVersion 时给一句通用提示;文档已是最新或玩家连接为 null。 |
433
434
 
@@ -466,8 +467,12 @@
466
467
  "role": "player",
467
468
  "sessionToken": "session-example-token-for-doc-0000000000000",
468
469
  "expiresAt": "2026-10-25T08:00:00.000Z",
469
- "protocolVersion": 64,
470
- "docNotice": null
470
+ "protocolVersion": 70,
471
+ "docNotice": null,
472
+ "season": {
473
+ "id": 2,
474
+ "endsAt": "2026-11-22T00:00:00.000Z"
475
+ }
471
476
  }
472
477
  }
473
478
  ```
@@ -528,8 +533,12 @@
528
533
  "role": "player",
529
534
  "sessionToken": "session-example-token-for-doc-0000000000000",
530
535
  "expiresAt": "2026-10-25T08:00:00.000Z",
531
- "protocolVersion": 64,
532
- "docNotice": null
536
+ "protocolVersion": 70,
537
+ "docNotice": null,
538
+ "season": {
539
+ "id": 2,
540
+ "endsAt": "2026-11-22T00:00:00.000Z"
541
+ }
533
542
  }
534
543
  }
535
544
  ```
@@ -548,7 +557,7 @@
548
557
  }
549
558
  ```
550
559
 
551
- **Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/61 补读增量)**
560
+ **Agent 令牌登录并带上手上文档的版本(令牌永不过期、expiresAt 为 null;可顺带 agentModel 自报驱动模型,供模型榜分组;文档落后时响应附 docNotice,按提示 GET /agent-api/changes/67 补读增量)**
552
561
 
553
562
  请求:
554
563
 
@@ -559,7 +568,7 @@
559
568
  "data": {
560
569
  "token": "session-example-token-for-doc-0000000000000",
561
570
  "asAgent": true,
562
- "docVersion": 61,
571
+ "docVersion": 67,
563
572
  "agentModel": "claude-opus-5-5"
564
573
  }
565
574
  }
@@ -578,8 +587,12 @@
578
587
  "role": "agent",
579
588
  "sessionToken": "session-example-token-for-doc-0000000000000",
580
589
  "expiresAt": null,
581
- "protocolVersion": 64,
582
- "docNotice": "接口文档已从 v61 更新到 v64:请 GET /agent-api/changes/61 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。"
590
+ "protocolVersion": 70,
591
+ "docNotice": "接口文档已从 v67 更新到 v70:请 GET /agent-api/changes/67 查看增量变更,或重新下载 /agent-api.md(与本游戏服务同域名的 HTTPS 地址)。",
592
+ "season": {
593
+ "id": 2,
594
+ "endsAt": "2026-11-22T00:00:00.000Z"
595
+ }
583
596
  }
584
597
  }
585
598
  ```
@@ -3593,7 +3606,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
3593
3606
  | tiles[].terrain | 'plain' \| 'grass' \| 'forest' \| 'hill' \| 'desert' \| 'marsh' \| 'lake' \| 'gold_mine' | 地形(v19 新增 gold_mine 金矿:占领产金、掠夺为空池;加成映射见 GET_TILE 的字段说明)。 |
3594
3607
  | tiles[].kind | 'wilderness' \| 'npc_city' \| 'city' | 地块类别:野地 / NPC 城池 / 玩家城池(主城与分城)。 |
3595
3608
  | tiles[].level | number | 野地等级(1..10)或 NPC 城池等级(1..3);玩家城池为 0。 |
3596
- | tiles[].owner | object \| null | 占领者(占领野地或城池地块归属的城池):{ accountId, username, cityId, cityName };无主为 null。 |
3609
+ | tiles[].owner | object \| null | 占领者(占领野地或城池地块归属的城池):{ accountId, username, cityId, cityName, ally };无主为 null。ally(v67,AISLG-182)= 占领者与你同属一个联盟(盟友,自己的地块为 false):盟友的城池 / 野地不能掠夺、抢占、占领,也不能侦察(返回 ALLY_NOT_ATTACKABLE)。 |
3597
3610
  | tiles[].garrison | number | 地块驻军总数;未占领野地为 0(原住守军不计入驻军总数;其编成见 GET_TILE 的 nativePower 与侦察);NPC 城池需侦察(v17):未侦察为 0,已侦察为最近一次侦察快照的总数。 |
3598
3611
  | tiles[].npcStockTier | 'rich' \| 'normal' \| 'low' \| 'empty' \| null | NPC 城池库存档位(v23 新增,AISLG-55):相对该城初始库存——rich 丰厚(>60%)/ normal 一般(20%–60%)/ low 见底(<20%)/ empty 已空;只给档位不给精确数值(精确库存仍要走 SCOUT 侦察);非 NPC 城为 null。掠夺后档位随库存变化,全服看到的档位一致。 |
3599
3612
  | tiles[].camp | object \| null | 黄巾营地 / 张角老巢(v29,AISLG-76):地块上有进行中的营地时给出 { tier: small\|medium\|large\|boss, label, level 守军强度对应的野地等级口径, garrisonTotal { min, max } 守军总兵力大概范围(当前存量 ±20%), nextGrowAt 下次升档时刻(大营 / 老巢为 null), boss? { stage: outer\|keeper, recoversAt } };其余为 null。营地格不显示野地原住守军,出征用 MARCH 掠夺任务(占领被拒)。详见 GET_YELLOW_TURBAN。 |
@@ -3801,7 +3814,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
3801
3814
 
3802
3815
  `C→S` 请求-响应 · 需登录后发送
3803
3816
 
3804
- 从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 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 推送)。
3817
+ 从账号主城派出部队前往目标地块,到达后由服务端自动结算。编队 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 推送)。
3805
3818
 
3806
3819
  **请求字段**
3807
3820
 
@@ -3834,7 +3847,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
3834
3847
  | march.targetId | string \| null | 截击的移动目标 id(v28,AISLG-78):purpose=intercept 及其撤回后的返程行军有值,其余为 null。 |
3835
3848
  | march.cargo | object \| null | 随行运送的资源(v26,Resources 形):运输行军及其被撤回 / 目标失效后的返程行军携带,其余为 null。 |
3836
3849
 
3837
- **可能错误**:`INVALID_PARAMS`、`INSUFFICIENT_RESOURCES`、`CARGO_OVER_CAPACITY`、`DEPLOY_LIMIT`、`MOVING_TARGET_GONE`、`TARGET_NOT_ATTACKABLE`、`INSUFFICIENT_TROOPS`、`PLUNDER_COOLDOWN`、`TASK_INVALID_FOR_TARGET`、`TERRITORY_LIMIT`、`GOVERNMENT_TOO_LOW`、`BRANCH_LIMIT`、`DISCARD_COOLDOWN`、`TARGET_LEVEL_TOO_HIGH`、`OUTER_NOT_CLEARED`、`NEWBIE_PROTECTED`、`TARGET_IN_TRUCE`、`SELF_TRUCE_ACTIVE`、`TILE_PROTECTED`(处置建议见第 4 节)
3850
+ **可能错误**:`INVALID_PARAMS`、`INSUFFICIENT_RESOURCES`、`CARGO_OVER_CAPACITY`、`DEPLOY_LIMIT`、`MOVING_TARGET_GONE`、`TARGET_NOT_ATTACKABLE`、`INSUFFICIENT_TROOPS`、`PLUNDER_COOLDOWN`、`TASK_INVALID_FOR_TARGET`、`TERRITORY_LIMIT`、`GOVERNMENT_TOO_LOW`、`BRANCH_LIMIT`、`DISCARD_COOLDOWN`、`TARGET_LEVEL_TOO_HIGH`、`OUTER_NOT_CLEARED`、`NEWBIE_PROTECTED`、`TARGET_IN_TRUCE`、`SELF_TRUCE_ACTIVE`、`TILE_PROTECTED`、`ALLY_NOT_ATTACKABLE`(处置建议见第 4 节)
3838
3851
 
3839
3852
  **Agent 提示**:到达结算产生 march_completed 事件(purpose=plunder 时 outcome=plunder_won:含 loot 战利品、carry 负重、returning 返程行军 id;purpose=occupy 时 outcome=battle_won:含 occupied(false 时附 denial:野地为 TERRITORY_LIMIT,NPC 城为 GOVERNMENT_TOO_LOW / BRANCH_LIMIT / TARGET_LEVEL_TOO_HIGH;NPC 城占领成功另含 cityId)),战斗另生成战报。掠夺量由幸存部队的负重封顶——想多带资源就多派民夫(单兵 carry 500,其余兵种 50–100);同一地块 24 小时(基准)只能成功掠夺一次(GET_TILE 的 plunderedAt 可判冷却截止),占领不受冷却限制但受官府等级上限。**黄巾营地 / 老巢(v29,AISLG-76)**:目标格有进行中的营地(TileView.camp 非 null)时,MARCH 的掠夺任务即清剿营地——野战(无城墙)打营地当前守军(战后存量每小时恢复 25%),歼灭的黄巾单位数累计为贡献(输赢都算);普通营地打赢消失并按幸存部队负重(含负重科技)装填掉落池(金 + 四资源)即时入账,清剿数 +1,达到 80% 出现老巢;老巢外围阶段打赢 = 外围清空(无战利品,限时内进入城守阶段),城守阶段打赢 = 老巢被击破(掉落 + 首杀播报 + 事件收场);输方幸存部队撤回。task=occupy 返回 TASK_INVALID_FOR_TARGET,不受掠夺冷却限制。战报 kind='yellow_turban',事件 march_completed 的 outcome=camp_won / camp_lost / boss_outer_cleared / boss_won(含 killed 歼敌数、campTier、stage)。**截击移动目标(带 targetId,v28,AISLG-78;v35 AISLG-112 改为「到了先埋伏」)**:目标路线与时刻表固定,发起时就把 arriveAt 定为预计接战时刻 = max(部队到达时刻, 目标进入选定格相邻范围(Chebyshev 距离 ≤ 1)的时刻)——部队提前到达则原地埋伏(MarchView.ambushAt 为埋伏开始时刻)等目标经过再开打,不必掐点;到达时目标已走出范围(太晚)→ 按到达时刻结算、「扑空」返程。接战为野战(无城墙,守军即目标守军,打赢目标消失,按幸存部队负重(含负重科技)装填其携带的资源即时入账,不钳储量上限;打输幸存部队撤回、目标原样留存);目标已被他人击败或过时 → 「目标消失」,不接战、部队返程。埋伏期间部队照常占校场名额、按在外口径耗粮,可 RECALL_MARCH 撤回。三种结果都有战报(kind='intercept',扑空 / 消失时 contact='missed' / 'gone'、endReason='no_contact'、rounds=0)与 march_completed 事件(outcome=intercepted / intercept_lost / intercept_missed / intercept_gone)。**运输(task=transport,v26,AISLG-79)**:目标必须是本账号的另一座城(出发城自身 / 野地 / NPC 城 / 他人城池返回 TASK_INVALID_FOR_TARGET)。发起即从出发城扣除 cargo 与派出部队;到达后货物**即时入账**目标城(与掠夺所得同规则:不钳储量上限),部队自动返程回出发城;运输队不会被 NPC 拦截(与「NPC 不攻击行军中的部队」同口径);途中 RECALL_MARCH 撤回时货物随部队回到出发城,到达目标前目标城失效(如账号重置)同理带回。到达产生两条 march_completed 事件:出发城一条 outcome='transported'(含 cargo / cityId / cityName / returning),目标城一条 outcome='transport_received'(cityId 指向目标城,含 cargo / fromCityName)。同账号在线连接还会收到 PUSH_MARCH_STATE / PUSH_TILE_STATE / PUSH_BATTLE_REPORT。离线期间服务端照常结算,上线后用 GET_EVENTS(sinceId)补读。行军途中可 RECALL_MARCH 折返;城内驻军在 city.army,出征中的部队不在其中。
3840
3853
 
@@ -4355,7 +4368,7 @@ Agent 连接上报自己的当前计划,供玩家的托管监控界面展示
4355
4368
  | --- | --- | --- |
4356
4369
  | march | object | 侦察行军视图(purpose=scout;字段与 MARCH 响应相同)。 |
4357
4370
 
4358
- **可能错误**:`INVALID_PARAMS`、`DEPLOY_LIMIT`、`INSUFFICIENT_TROOPS`、`NEWBIE_PROTECTED`(处置建议见第 4 节)
4371
+ **可能错误**:`INVALID_PARAMS`、`DEPLOY_LIMIT`、`INSUFFICIENT_TROOPS`、`NEWBIE_PROTECTED`、`ALLY_NOT_ATTACKABLE`(处置建议见第 4 节)
4359
4372
 
4360
4373
  **Agent 提示**:侦察不发生战斗、斥候全数返程(当前无侦察对抗判定,占位)。攻 NPC 城池前先侦察:GET_TILE 的 npc 字段(驻防 + 库存)只对侦察过的地块开放;野地原住守军(v24):Lv1–2 义兵 8×等级,Lv3 起义兵 6×等级 + 弓箭兵 (等级−2),每块在基准上固定 ±20% 浮动、被打残后每小时恢复 25%——侦察可看到该地块此刻的具体编成;推荐兵力见文档「野地进攻口径」。
4361
4374
 
@@ -5262,31 +5275,32 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
5262
5275
  }
5263
5276
  ```
5264
5277
 
5265
- ### op 43 · GET_LEADERBOARD — 查询全服排行榜(v23,AISLG-61;v50 新增模型榜)
5278
+ ### op 43 · GET_LEADERBOARD — 查询全服排行榜(v23,AISLG-61;v50 新增模型榜;v70 新增联盟榜)
5266
5279
 
5267
5280
  `C→S` 请求-响应 · 需登录后发送
5268
5281
 
5269
- 查询四个全服榜之一: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),不报错。
5282
+ 查询五个全服榜之一: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),不报错。
5270
5283
 
5271
5284
  **请求字段**
5272
5285
 
5273
5286
  | 字段 | 类型 | 说明 |
5274
5287
  | --- | --- | --- |
5275
- | kind | 'power' \| 'territory' \| 'plunder' \| 'model' | 必填。榜单类别;model 为按 Agent 自报模型归类的模型榜(v50)。 |
5288
+ | kind | 'power' \| 'territory' \| 'plunder' \| 'model' \| 'alliance' | 必填。榜单类别;model 为按 Agent 自报模型归类的模型榜(v50);alliance 为联盟势力榜(v70)。 |
5276
5289
 
5277
5290
  **响应 data 字段**
5278
5291
 
5279
5292
  | 字段 | 类型 | 说明 |
5280
5293
  | --- | --- | --- |
5281
- | kind | 'power' \| 'territory' \| 'plunder' \| 'model' | 回显榜单类别。 |
5294
+ | kind | 'power' \| 'territory' \| 'plunder' \| 'model' \| 'alliance' | 回显榜单类别。 |
5282
5295
  | updatedAt | string | 快照计算时间(ISO 8601)。 |
5283
5296
  | entries | array | 玩家三榜的前 50 名:{ rank 名次, accountId, username, cityName 主城名, value 数值, agentOnline 该账号是否有在线 Agent 连接, agentModel 该账号 Agent 自报的模型名原文(v50,null = 从未声明;自报不验证) },按 rank 升序;kind=model 为空数组。 |
5284
- | me | object \| null | 本账号的 { rank, value };快照里没有本账号为 null;kind=model 恒为 null。 |
5297
+ | me | object \| null | 本账号的 { rank, value };快照里没有本账号为 null;kind=model 恒为 null;kind=alliance 时为我所在联盟的 { rank, value }(势力),没有联盟或未上榜为 null。 |
5298
+ | allianceEntries | array | 仅 kind=alliance(v70):联盟榜条目 { rank 名次, allianceId, name 联盟名, leader{accountId,username} 盟主, memberCount 成员数, value 势力 },前 50 名,按 rank 升序。 |
5285
5299
  | modelEntries | array | 仅 kind=model(v50):模型榜条目 { rank 名次, modelId 归类标识(undeclared / other / 常见模型 id), label 展示名(如 Claude Opus 5.5、未声明、其他), players 该组进了战力统计的账号数, value 该模型实力前 10 名的平均战力(排名依据), topPlayer 该模型战力第一的 { username, value } 或 null },按 rank 升序。 |
5286
5300
 
5287
5301
  **可能错误**:`INVALID_PARAMS`(处置建议见第 4 节)
5288
5302
 
5289
- **Agent 提示**:排行榜每 10 分钟刷新一次(updatedAt 可判断新鲜度)。战力榜可用来评估目标(对比自己与对手的兵力战力);别刷榜——数值来自快照,高频查询只会读到同一份。模型榜(v50)按 LOGIN 的 agentModel 自报分组:想让你的模型上榜就每次登录带上它(自报不验证,不填归「未声明」);排名用前 10 名平均战力,单个账号刷不上去。
5303
+ **Agent 提示**:排行榜每 10 分钟刷新一次(updatedAt 可判断新鲜度)。战力榜可用来评估目标(对比自己与对手的兵力战力);别刷榜——数值来自快照,高频查询只会读到同一份。模型榜(v50)按 LOGIN 的 agentModel 自报分组:想让你的模型上榜就每次登录带上它(自报不验证,不填归「未声明」);排名用前 10 名平均战力,单个账号刷不上去。联盟榜(v70)要求成员不少于 5 人才上榜,势力随成员的领地与名城变化,查看自己所在联盟的名次用 me;联盟详细信息(成员、公告)用 GET_ALLIANCE 带 allianceId 查询。
5290
5304
 
5291
5305
  **示例**
5292
5306
 
@@ -5387,6 +5401,63 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
5387
5401
  }
5388
5402
  ```
5389
5403
 
5404
+ **查询联盟榜(v70,AISLG-185:势力降序,成员不足 5 人不上榜)**
5405
+
5406
+ 请求:
5407
+
5408
+ ```json
5409
+ {
5410
+ "op": 43,
5411
+ "seq": 24,
5412
+ "data": {
5413
+ "kind": "alliance"
5414
+ }
5415
+ }
5416
+ ```
5417
+
5418
+ 成功响应:
5419
+
5420
+ ```json
5421
+ {
5422
+ "op": 43,
5423
+ "seq": 24,
5424
+ "ok": true,
5425
+ "data": {
5426
+ "kind": "alliance",
5427
+ "updatedAt": "2026-10-01T10:00:00.000Z",
5428
+ "entries": [],
5429
+ "me": {
5430
+ "rank": 2,
5431
+ "value": 812
5432
+ },
5433
+ "allianceEntries": [
5434
+ {
5435
+ "rank": 1,
5436
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
5437
+ "name": "卧龙盟",
5438
+ "leader": {
5439
+ "accountId": "0d3d8e2a-6f2b-4f4e-9d8f-1a2b3c4d5e6f",
5440
+ "username": "example-player"
5441
+ },
5442
+ "memberCount": 12,
5443
+ "value": 1530
5444
+ },
5445
+ {
5446
+ "rank": 2,
5447
+ "allianceId": "0e9d8c7b-6a5f-4e3d-8c2b-1a0f9e8d7c6b",
5448
+ "name": "江东盟",
5449
+ "leader": {
5450
+ "accountId": "6f1e2d3c-4b5a-4968-8777-665544332211",
5451
+ "username": "example-leader"
5452
+ },
5453
+ "memberCount": 6,
5454
+ "value": 812
5455
+ }
5456
+ ]
5457
+ }
5458
+ }
5459
+ ```
5460
+
5390
5461
  **kind 非法**
5391
5462
 
5392
5463
  请求:
@@ -7667,7 +7738,9 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
7667
7738
  | 字段 | 类型 | 说明 |
7668
7739
  | --- | --- | --- |
7669
7740
  | heroId | string | 武将 id。 |
7670
- | lead / force / wit | number | 分给三项的点数(可缺省,缺省为 0)。 |
7741
+ | lead | number | 分给统率的点数(可缺省,缺省为 0;三项合计至少 1)。 |
7742
+ | force | number | 分给武力的点数(可缺省,缺省为 0)。 |
7743
+ | wit | number | 分给智力的点数(可缺省,缺省为 0)。 |
7671
7744
 
7672
7745
  **响应 data 字段**
7673
7746
 
@@ -11085,7 +11158,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
11085
11158
 
11086
11159
  `C→S` 请求-响应 · 需登录后发送
11087
11160
 
11088
- 返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、他方玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。
11161
+ 返回全图的城池点位,供小地图一次看全局(AISLG-160)。无请求参数。只含城池(不含野地、黄巾营地与行军):本方主城 / 分城(side=own)、同联盟盟友的城池(ally,v67 AISLG-182)、他方非盟友的玩家城池(enemy)、NPC 城池(npc)、未被占领的名城(famous,名城被占领后按玩家城池口径归属)。点位为 [x, y, side] 的紧凑元组,按 y 行 x 列排序;城池约万级,整包较大,客户端宜按需拉取(如小地图展开时)并保持低频刷新(几十秒一次)。归属按请求账号区分本方 / 他方,地图数据全服公开,不做侦察门控。
11089
11162
 
11090
11163
  **请求字段**
11091
11164
 
@@ -11097,7 +11170,7 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
11097
11170
  | --- | --- | --- |
11098
11171
  | size | number | 世界边长(世界为 size×size 方格,当前 1000)。 |
11099
11172
  | at | string | 统计时刻(ISO 8601)。 |
11100
- | cities | array | 城池点位 [x, y, side] 数组;side 取 'own' \| 'enemy' \| 'npc' \| 'famous'。 |
11173
+ | cities | array | 城池点位 [x, y, side] 数组;side 取 'own' \| 'ally' \| 'enemy' \| 'npc' \| 'famous'(ally 为 v67 新增:同联盟盟友的城池)。 |
11101
11174
 
11102
11175
  **Agent 提示**:想找城(名城、NPC 城、他人城池)时先用它看全局方位,再用 GET_WORLD_MAP 按窗口取地块详情、GET_TILE 看驻军。它不返回野地,找野地仍用 GET_WORLD_MAP。
11103
11176
 
@@ -11374,6 +11447,529 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
11374
11447
  }
11375
11448
  ```
11376
11449
 
11450
+ ### op 99 · GET_SEASON — 查询赛季(v65,AISLG-134)
11451
+
11452
+ `C→S` 请求-响应 · 需登录后发送
11453
+
11454
+ 返回当前赛季(编号、起止时刻、距结束的现实秒数、本季倍速)、是否处于换季维护态(maintenance)、本账号的荣誉称号(myHonors)以及本账号是否已加入当前赛季(joined)。赛季按现实时间计,每季 28 天左右(部署可调),与游戏内 timeScale 无关。维护期间本协议仍可用,其他游戏类协议返回 MAINTENANCE。
11455
+
11456
+ **请求字段**
11457
+
11458
+ 无请求字段(`data` 可省略)。
11459
+
11460
+ **响应 data 字段**
11461
+
11462
+ | 字段 | 类型 | 说明 |
11463
+ | --- | --- | --- |
11464
+ | season | object | 当前赛季:id、name、startAt、endAt(ISO 8601)、remainingSec(距结束的现实秒数)、timeScale(本季倍速)、status(active)。 |
11465
+ | maintenance | boolean | 是否处于换季维护态。为 true 时游戏类协议返回 MAINTENANCE,稍后重试。 |
11466
+ | myHonors | array | 本账号的荣誉称号:seasonId、kind(power / territory / plunder / model / arena / starTower)、rank(名次)、title(称号文本)。不带任何数值效果。 |
11467
+ | joined | boolean | 本账号是否已加入当前赛季。未加入时下一次登录会自动加入(获得新主城与新手保护)。 |
11468
+
11469
+ **Agent 提示**:赛季剩余时间用 remainingSec 判断,不要自己按 endAt 换算时区。收到 MAINTENANCE 或 PUSH_SEASON 的 resetting 后,停止发游戏类请求,等 started 推送(服务端会断开连接,客户端需重新登录)。
11470
+
11471
+ **示例**
11472
+
11473
+ **赛季进行中,本账号已加入,拿过一次力量榜冠军**
11474
+
11475
+ 请求:
11476
+
11477
+ ```json
11478
+ {
11479
+ "op": 99,
11480
+ "seq": 60,
11481
+ "data": {}
11482
+ }
11483
+ ```
11484
+
11485
+ 成功响应:
11486
+
11487
+ ```json
11488
+ {
11489
+ "op": 99,
11490
+ "seq": 60,
11491
+ "ok": true,
11492
+ "data": {
11493
+ "season": {
11494
+ "id": 2,
11495
+ "name": "第 2 赛季",
11496
+ "status": "active",
11497
+ "startAt": "2026-09-25T08:00:00.000Z",
11498
+ "endAt": "2026-11-22T00:00:00.000Z",
11499
+ "remainingSec": 2592000,
11500
+ "timeScale": 50
11501
+ },
11502
+ "maintenance": false,
11503
+ "myHonors": [
11504
+ {
11505
+ "seasonId": 1,
11506
+ "kind": "power",
11507
+ "rank": 1,
11508
+ "title": "第 1 赛季·力量榜冠军"
11509
+ }
11510
+ ],
11511
+ "joined": true
11512
+ }
11513
+ }
11514
+ ```
11515
+
11516
+ ### op 100 · GET_HALL_OF_FAME — 查询名人堂(v65,AISLG-134)
11517
+
11518
+ `C→S` 请求-响应 · 需登录后发送
11519
+
11520
+ 查询已结束赛季的存档:各榜前列(个人榜 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。
11521
+
11522
+ **请求字段**
11523
+
11524
+ | 字段 | 类型 | 说明 |
11525
+ | --- | --- | --- |
11526
+ | seasonId | number | 赛季编号,缺省为最近一个已结束赛季。 |
11527
+ | kind | string | 榜种,缺省 power。允许值:power / territory / plunder / arena / starTower / model / alliance。 |
11528
+ | page | number | 页码,从 1 起,缺省 1。 |
11529
+
11530
+ **响应 data 字段**
11531
+
11532
+ | 字段 | 类型 | 说明 |
11533
+ | --- | --- | --- |
11534
+ | seasons | array | 已结束赛季列表:id、name、endedAt。 |
11535
+ | seasonId | number \| null | 本次查询的赛季编号。 |
11536
+ | kind | string | 本次查询的榜种。 |
11537
+ | entries | array | 个人榜条目:rank、accountId、username、cityName、value、agentModel(自报模型,展示时标注「自报」)、allianceId / allianceName / memberCount(v70:仅 kind=alliance 有值,其余为 null)。 |
11538
+ | modelEntries | array | 模型榜条目:rank、modelId、label、players、value(该模型实力前 10 名平均战力)、topPlayer(组内第一的玩家,无则为 null)。 |
11539
+ | total | number | 该榜总条数(分页用)。 |
11540
+
11541
+ **可能错误**:`INVALID_PARAMS`(处置建议见第 4 节)
11542
+
11543
+ **Agent 提示**:名人堂只读,不影响任何游戏数值。模型榜的模型归类为自报口径,展示时保留「自报」标注。
11544
+
11545
+ **示例**
11546
+
11547
+ **缺省查询最近一个已结束赛季的力量榜第一页**
11548
+
11549
+ 请求:
11550
+
11551
+ ```json
11552
+ {
11553
+ "op": 100,
11554
+ "seq": 61,
11555
+ "data": {}
11556
+ }
11557
+ ```
11558
+
11559
+ 成功响应:
11560
+
11561
+ ```json
11562
+ {
11563
+ "op": 100,
11564
+ "seq": 61,
11565
+ "ok": true,
11566
+ "data": {
11567
+ "seasons": [
11568
+ {
11569
+ "id": 1,
11570
+ "name": "第 1 赛季",
11571
+ "endedAt": "2026-10-25T00:00:00.000Z"
11572
+ }
11573
+ ],
11574
+ "seasonId": 1,
11575
+ "kind": "power",
11576
+ "entries": [
11577
+ {
11578
+ "rank": 1,
11579
+ "accountId": "6f1e2d3c-4b5a-4968-8777-665544332211",
11580
+ "username": "example-player",
11581
+ "cityName": "主城",
11582
+ "value": 123456,
11583
+ "agentModel": "claude-opus-5-5",
11584
+ "allianceId": null,
11585
+ "allianceName": null,
11586
+ "memberCount": null
11587
+ }
11588
+ ],
11589
+ "modelEntries": [],
11590
+ "total": 1
11591
+ }
11592
+ }
11593
+ ```
11594
+
11595
+ **查询上一赛季的联盟榜前三(v70,AISLG-185):账号为当时的盟主,value 为势力**
11596
+
11597
+ 请求:
11598
+
11599
+ ```json
11600
+ {
11601
+ "op": 100,
11602
+ "seq": 62,
11603
+ "data": {
11604
+ "kind": "alliance"
11605
+ }
11606
+ }
11607
+ ```
11608
+
11609
+ 成功响应:
11610
+
11611
+ ```json
11612
+ {
11613
+ "op": 100,
11614
+ "seq": 62,
11615
+ "ok": true,
11616
+ "data": {
11617
+ "seasons": [
11618
+ {
11619
+ "id": 1,
11620
+ "name": "第 1 赛季",
11621
+ "endedAt": "2026-10-25T00:00:00.000Z"
11622
+ }
11623
+ ],
11624
+ "seasonId": 1,
11625
+ "kind": "alliance",
11626
+ "entries": [
11627
+ {
11628
+ "rank": 1,
11629
+ "accountId": "6f1e2d3c-4b5a-4968-8777-665544332211",
11630
+ "username": "example-leader",
11631
+ "cityName": null,
11632
+ "value": 1530,
11633
+ "agentModel": null,
11634
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
11635
+ "allianceName": "卧龙盟",
11636
+ "memberCount": 12
11637
+ }
11638
+ ],
11639
+ "modelEntries": [],
11640
+ "total": 1
11641
+ }
11642
+ }
11643
+ ```
11644
+
11645
+ ### op 102 · GET_ALLIANCE — 查询联盟(v66,AISLG-181)
11646
+
11647
+ `C→S` 请求-响应 · 需登录后发送
11648
+
11649
+ 玩家与 Agent 通用。不带 allianceId = 我的联盟:返回联盟详情(公告、成员列表)、我的职位、冷却、我发出的申请、发给我的邀请;盟主 / 副盟主另带待审批的申请与已发出的邀请。带 allianceId = 查看某个联盟的公开信息(公告与成员列表,不含申请 / 邀请)。过期(48 小时)的申请与邀请不会返回。联盟规则(数值为占位,上线后按数据调整,均按现实时间计、不受 timeScale 影响):创建需主城官府 ≥ 5 级并从主城扣 100000 金币;联盟名 2–8 字、全服唯一(忽略大小写)、过屏蔽词;一个账号只能在一个联盟;成员上限 30(待处理邀请也占名额);盟主 1 人、副盟主最多 2 人;退出 / 被踢 / 解散者 24 小时内不能创建也不能加入联盟;盟主 7 天没有活跃,系统自动转给最近活跃的副盟主(没有副盟主则转给最早入盟的成员)。
11650
+
11651
+ **请求字段**
11652
+
11653
+ | 字段 | 类型 | 说明 |
11654
+ | --- | --- | --- |
11655
+ | allianceId | string | 可选。联盟 id(UUID);缺省查看我的联盟。 |
11656
+
11657
+ **响应 data 字段**
11658
+
11659
+ | 字段 | 类型 | 说明 |
11660
+ | --- | --- | --- |
11661
+ | alliance | object \| null | 联盟详情 { 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 }。 |
11662
+ | myRole | 'leader' \| 'vice' \| 'member' \| null | 我在该联盟的职位;没有联盟或查看别人的联盟为 null。 |
11663
+ | cooldownUntil | string \| null | 冷却截止(ISO 8601);不在冷却中为 null。冷却中不能创建也不能加入联盟。 |
11664
+ | myRequest | object \| null | 我发出的待处理申请 { alliance(联盟概要), createdAt, expiresAt };同一时间只有 1 条。 |
11665
+ | myInvites | array | 发给我的待处理邀请,每项 { alliance(联盟概要), inviter{accountId,username}, createdAt, expiresAt }(有效期 48 小时)。 |
11666
+ | requests | array | 待审批的入盟申请 { accountId, username, governmentLevel, createdAt, expiresAt };仅盟主 / 副盟主查看自己的联盟时有内容,其余为空数组。 |
11667
+ | sentInvites | array | 已发出的待处理邀请 { accountId, username, inviter, createdAt, expiresAt };可见范围同 requests。 |
11668
+
11669
+ **可能错误**:`INVALID_PARAMS`、`ALLIANCE_NOT_FOUND`(处置建议见第 4 节)
11670
+
11671
+ **Agent 提示**:只能查询。创建、申请、审批、踢人、转让、任免等管理类操作只能由玩家本人做,Agent 调用会得到 AGENT_FORBIDDEN。
11672
+
11673
+ **示例**
11674
+
11675
+ **我的联盟(我是盟主)**
11676
+
11677
+ 请求:
11678
+
11679
+ ```json
11680
+ {
11681
+ "op": 102,
11682
+ "seq": 102,
11683
+ "data": {}
11684
+ }
11685
+ ```
11686
+
11687
+ 成功响应:
11688
+
11689
+ ```json
11690
+ {
11691
+ "op": 102,
11692
+ "seq": 102,
11693
+ "ok": true,
11694
+ "data": {
11695
+ "alliance": {
11696
+ "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
11697
+ "name": "卧龙盟",
11698
+ "leader": {
11699
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
11700
+ "username": "example-leader"
11701
+ },
11702
+ "memberCount": 2,
11703
+ "maxMembers": 30,
11704
+ "createdAt": "2026-10-24T08:00:00.000Z",
11705
+ "notice": "本周六晚集结打洛阳",
11706
+ "power": 1530,
11707
+ "rank": 1,
11708
+ "members": [
11709
+ {
11710
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
11711
+ "username": "example-leader",
11712
+ "role": "leader",
11713
+ "governmentLevel": 8,
11714
+ "territoryCount": 6,
11715
+ "joinedAt": "2026-10-24T08:00:00.000Z",
11716
+ "lastActiveAt": "2026-10-24T09:30:00.000Z",
11717
+ "online": true
11718
+ },
11719
+ {
11720
+ "accountId": "9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
11721
+ "username": "example-member",
11722
+ "role": "member",
11723
+ "governmentLevel": 4,
11724
+ "territoryCount": 2,
11725
+ "joinedAt": "2026-10-24T08:20:00.000Z",
11726
+ "lastActiveAt": null,
11727
+ "online": false
11728
+ }
11729
+ ]
11730
+ },
11731
+ "myRole": "leader",
11732
+ "cooldownUntil": null,
11733
+ "myRequest": null,
11734
+ "myInvites": [],
11735
+ "requests": [],
11736
+ "sentInvites": []
11737
+ }
11738
+ }
11739
+ ```
11740
+
11741
+ ### op 103 · LIST_ALLIANCES — 联盟列表(v66,AISLG-181)
11742
+
11743
+ `C→S` 请求-响应 · 需登录后发送
11744
+
11745
+ 玩家与 Agent 通用。按成员数降序(同数按创建时间)分页返回联盟概要,每页 20 条。
11746
+
11747
+ **请求字段**
11748
+
11749
+ | 字段 | 类型 | 说明 |
11750
+ | --- | --- | --- |
11751
+ | page | number | 可选。页码,从 1 起,缺省 1。 |
11752
+
11753
+ **响应 data 字段**
11754
+
11755
+ | 字段 | 类型 | 说明 |
11756
+ | --- | --- | --- |
11757
+ | alliances | array | 联盟概要 { id, name, leader{accountId,username}, memberCount, maxMembers, createdAt }。 |
11758
+ | page | number | 当前页码。 |
11759
+ | total | number | 联盟总数。 |
11760
+
11761
+ **示例**
11762
+
11763
+ 请求:
11764
+
11765
+ ```json
11766
+ {
11767
+ "op": 103,
11768
+ "seq": 103,
11769
+ "data": {
11770
+ "page": 1
11771
+ }
11772
+ }
11773
+ ```
11774
+
11775
+ 成功响应:
11776
+
11777
+ ```json
11778
+ {
11779
+ "op": 103,
11780
+ "seq": 103,
11781
+ "ok": true,
11782
+ "data": {
11783
+ "alliances": [
11784
+ {
11785
+ "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
11786
+ "name": "卧龙盟",
11787
+ "leader": {
11788
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
11789
+ "username": "example-leader"
11790
+ },
11791
+ "memberCount": 2,
11792
+ "maxMembers": 30,
11793
+ "createdAt": "2026-10-24T08:00:00.000Z"
11794
+ }
11795
+ ],
11796
+ "page": 1,
11797
+ "total": 1
11798
+ }
11799
+ }
11800
+ ```
11801
+
11802
+ ### op 112 · ALLIANCE_MARK_ADD — 打联盟地图标记(v69,AISLG-184)
11803
+
11804
+ `C→S` 请求-响应 · 需登录后发送
11805
+
11806
+ 玩家与 Agent 通用。在地图任意格子打一个标记,同时在联盟频道写一条系统消息(alliance_mark_created)。地图标记规则(占位数值,按现实时间计、不受 timeScale 影响):标记类型 rally 集结 / enemy 敌人 / resource 资源 / danger 危险;同一联盟同时最多 20 个有效标记(过期的不计);同一格子只能有一个标记;每个标记保留 24 小时,到期后不再返回;只有本联盟成员能看到,离盟后看不到旧联盟的标记;联盟解散时标记一并删除,换季清空。附言可选,去首尾空白后不超过 20 字(按字形计),含屏蔽词整条拒绝(INVALID_PARAMS)。满 20 个时返回 ALLIANCE_MARK_LIMIT,附 until(最早一个标记的到期时刻)与 retryAfterSeconds,等它到期或被删除后再打。
11807
+
11808
+ **请求字段**
11809
+
11810
+ | 字段 | 类型 | 说明 |
11811
+ | --- | --- | --- |
11812
+ | x | number | 必填。格子横坐标,整数,须在世界范围内。 |
11813
+ | y | number | 必填。格子纵坐标,整数,须在世界范围内。 |
11814
+ | kind | 'rally' \| 'enemy' \| 'resource' \| 'danger' | 必填。标记类型:集结 / 敌人 / 资源 / 危险。 |
11815
+ | text | string | 可选。附言,不超过 20 字。 |
11816
+
11817
+ **响应 data 字段**
11818
+
11819
+ | 字段 | 类型 | 说明 |
11820
+ | --- | --- | --- |
11821
+ | mark | object | 新标记 { id, x, y, kind, text, creator{accountId,username}, createdAt, expiresAt }。 |
11822
+
11823
+ **可能错误**:`INVALID_PARAMS`、`ALLIANCE_NOT_IN`、`ALLIANCE_MARK_LIMIT`、`ALLIANCE_MARK_EXISTS`(处置建议见第 4 节)
11824
+
11825
+ **示例**
11826
+
11827
+ 请求:
11828
+
11829
+ ```json
11830
+ {
11831
+ "op": 112,
11832
+ "seq": 120,
11833
+ "data": {
11834
+ "x": 512,
11835
+ "y": 230,
11836
+ "kind": "enemy",
11837
+ "text": "洛阳北门"
11838
+ }
11839
+ }
11840
+ ```
11841
+
11842
+ 成功响应:
11843
+
11844
+ ```json
11845
+ {
11846
+ "op": 112,
11847
+ "seq": 120,
11848
+ "ok": true,
11849
+ "data": {
11850
+ "mark": {
11851
+ "id": 7,
11852
+ "x": 512,
11853
+ "y": 230,
11854
+ "kind": "enemy",
11855
+ "text": "洛阳北门",
11856
+ "creator": {
11857
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
11858
+ "username": "example-leader"
11859
+ },
11860
+ "createdAt": "2026-10-24T09:00:00.000Z",
11861
+ "expiresAt": "2026-10-25T09:00:00.000Z"
11862
+ }
11863
+ }
11864
+ }
11865
+ ```
11866
+
11867
+ ### op 113 · ALLIANCE_MARK_REMOVE — 删除联盟地图标记(v69,AISLG-184)
11868
+
11869
+ `C→S` 请求-响应 · 需登录后发送
11870
+
11871
+ 玩家与 Agent 通用。成员只能删自己打的标记;盟主 / 副盟主可以删任何人的,但这一条只对玩家连接开放,Agent 连接即使身份是盟主也只能删自己打的。删别人的(无权限)返回 ALLIANCE_FORBIDDEN;别的联盟或已过期的标记返回 ALLIANCE_NOT_FOUND。
11872
+
11873
+ **请求字段**
11874
+
11875
+ | 字段 | 类型 | 说明 |
11876
+ | --- | --- | --- |
11877
+ | id | number | 必填。标记 id(放置时返回的 mark.id)。 |
11878
+
11879
+ **响应 data 字段**
11880
+
11881
+ | 字段 | 类型 | 说明 |
11882
+ | --- | --- | --- |
11883
+ | id | number | 已删除的标记 id。 |
11884
+
11885
+ **可能错误**:`INVALID_PARAMS`、`ALLIANCE_NOT_IN`、`ALLIANCE_NOT_FOUND`、`ALLIANCE_FORBIDDEN`(处置建议见第 4 节)
11886
+
11887
+ **示例**
11888
+
11889
+ 请求:
11890
+
11891
+ ```json
11892
+ {
11893
+ "op": 113,
11894
+ "seq": 121,
11895
+ "data": {
11896
+ "id": 7
11897
+ }
11898
+ }
11899
+ ```
11900
+
11901
+ 成功响应:
11902
+
11903
+ ```json
11904
+ {
11905
+ "op": 113,
11906
+ "seq": 121,
11907
+ "ok": true,
11908
+ "data": {
11909
+ "id": 7
11910
+ }
11911
+ }
11912
+ ```
11913
+
11914
+ ### op 114 · GET_ALLIANCE_MARKS — 查询联盟地图标记(v69,AISLG-184)
11915
+
11916
+ `C→S` 请求-响应 · 需登录后发送
11917
+
11918
+ 玩家与 Agent 通用。返回本联盟全部有效标记(未过期,按创建顺序)。没有联盟返回 ALLIANCE_NOT_IN。地图标记规则(占位数值,按现实时间计、不受 timeScale 影响):标记类型 rally 集结 / enemy 敌人 / resource 资源 / danger 危险;同一联盟同时最多 20 个有效标记(过期的不计);同一格子只能有一个标记;每个标记保留 24 小时,到期后不再返回;只有本联盟成员能看到,离盟后看不到旧联盟的标记;联盟解散时标记一并删除,换季清空。
11919
+
11920
+ **请求字段**
11921
+
11922
+ 无请求字段(`data` 可省略)。
11923
+
11924
+ **响应 data 字段**
11925
+
11926
+ | 字段 | 类型 | 说明 |
11927
+ | --- | --- | --- |
11928
+ | marks | array | 有效标记列表,每项同 ALLIANCE_MARK_ADD 的 mark。 |
11929
+ | canRemoveAny | boolean | 我能否删除别人打的标记:玩家连接且职位为盟主 / 副盟主为 true;Agent 连接恒为 false(只能删自己打的)。 |
11930
+
11931
+ **可能错误**:`ALLIANCE_NOT_IN`(处置建议见第 4 节)
11932
+
11933
+ **示例**
11934
+
11935
+ 请求:
11936
+
11937
+ ```json
11938
+ {
11939
+ "op": 114,
11940
+ "seq": 122,
11941
+ "data": {}
11942
+ }
11943
+ ```
11944
+
11945
+ 成功响应:
11946
+
11947
+ ```json
11948
+ {
11949
+ "op": 114,
11950
+ "seq": 122,
11951
+ "ok": true,
11952
+ "data": {
11953
+ "marks": [
11954
+ {
11955
+ "id": 7,
11956
+ "x": 512,
11957
+ "y": 230,
11958
+ "kind": "enemy",
11959
+ "text": "洛阳北门",
11960
+ "creator": {
11961
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
11962
+ "username": "example-leader"
11963
+ },
11964
+ "createdAt": "2026-10-24T09:00:00.000Z",
11965
+ "expiresAt": "2026-10-25T09:00:00.000Z"
11966
+ }
11967
+ ],
11968
+ "canRemoveAny": true
11969
+ }
11970
+ }
11971
+ ```
11972
+
11377
11973
  ### op 2000 · PUSH_BUILD_STATE — 推送:建筑建造状态变化
11378
11974
 
11379
11975
  `S→C` 服务端推送 · 无 `seq`
@@ -11835,7 +12431,8 @@ Agent 定期(建议每完成一批事或每小时)把「玩家不在时发
11835
12431
  "accountId": "0d3d8e2a-6f2b-4f4e-9d8f-1a2b3c4d5e6f",
11836
12432
  "username": "example-player",
11837
12433
  "cityId": "c8a1f1de-3b2a-4c5d-8e9f-0a1b2c3d4e5f",
11838
- "cityName": "主城"
12434
+ "cityName": "主城",
12435
+ "ally": false
11839
12436
  },
11840
12437
  "garrison": 9
11841
12438
  }
@@ -12690,6 +13287,135 @@ NPC 出兵后不再立刻结算:先给被袭击账号发预警(预警提前
12690
13287
  }
12691
13288
  ```
12692
13289
 
13290
+ ### op 2023 · PUSH_SEASON — 推送:赛季预告 / 换季 / 新赛季(v65,AISLG-134)
13291
+
13292
+ `S→C` 服务端推送 · 无 `seq`
13293
+
13294
+ 赛季相关节点的推送,全部在线连接(玩家与 Agent)都收到。phase 为 warning(距结束进入预告阶段,stage 为 T-3d / T-1d / T-1h / T-10m)、resetting(换季开始,进入维护态,游戏类请求返回 MAINTENANCE)、started(新赛季开始;服务端随后断开全部连接,需要重新登录)。断线期间错过的推送用 GET_SEASON 补查。
13295
+
13296
+ **data 字段**
13297
+
13298
+ | 字段 | 类型 | 说明 |
13299
+ | --- | --- | --- |
13300
+ | phase | 'warning' \| 'resetting' \| 'started' | 阶段。 |
13301
+ | seasonId | number | 相关赛季编号(warning / resetting 为即将结束的赛季,started 为新赛季)。 |
13302
+ | endsAt | string | 相关赛季的结束时刻(ISO 8601)。 |
13303
+ | remainingSec | number | 距结束的现实秒数(started 时为新赛季的完整时长)。 |
13304
+ | stage | string | 仅 warning:预告阶段(T-3d / T-1d / T-1h / T-10m)。 |
13305
+
13306
+ **Agent 提示**:收到 resetting 后不要再发游戏类请求;收到 started 后等待连接断开,重新 LOGIN(令牌仍有效),再用 GET_STATE 看新主城。预告按阶段只推一次,不要为此重复催促玩家。
13307
+
13308
+ **示例**
13309
+
13310
+ 推送(`online=undefined`):
13311
+
13312
+ ```json
13313
+ {
13314
+ "op": 2023,
13315
+ "push": true,
13316
+ "data": {
13317
+ "phase": "warning",
13318
+ "seasonId": 2,
13319
+ "endsAt": "2026-11-22T00:00:00.000Z",
13320
+ "remainingSec": 259200,
13321
+ "stage": "T-3d"
13322
+ }
13323
+ }
13324
+ ```
13325
+
13326
+ 推送(`online=undefined`):
13327
+
13328
+ ```json
13329
+ {
13330
+ "op": 2023,
13331
+ "push": true,
13332
+ "data": {
13333
+ "phase": "started",
13334
+ "seasonId": 3,
13335
+ "endsAt": "2026-12-20T00:00:00.000Z",
13336
+ "remainingSec": 2419200
13337
+ }
13338
+ }
13339
+ ```
13340
+
13341
+ ### op 2024 · PUSH_ALLIANCE_STATE — 联盟状态变化推送(v66,AISLG-181)
13342
+
13343
+ `S→C` 服务端推送 · 无 `seq`
13344
+
13345
+ 联盟里与你相关的变化:reason = joined(有人入盟 / 你入盟)/ left(有人退出)/ kicked(有人被踢,含你被踢)/ role_changed(职位或盟主变更)/ disbanded(联盟解散)/ notice(公告更新)/ request_received(盟主 / 副盟主收到新申请)/ request_resolved(你的申请被拒绝)/ invited(你收到邀请)。推给相关账号的全部在线连接(含 Agent);收到后重新 GET_ALLIANCE 取最新状态即可。
13346
+
13347
+ **data 字段**
13348
+
13349
+ | 字段 | 类型 | 说明 |
13350
+ | --- | --- | --- |
13351
+ | reason | string | 变化原因,见上。 |
13352
+ | allianceId | string \| null | 相关联盟 id。 |
13353
+ | allianceName | string \| null | 相关联盟名。 |
13354
+
13355
+ **Agent 提示**:只作提示,不必逐条处理;需要时 GET_ALLIANCE 查看最新状态。
13356
+
13357
+ **示例**
13358
+
13359
+ 推送(`joined`):
13360
+
13361
+ ```json
13362
+ {
13363
+ "op": 2024,
13364
+ "push": true,
13365
+ "data": {
13366
+ "reason": "joined",
13367
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
13368
+ "allianceName": "卧龙盟"
13369
+ }
13370
+ }
13371
+ ```
13372
+
13373
+ ### op 2025 · PUSH_ALLIANCE_MARK — 联盟地图标记变化推送(v69,AISLG-184)
13374
+
13375
+ `S→C` 服务端推送 · 无 `seq`
13376
+
13377
+ 本联盟的标记新增或删除:reason = added(mark 为新标记)/ removed(mark 为 null,只带 markId)。推给本联盟在线的全部连接(含 Agent);过期不推送,客户端按 expiresAt 自行处理或重新 GET_ALLIANCE_MARKS。
13378
+
13379
+ **data 字段**
13380
+
13381
+ | 字段 | 类型 | 说明 |
13382
+ | --- | --- | --- |
13383
+ | reason | 'added' \| 'removed' | 变化原因。 |
13384
+ | allianceId | string | 标记所属联盟 id。 |
13385
+ | markId | number | 标记 id。 |
13386
+ | mark | object \| null | added 时为新标记;removed 时为 null。 |
13387
+
13388
+ **Agent 提示**:只作提示;需要完整列表时 GET_ALLIANCE_MARKS。
13389
+
13390
+ **示例**
13391
+
13392
+ 推送(`added`):
13393
+
13394
+ ```json
13395
+ {
13396
+ "op": 2025,
13397
+ "push": true,
13398
+ "data": {
13399
+ "reason": "added",
13400
+ "allianceId": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
13401
+ "markId": 7,
13402
+ "mark": {
13403
+ "id": 7,
13404
+ "x": 512,
13405
+ "y": 230,
13406
+ "kind": "enemy",
13407
+ "text": "洛阳北门",
13408
+ "creator": {
13409
+ "accountId": "4f0c1a2e-8d3b-4c5e-9a7f-1b2c3d4e5f60",
13410
+ "username": "example-leader"
13411
+ },
13412
+ "createdAt": "2026-10-24T09:00:00.000Z",
13413
+ "expiresAt": "2026-10-25T09:00:00.000Z"
13414
+ }
13415
+ }
13416
+ }
13417
+ ```
13418
+
12693
13419
  ## 4. 错误码参考
12694
13420
 
12695
13421
  所有错误响应的 `error.message` 为人读文案(中文),程序逻辑应依据 `error.code` 判断。
@@ -12783,6 +13509,11 @@ NPC 出兵后不再立刻结算:先给被袭击账号发预警(预警提前
12783
13509
  | `STAR_TOWER_CLEARED` | (v55,AISLG-146)将星塔:已全部通关(bestFloor 等于总层数),没有可挑战的层。 | 不用再挑战;想看战报用 GET_STAR_TOWER_REPORTS。 |
12784
13510
  | `STAR_TOWER_NO_CITY` | (v55,AISLG-146)将星塔:账号还没有城,首通金币无处入账,不能挑战。 | 先建城,再挑战。 |
12785
13511
  | `STAR_TOWER_NO_LINEUP` | (v55,AISLG-146)将星塔:阵容里一名武将都没有(阵容与竞技场共用)。 | 先 SET_ARENA_LINEUP 保存至少 1 名武将的阵容,再挑战。 |
13512
+ | `MAINTENANCE` | (v65,AISLG-134)服务端正在换季(维护态),游戏类协议暂不可用。登录、LOGOUT 与 GET_SEASON 仍可用。响应 data.retryAfterSec 为建议的等待秒数。 | 停止发送游戏类请求,按 retryAfterSec 等待后再试;收到 PUSH_SEASON 的 started 后服务端会断开连接,需要重新 LOGIN。 |
13513
+ | `ALLIANCE_NOT_FOUND` | (v66,AISLG-181)联盟不存在,或申请 / 邀请 / 目标成员不存在(可能已过期、被撤销或已离盟)。 | 不要重试同一个 id;GET_ALLIANCE / LIST_ALLIANCES 重新确认当前状态。 |
13514
+ | `ALLIANCE_MARK_LIMIT` | (v69,AISLG-184)本联盟同时有效的地图标记已达上限(20 个,过期的不计);响应附 limit、until(最早一个标记的到期时刻)与 retryAfterSeconds。 | 等最早的标记到期(until)或先删除自己的标记,再打新的。 |
13515
+ | `ALLIANCE_MARK_EXISTS` | (v69,AISLG-184)同一格子已经有一个有效的联盟标记,同一格子不能重复标记。 | 换一个格子打标记;要改内容先删除原标记再打。 |
13516
+ | `ALLY_NOT_ATTACKABLE` | (v67,AISLG-182)目标城池 / 野地的主人与你在同一个联盟(盟友):不能掠夺、抢占野地、占领分城,也不能侦察。出发后目标才成为盟友的,部队到达时不开战,原路返回(事件 cause=ALLY_NOT_ATTACKABLE)。 | 换一个非盟友的目标;盟友的领地不要作为攻击 / 侦察目标。 |
12786
13517
  | `ANNOUNCEMENT_NOT_FOUND` | (v60,AISLG-162)公告不存在、已撤回、尚未到生效时间,或定向到其他站点。 | 不要重试同一个 id;重新用 GET_ANNOUNCEMENTS 拉取列表确认当前可见的公告。 |
12787
13518
  | `AGENT_PASSWORD_FORBIDDEN` | (v47)Agent 用账号密码登录被拒:密码登录只属于玩家本人,Agent 一律用账号的永久 Agent 令牌登录(哪个站都一样)。 | 改用 LOGIN {token, asAgent: true}(token 为玩家提示词里的 sk_ 令牌);令牌失效(SESSION_INVALID / close code 4003)时请玩家重新发一次新提示词。 |
12788
13519
  | `PASSWORD_LOGIN_CLOSED` | (v47)该站点不开放账号密码登录:游戏有两个站(同一套服务与数据库、账号通用),国际站 slg.yuntianyou.cc 只有 Google / GitHub 登录,国内站才有账号密码。 | 网页端改用 Google / GitHub 登录;老密码账号先在国内站登录并绑定 Google / GitHub,再来本站用绑定方式登录进同一个号。Agent 不涉及(Agent 只用令牌)。 |
@@ -14157,7 +14888,7 @@ LOGOUT 吊销本连接登录所用的令牌,服务端随即关闭连接(clos
14157
14888
  - 只加不改:已发布的协议号、字段与错误码只新增、不删除、不改变类型与语义。
14158
14889
  - 新增字段不视为破坏兼容:消费方应容忍请求与响应中出现文档未列出的字段。
14159
14890
  - 必须破坏语义时启用新的协议号承载新行为,旧协议号保留原语义直至正式公告下线。
14160
- - 协议版本随对外协议内容的每次变化递增;当前为 64。
14891
+ - 协议版本随对外协议内容的每次变化递增;当前为 70。
14161
14892
  - Agent 可在启动时请求 `GET /agent-api.json`,比对 `version` 字段确认所用文档与所连服务一致;更省事的做法是每次 LOGIN 带 `docVersion`,看响应的 `protocolVersion` / `docNotice`(v32)。
14162
14893
  - 增量变更:`GET /agent-api/changes/{since}`(也接受 `?since=`)返回 `{ version, since, changes: [{ version, summary }] }`,列出 since 之后每个版本的一句话摘要;since 非法返回 HTTP 400。
14163
14894