docs: add badge fetching design, update verified items (TODO-042,058,062,065)
Badge fetching design with Protobuf parsing, 24h cache refresh, cacache integration. Mark TODO-042 verified, TODO-058 monitoring, TODO-062 complete.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# Badge Fetching Design (TODO-065)
|
||||
|
||||
## Purpose
|
||||
|
||||
Fetch, cache, and display TeamSpeak client badges. Badges are visual indicators (icons) shown next to client names in the UI.
|
||||
|
||||
## Protocol Details
|
||||
|
||||
**Source:** `badges-content.teamspeak.com/list`
|
||||
|
||||
- **Format:** Protobuf (binary)
|
||||
- **Refresh:** Every 24 hours
|
||||
- **Cache location:** `cache/badges` (via cacache)
|
||||
|
||||
**Protobuf structure (from YaTQA §8.9):**
|
||||
1. `BigNum`: revision number
|
||||
2. `BigNum`: Unix timestamp
|
||||
3. Repeated badge entries:
|
||||
- GUID (string)
|
||||
- Name (string)
|
||||
- URL base (string, used to construct icon URL)
|
||||
- Description (string)
|
||||
- Timestamp
|
||||
- Unknown field (1-3 variants)
|
||||
|
||||
**Badge references in protocol:**
|
||||
- Server sends `client_badges` field in client info events
|
||||
- Format: `overwolf=0:badges=GUID1=GUID2=...`
|
||||
- Client looks up badge definitions by GUID, fetches icon by URL base
|
||||
|
||||
## Architecture
|
||||
|
||||
### New module: `crates/chanora_cache/src/badges.rs`
|
||||
|
||||
```
|
||||
badges.rs
|
||||
├── BadgeMeta { guid, name, url_base, description }
|
||||
├── BadgeCache
|
||||
│ ├── fetch_badge_list() -> Vec<BadgeMeta>
|
||||
│ ├── get_icon(guid) -> Option<bytes>
|
||||
│ ├── refresh_if_stale()
|
||||
│ └── metadata: RwLock<HashMap<Guid, BadgeMeta>>
|
||||
```
|
||||
|
||||
### Extend `chanora_cache/src/lib.rs`
|
||||
|
||||
- Add `PREFIX_BADGE: &str = "bg_"` for badge icon blobs
|
||||
- Update `validate_key()` to accept badge prefix (GUID format: 8-4-4-4-12 hex)
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
1. On connect → server sends client_badges (GUIDs)
|
||||
2. BadgeCache.refresh_if_stale():
|
||||
- Check last_refresh timestamp
|
||||
- If >24h: fetch badges-content.teamspeak.com/list
|
||||
- Parse Protobuf → Vec<BadgeMeta>
|
||||
- Update metadata map
|
||||
3. For each GUID in client_badges:
|
||||
- Lookup BadgeMeta by GUID
|
||||
- Fetch icon from url_base (HTTP GET)
|
||||
- Cache icon blob in BlobCache (PREFIX_BADGE + guid)
|
||||
- Return icon bytes to UI
|
||||
4. Flutter UI displays badge icons in:
|
||||
- Client info panel (profile)
|
||||
- Chat message sender badges
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Crate | Status | Purpose |
|
||||
|-------|--------|---------|
|
||||
| `reqwest` | Already in `chanora_protocol` | HTTP fetch |
|
||||
| `prost` | **Add** | Protobuf parsing |
|
||||
| `cacache` | Already in `chanora_cache` | Blob storage |
|
||||
| `tokio` | Already | Async runtime |
|
||||
|
||||
**Cargo.toml additions for `chanora_cache`:**
|
||||
```toml
|
||||
reqwest = { version = "0.13", default-features = false, features = ["rustls-tls"] }
|
||||
prost = "0.13"
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
|
||||
| Component | Integration |
|
||||
|-----------|-------------|
|
||||
| `chanora_protocol/src/adapter.rs` | Parse `client_badges` from `notifyclientupdated` events |
|
||||
| `chanora_bridge` | Expose `get_badge_icon(guid)` and `get_client_badges(client_id)` to Flutter |
|
||||
| Flutter UI | Display badge icons in `ClientInfoPanel` and `ChatMessage` widgets |
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
- **Create:** `crates/chanora_cache/src/badges.rs`
|
||||
- **Modify:** `crates/chanora_cache/src/lib.rs` (add `PREFIX_BADGE`, export module)
|
||||
- **Modify:** `crates/chanora_cache/Cargo.toml` (add reqwest, prost)
|
||||
- **Modify:** `crates/chanora_protocol/src/adapter.rs` (parse client_badges)
|
||||
- **Modify:** `crates/chanora_bridge/src/` (expose badge API to Flutter)
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Network failure:** Log warning, serve stale cache if available, retry on next refresh
|
||||
- **Protobuf parse error:** Log error, keep previous badge data, alert user "badges unavailable"
|
||||
- **Icon fetch failure:** Cache miss, show placeholder or skip badge display
|
||||
|
||||
## Effort Estimate
|
||||
|
||||
**L (3-5 days)**
|
||||
- Day 1: Protobuf schema research, add prost dependency, parse badge list
|
||||
- Day 2: BadgeCache implementation, icon fetch and caching
|
||||
- Day 3: Protocol adapter integration (parse client_badges)
|
||||
- Day 4: Flutter bridge API, UI display
|
||||
- Day 5: Testing, error handling, edge cases
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **Protobuf schema:** Need to define `.proto` file or use dynamic parsing. Prost requires compile-time schema — may need to reverse-engineer from reference or use `protobuf` crate for runtime parsing.
|
||||
2. **Icon URL construction:** Exact URL pattern for badge icons needs verification (likely `https://badges-content.teamspeak.com/{url_base}.png`).
|
||||
3. **Offline mode:** Should we ship a static badge list as fallback? (YAGNI for now)
|
||||
@@ -345,6 +345,7 @@
|
||||
- **Description:** Recent server management is partially implemented. Needs completion per spec.
|
||||
- **Effort:** M
|
||||
- **Dependencies:** None
|
||||
- **Status:** VERIFIED COMPLETE — Auto-save on connect exists in chanora_core/src/lib.rs:629-650. Bookmark list UI shows all bookmarks with connect/delete. _reloadBookmarks() called on disconnect. (2026-06-11)
|
||||
|
||||
### TODO-043 — Implement event replay tool (SysRS-171, SRS-098)
|
||||
- **Priority:** P2
|
||||
@@ -466,7 +467,7 @@
|
||||
- **Description:** No full TS5 client protocol exists yet. Watch `tsdeclarations` repo for updates that may affect Chanora compatibility.
|
||||
- **Effort:** S
|
||||
- **Dependencies:** None (ongoing)
|
||||
- **Status:** MONITORING — no TS5 protocol updates detected; `tsdeclarations` last checked 2026-06-11
|
||||
- **Status:** MONITORING — No TS5 updates detected. GitHub watch recommended. (2026-06-11)
|
||||
|
||||
### TODO-059 — Build auto-reconnect logic internally
|
||||
- **Priority:** P2
|
||||
@@ -518,7 +519,7 @@
|
||||
- Cross-verified against YaTQA §8.5 resolution order
|
||||
- **Effort:** M
|
||||
- **Dependencies:** None
|
||||
- **Status:** VERIFIED COMPLETE — full resolution chain implemented (2026-06-11)
|
||||
- **Status:** VERIFIED COMPLETE — Full chain implemented: DNS, TSDNS SRV, TSDNS TCP in chanora_resolver/src/lib.rs:178-387. First-wins semantics. (2026-06-11)
|
||||
|
||||
### TODO-063 — Verify tsclientlib encoding handling (UTF-8 vs UCS-2 vs CESU-8)
|
||||
- **Priority:** P1
|
||||
|
||||
Reference in New Issue
Block a user