-
Notifications
You must be signed in to change notification settings - Fork 0
Contract
Vocino edited this page Aug 20, 2026
·
4 revisions
Single source of truth: warband-pro/addon docs/CONTRACT.md. Web side must match src/lib/warband-import.ts.
wb1!<base64url(deflate(json))>
- No newlines, no spaces, single line paste (EditBox high but avoid whitespace)
-
wb0!— Camp DNA share URLs,wb1!— inventory,wb2!reserved talent loadouts - One envelope for 1 char and 20, so decoder has no branch
{
"v": 1,
"addon": "1.0.0",
"exportedAt": 1724001234,
"gameVersion": "12.1.0",
"interface": 120100,
"bundle": { "count": 3, "freshestSeenAt": 1724001200, "oldestSeenAt": 1723980000 },
"characters": [CharacterObject, ...]
}{
"guid": "Player-112-0A1B2C3D",
"name": "Vocnar",
"realm": "Wyrmrest Accord", "realmSlug": "wyrmrest-accord",
"faction": "Horde", "class": "DRUID", "classId": 11,
"level": 80, "xp":123456, "restXP":234567,
"guild": {"name":"Moxes","rank":"Initiate","rankIndex":2},
"gold": 8457392,
"bags": [{"bagID":0,"size":30,"free":3,"items":[{"id":211493,"count":20,"link":"|Hitem:211493::::::::80:::::::::|h[Phial]|h","quality":2}]}],
"bank": [...], "bankBags": [...], "reagentBank": {"size":98,"free":12,"items":[...]},
"warbandBank": {"seenAt":1723999000,"seenByGuid":"...","tabs":[[{id,count}]]},
"mail": {"countItems":2,"goldPending":120000,"soonestExpiryHours":12,"seenAt":null},
"auctions": {"countActive":3,"goldHeld":500000,"seenAt":1723998000},
"currencies": [{"id":2815,"name":"Resonance Crystals","quantity":4500,"maxQuantity":20000}],
"professions": [{"id":171,"name":"Alchemy","skill":100,"maxLevel":100}],
"instances": [{"name":"Nerub-ar Palace","instanceID":1273,"difficulty":3,"locked":true,"bosses":[...]}],
"keystone": {"level":12,"dungeonID":503},
"weeklyVault": {"raid":{"progress":1,"threshold":3,"unlocked":false},"mplus":{"progress":4,"threshold":8,"unlocked":true}},
"consumables": {"phial":120,"healthPotion":80,"foodFeast":200},
"seenAt": {"lastSeen":1724001000,"bag":1724001000,"bank":1723999000,"warbank":1723999000,"currency":1724001000,"instance":1723998000,"vault":1723997000}
}- All
_seentimes = unix seconds UTC fromtime(), not ms (web converts). Null = never seen. -
items= inventory only, no equips (API has it). Link optional for debug. - Bank never opened:
free=null,items=[]→ unknown vs empty (UI says "not opened" not "0 free", avoids wrong "clear bank" urge). - Warband bank
seenByGuid→ web "by Vocnar" credit line, valid across alts. Payload root + separate D1 tablewarband_bank_cache(one row per user) avoids repeating 5 tabs × 6 chars (~22KB saved, deflate 32KB window can't fold copies). -
currencies.maxQuantity0=no cap,weeklyMax0=not weekly-capped. -
consumablesderived cache for Tonight Plan speed: count known consumable ids, not name regex. Absent ⇒ unknown, not zero (prevents hard-block on "0 phials" when we didn't look). -
instances.bossesbool order matches encounter order, name included.
-
Not
LibDeflate:EncodeForPrint. That uses LibDeflate 6-bit alphabet — neither base64 nor base64url — swap+/for-_doesn't make itatob-readable. Addon carries real RFC4648 §5 encoder. -
Raw deflate, not zlib.
CompressDeflateemits bare stream, no header →DecompressionStream('deflate')rejects. Must'deflate-raw'orpako.inflateRaw. Same fix on both sides.
- 20-char cap (DoS)
- 1MB decoded cap (not 25KB — measured 1 full char 39KB JSON/8.6KB wire, 6 154KB/26KB, 20 474KB/73KB). Enforced chunk-by-chunk during inflate, not after (bomb mitigation).
- Validated
v==1, array 1..20, each hasguid,name,seenAt.lastSeen. - Base64url deflated via LibDeflate lvl9 → EncodeForPrint→b64url strip
=→ prefixwb1!.
- Section absent ⇒ never seen ⇒ unknown ⇒ UI prints
not opened/ greys, doesn't delete. - Char missing from bundle ⇒ not gone ⇒ row keeps old snapshot aging red.
- Consumables absent until table filled — absent ≠ zero.
-
docs/contract/vectors/v1-min.json630 bytes (min) -
v1-min.wb1test string Add vectorsv1-full.json,v1-6.jsonplanned for CIcheck-contract-vectors.
Root + warband_bank_cache table. Each char carries seenAt.warbank for dots. seenByName holds UI credit.
- Single
wb1!version stringent. Any field change bumps prefix and needs web importer update same day (broken paste if sides disagree). Web does version check on prefix first.
Spec lives in addon repo, enforced here and in app warband-import.ts.
Maintained alongside Warband.pro App and Addon. Syncs on push. Companion for Warband.pro. MIT. Draft version 0 until CurseForge live.
Start
Integration
Internals