Files
chanora/docs/references/protocol-implementation-traps.md
T
Edison Jwa 475f6e0603 docs: verify DNS/reconnect, revise encoding scope, document protocol traps (TODO-059,062,063,070)
Mark TODO-059 (auto-reconnect) and TODO-062 (DNS chain) as verified
complete with evidence. Revise TODO-063 from implementation to
verification task (tsclientlib handles encoding). Create protocol
implementation traps doc with 13 traps from YaTQA/ReSpeak/TeaSpeak.
2026-06-11 14:42:32 +09:00

5.9 KiB

Protocol Implementation Traps — Developer Notes

Date: 2026-06-11 Purpose: Compile protocol quirks and gotchas from YaTQA, ReSpeak, and TeaSpeak references that could cause bugs if not handled.


1. Icon ID Signedness (HIGH)

What: Icon IDs are i32 (signed), not u32. Read contexts return signed values; write contexts may expect unsigned.

Why it's a trap: Negative icon IDs from permlist/clientinfo will be misinterpreted as large positive numbers if stored as u32.

How to handle: Use i32 for all icon ID fields. When displaying, convert to absolute value or handle negative as "no icon".

Source: YaTQA §1.4

2. Avatar Flag = MD5 Hash (HIGH)

What: client_flag_avatar is an MD5 hash string, not a boolean.

Why it's a trap: Treating it as a boolean (present/absent) loses the identity reference. Avatar filename is derived from Global ID, not from the flag.

How to handle: Store avatar flag as a string. Use Global ID → Base64 → [a-p] encoding for filename (YaTQA §1.5).

Source: YaTQA §1.5

3. Channel Subscription = ONE at a Time (MEDIUM)

What: channelsubscribe command subscribes to exactly ONE channel. No array parameter exists.

Why it's a trap: Attempting to subscribe to multiple channels in one command will fail silently or error.

How to handle: Send individual subscribe commands per channel. Track subscription state client-side.

Source: YaTQA §3.1

4. Line Terminator = 0x0A 0x0D (MEDIUM)

What: TS3 protocol line terminator is 0x0A 0x0D (reversed Windows \n\r).

Why it's a trap: Standard \r\n (0x0D 0x0A) will cause parse failures. Max line length: 9203 bytes (excluding terminator).

How to handle: Use \n\r (0x0A 0x0D) for all command protocol messages. tsclientlib handles this internally.

Source: YaTQA §1.3

5. UCS-2 vs UTF-8 Encoding (HIGH)

What: TS3 claims UTF-8 but actually uses UCS-2 (BMP only). Mobile apps use CESU-8. Server 3.2.0+ adds partial SIP support (emoji ranges).

Why it's a trap: Characters outside BMP (emoji, rare CJK) may not round-trip correctly. tsclientlib uses str::from_utf8() — if server sends UCS-2, it will error.

How to handle: tsclientlib/tsproto handles encoding at the protocol layer. If encoding bugs are found, fix in the EdisonJwa/tsclientlib fork. Document any encoding-related issues here.

Source: YaTQA §1.3, ReSpeak §1.8.3

6. IPv6 Canonicalization Bug (LOW)

What: TS3 server 3.1.6-3.1.7 has IPv6 canonicalization bug in Blacklist2 protocol.

Why it's a trap: Connecting to older servers via IPv6 may trigger false blacklist matches.

How to handle: Be aware when connecting to older servers. Not actionable from client side.

Source: YaTQA §8.7

7. Channel Icon Semi-Permanent (MEDIUM)

What: channel_icon_id changes via channeledit are semi-permanent (lost on server restart).

Why it's a trap: Icon changes appear to succeed but revert after restart. Users may think their changes are persistent.

How to handle: Document this limitation in UI. Don't rely on channel icon persistence for critical features.

Source: YaTQA §4.2

8. Avatar Filename from Global ID (MEDIUM)

What: Avatar filename is derived from Global ID (not from avatar flag). Algorithm: Base64-decode Global ID → 20 bytes → display with [a-p] instead of [0-9a-f].

Why it's a trap: Using the avatar flag directly as a filename will fail to find the cached avatar.

How to handle: Implement the Global ID → filename conversion. Store avatars in cache/clients/ directory.

Source: YaTQA §1.5, §1.7

9. Snapshot SHA1 Hash Format (LOW)

What: Snapshot file starts with SHA1 hash of remaining UTF-8 data (excluding trailing newline). Internally runs Query commands when deploying.

Why it's a trap: Modifying snapshot data without recalculating the hash will cause deploy failure.

How to handle: If implementing snapshot import/export, always recalculate SHA1 after modification.

Source: YaTQA §1.6

10. BBCode Stack Limits (LOW)

What: BBCode max stack size 20, 10 tags can be active simultaneously. Self-closing [hr] doesn't count toward stack but can't be used at 20.

Why it's a trap: Complex channel descriptions with nested BBCode may be silently truncated or rejected.

How to handle: Validate BBCode depth before sending. Truncate if exceeding limits.

Source: YaTQA §1.8

11. Anti-Flood Server-Configurable (HIGH)

What: Anti-flood thresholds are server-configurable, not fixed. Key variables:

  • AntifloodPointsTickReduce — points deducted per 0.5-second tick (TeaSpeak default: 25)
  • AntifloodPointsToCommandBlock — threshold to block commands (TeaSpeak default: 150)
  • AntifloodPointsToIpBlock — threshold to block IP (TeaSpeak default: 300)

Why it's a trap: Hardcoding flood thresholds will cause either over-aggressive throttling or server bans.

How to handle: Read flood config from serverinfo response. Use conservative defaults. Implement client-side flood tracking (TODO-064).

Source: YaTQA §5.1, ReSpeak §vars, TeaSpeak §vars

12. TeaSpeak Query Newline Divergence (INFO)

What: TeaSpeak changed ServerQuery line terminator from \n\r to \n in 1.4.14-beta6. TS3 uses 0x0A 0x0D.

Why it matters: If Chanora ever adds ServerQuery support, must detect server type.

How to handle: Not relevant for voice client path (Chanora uses voice protocol, not query). Note for future reference.

Source: TeaSpeak §divergence-2

13. TeaSpeak Strict UTF-8 Mode (MEDIUM)

What: TeaSpeak has strict_utf8_mode config option that may reject non-UTF-8 strings.

Why it's a trap: Strings that pass through TS3 servers may be rejected by TeaSpeak servers.

How to handle: Ensure all outbound strings are valid UTF-8. Rust's String type guarantees this, but verify at protocol boundaries.

Source: TeaSpeak §config