오픈 플랫폼
Haneoka 계정은 도구가 그 계정의 데이터를 읽거나 바꿀 수 있는 토큰을 발급할 수 있습니다. 편성 계산은 서버에서 하지 않습니다. 코드가 카드를 읽은 뒤 Haneoka 편성 도구와 같은 엔진을 호출한 기기에서 실행합니다.
| 범위 | 허용 |
|---|---|
team:read | 박스, 계정 보너스, 저장한 편성 |
team:write | 박스와 저장한 편성 변경 |
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입니다.
박스 읽기
섹션 제목: “박스 읽기”curl -H "Authorization: Bearer $HANEOKA_TOKEN" \ https://haneoka.org/api/v1/team-data/intlserver는 카탈로그 서버(jp 또는 intl)입니다. 어느 오리진에서나 호출할 수 있습니다. 쿠키는 무시되며 토큰만 인증 정보입니다.
{ "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 | 박스 버전. 0은 이 서버에 박스가 없다는 뜻입니다 |
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();}목표, 조건, 결과 필드는 기기에서 계산하기를 참고하세요.
박스 변경
섹션 제목: “박스 변경”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 랭크 |
게임 계정과 가챠 기록
섹션 제목: “게임 계정과 가챠 기록”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 | 필요한 권한이 있는 토큰을 만드세요 |
404 | server_not_found | jp 또는 intl을 사용하세요 |
413 | box_too_large | 박스 한도에 도달했습니다 |
422 | invalid_changes | 키와 값을 확인하세요 |
429 | rate_limit_exceeded | 잠시 후 다시 시도하세요 |
도구에 Haneoka 출처를 표시해 주세요. createTeamBuilder가 반환한 attribution에 문구와 링크가 있습니다.