开放平台
Haneoka 账号可以签发令牌,让工具读取或更新该账号的数据。配队计算不是服务器功能:你的代码读取卡牌后,在调用方设备上运行与 Haneoka 配队页面相同的引擎。
| 范围 | 允许 |
|---|---|
team:read | Box、账号加成和保存的队伍 |
team:write | 修改 Box 和保存的队伍 |
gacha:read | 云端抽卡记录 |
games:read | 绑定的游戏账号及其摘要 |
profile:read | UID、显示名称、用户名和简介 |
令牌不能在社区发帖、修改登录信息、删除账号或管理其他令牌。
| 步骤 | 运行位置 |
|---|---|
| 创建令牌 | Haneoka 账号设置 |
| 读取卡牌和加成 | GET /api/v1/team-data/{server} |
| 计算配队 | 调用方浏览器的 Web Worker |
- 登录 haneoka.org,打开账号 → 登录与安全。
- 在 API 令牌下填写名称,选择 30 天、90 天或 1 年,只勾选工具需要的权限。
- 复制令牌。它以
hnk_开头,只显示一次。
每个账号最多有 10 个有效令牌。在同一列表撤销后立即失效,账号被限制或删除时令牌也会失效。
请像对待密码一样对待令牌:让每位用户把自己的令牌粘贴到你的工具里,保存在其设备上,不要提交到代码库,也不要放进 URL。
curl -H "Authorization: Bearer $HANEOKA_TOKEN" https://haneoka.org/api/v1/open/me{ "token": { "name": "My tool", "expiresAt": 1801176000000, "scopes": ["team:read", "profile:read"] }, "profile": { "uid": 1024, "displayName": "Player", "handle": "player", "bio": null }}没有 profile:read 时 profile 为 null。
读取 Box
Section titled “读取 Box”curl -H "Authorization: Bearer $HANEOKA_TOKEN" \ https://haneoka.org/api/v1/team-data/intlserver 是图鉴服务器:jp 或 intl。任何来源都可以调用此接口。接口忽略 Cookie,令牌是唯一凭据。
{ "server": "intl", "revision": 42, "members": [ { "key": "m1", "cardId": 1, "level": 60, "awake": 2, "rank": 3, "liveSkillLevel": 5, "gekisoSkillLevel": null } ], "snaps": [{ "key": "s1", "cardId": 1, "level": 40, "rank": 2 }], "player": { "characterRanks": { "1": 20 }, "characterTotalRank": null, "bandItems": { "1": 3 }, "vipRank": null, "characterMemory": {}, "musicMemory": {} }}| 字段 | 含义 |
|---|---|
revision | Box 版本。0 表示用户在此服务器没有保存 Box |
members、snaps | 用户标记为参与的卡牌,格式即引擎输入 |
player | 账号全局加成 |
teams | 保存的队伍 |
养成字段为 null | 未记录,由 unknownPolicy 决定引擎如何填充 |
fetchTeamData 读取数据,createTeamBuilder 加载引擎。读取之后的全部步骤都在本地运行。
import { createTeamBuilder, fetchTeamData } from "https://haneoka.org/tools/team-builder.js";
const server = "intl";const { members, snaps, player } = await fetchTeamData({ server, token });const engine = await createTeamBuilder({ server, maxWorkers: navigator.hardwareConcurrency });try { const result = await engine.run({ members, snaps, player, unknownPolicy: "min", goal: { kind: "power", song: null, challengeEventId: null }, constraints: { requiredMembers: [], excludedMembers: [], requiredSnaps: [], excludedSnaps: [], leader: null, bindings: [], noSnaps: false, minBonusPercent: null }, k: 5, timeLimitMs: 10000, }); console.log(result.overall, result.stopReason);} finally { engine.dispose();}目标、约束和结果字段见在用户设备上运行计算。没有浏览器的脚本可以把同样的数据发给该页介绍的本地 HTTP 服务。
修改 Box
Section titled “修改 Box”使用 team:write 一次最多发送 4000 项修改。null 表示清除该键。网站下次同步时会读到修改。
curl -X POST -H "Authorization: Bearer $HANEOKA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"changes":[{"key":"m.1.own","value":true},{"key":"m.1.lvl","value":60}]}' \ https://haneoka.org/api/v1/team-data/intl{ "revision": 43, "changed": 2 }| 键 | 值 |
|---|---|
m.<card>.own、s.<card>.own | 拥有成员或留影 |
m.<card>.use、s.<card>.use | 是否参与搜索 |
m.<card>.lvl、awk、rnk、sk、gsk | 等级、特训、觉醒、演出技能、激奏技能 |
s.<card>.lvl、rnk | 留影等级和突破 |
cr.<character>、cm.<character>、mm.<song>、bi.<item> | 角色等级、角色记忆、歌曲记忆、乐队道具 |
p.vip | VIP 等级 |
游戏账号和抽卡记录
Section titled “游戏账号和抽卡记录”GET /api/v1/open/game-accountsGET /api/v1/open/gacha-historyGET /api/v1/open/gacha-history/{accountKey}列表为每个游戏账号返回一个 accountKey,完整记录另含 histories。
| 状态码 | 错误码 | 处理 |
|---|---|---|
401 | invalid_token | 令牌缺失、已撤销或已过期,请新建 |
403 | account_restricted | 账号被限制或已删除 |
403 | insufficient_scope | 新建带该权限的令牌 |
413 | box_too_large | 已达到 Box 上限 |
422 | invalid_changes | 检查键和值 |
404 | server_not_found | 使用 jp 或 intl |
429 | rate_limit_exceeded | 稍后重试 |
请在工具中注明 Haneoka。createTeamBuilder 返回对象的 attribution 提供了文字和链接。