Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ThalissonTMora/shaiya-chat-native-re/llms.txt

Use this file to discover all available pages before exploring further.

This document specifies every wire packet layout used by Shaiya Core V9’s native chat system. Layouts are inferred from decompiled handlers in game-chat-native/ and psgame-chat-native/; do not edit manually — regenerate .c files via tools/ghidra/. All offsets are after the u16 LE opcode unless noted. (?) marks partial inference. LE = little-endian.
BinaryMD5ImageBase
Game.exec1edd96639ad81835624b9c4516ac7810x00400000
ps_game.exe91b212afbe6623382713772489dc82ce0x00400000

TCP Envelope (Wire)

Every packet is framed in a two-byte length prefix followed by ciphertext. The plaintext payload begins with the u16 opcode that the PacketDispatcher routes.
┌──────────────┬─────────────────────────────┐
│ wire_len u16 │  ciphertext (wire_len − 2)   │
│  (= plain+2) │  encrypted opcode + body     │
└──────────────┴─────────────────────────────┘
         │ decrypt (client: PacketPayload_Decrypt @ 0x401080)

┌──────────┬──────────────────┐
│ opcode   │  body (handler)  │
│ u16 LE   │                  │
└──────────┴──────────────────┘
FieldSizeNotes
wire_len2 Bplaintext_size + 2
ciphertextwire_len − 2 BAES-128 CTR-like — see WIRE_CRYPTO.md
opcode2 BFirst plaintext field; routed by PacketDispatcher @ 0x5F1E10
Readers (client): PacketRead_Scalar @ 0x005F4700 = memcpy N bytes; PacketRead_String @ 0x005F4780 = up to N bytes (no null terminator on wire). Limits: reader max 0x2000; server send must be < 0x801.

Client → Server (Send)

Common Layout — Short Chat

Most chat channels share a compact three-field structure. NetworkSend takes msg_len + 3 as the total plaintext size. Maximum wire text is 255 bytes (single u8).
/* Common short-chat client send */
+0x00  u16  opcode
+0x02  u8   msg_len
+0x03  u8   msg[msg_len]
OpcodeSender functionChannel
0x1101PacketSend_Chat(0, 0, …)Normal
0x1103PacketSend_Chat(0, 1, …) or PacketSend_Party(0, …)Trade / Party send
0x1104PacketSend_Chat(0, 2, …) or PacketSend_Guild(0, …)Guild
0x1105PacketSend_Chat(0, 3, …)Party
0x1107PacketSend_Chat(0, 4, …)Shout
0x1111PacketSend_ZoneZone / Area
0xF1010xF105PacketSend_Chat(1, …) / Guild / Party with param_1 != 0Admin (opcode + 0xE000)

Whisper Send

CONFIRMEDPacketSend_Whisper @ 0x005ED160. The whisper packet carries a fixed 21-byte target name field before the message length byte.
/* Client → Server whisper (0x1102 normal / 0xF102 admin) */
+0x00  u16  opcode          // 0x1102 or 0xF102
+0x02  u8   target[21]      // 5×u32 LE + u8 (21 B fixed; NOT length-prefixed)
+0x17  u8   msg_len
+0x18  u8   msg[msg_len]
// Plaintext size: msg_len + 0x18 (24 B minimum)

Admin Opcodes 0xF107 / 0xF109 / 0xF108

0xF107 and 0xF109 have no send site in stock Game.exe (objdump finds zero mov $0xF107 / $0xF109 instructions). C→S packets are handled server-side only in AdminChat_ProcessIncoming @ 0x0047FD10. 0xF108 is likewise absent from the client — the server routes bound whisper relay through 0xF102 downstream.

Server → Client (Recv) — 0x11010x110B

Wire Pattern Summary

Each opcode maps to one of seven structural patterns. The pattern letter identifies the field layout immediately following the u16 opcode in plaintext.
PatternOpcodesLayout after opcode
A1101, 1105, 1107, F101u32 id · u8 len · bytes[len]
B1103, 1104, 1108, 1111char[21] name · u8 len · bytes[len]
C1102u8 dir · char[21] name · u8 len · bytes[len]
D1109u8 flag · u32 id · u8 len · bytes[len]
E110Au32 id · u16 message_id (no text on wire)
F1106u8 code (fixed SysMsg — ignored in vtable)
G110Bu32 entity · char[32] label (fixed 32 B)

Per-Channel Table

OpcodeChannelPayload patternUI / effectBalloon @ 4126D0
0x1101NormalADrawText style 0x22Yes (conditional)
0x1102WhisperCSysMsg + highlightNo
0x1103TradeBSysMsgNo
0x1104GuildBSysMsgNo
0x1105PartyASysMsg partyNo
0x1106ErrorFFixed SysMsg 0x14BNo
0x1107ShoutADrawText style 0x27Yes (conditional)
0x1108MegaphoneBSysMsg banner 0x1E1No
0x1109ZoneDDrawTextNo
0x110AUnionEDrawText + GetMsgNo
0x110BChannel linkGNameplate (56C650)No

Pattern Layouts

/* Pattern A: opcodes 1101, 1105, 1107, F101 */
+0x00  u16  opcode
+0x02  u32  id          // entity / char id
+0x06  u8   len
+0x07  u8   text[len]
// Plaintext size: len + 7

0x0502 — Entity Spawn / State Body

Handler: Handler_Packet_0502 @ 0x005E0CF0 → vtable +0xF0ChatEntitySpawn_vfn @ 0x00593970. This is not a chat box opcode.
/* 0x0502 entity spawn body (15 bytes after opcode) */
+0x00  u8   kind        // entity type / spawn mode
+0x01  u32  field_a
+0x05  u32  field_b
+0x09  u16  field_c
+0x0B  u16  field_d
+0x0D  u16  field_e
Effect: resolves entity via world manager (0x7C4A68); may attach FX (0x459D30), update entity+0x1EC..0x1F4, call EntityStateRefresh @ 0x004153C0. No chat box output. Evidence: game-chat-native/vtable/ChatEntitySpawn_vfn_0xF0_00593970.c

0x00A101 — Key Material (Crypto Handshake)

Handler: Handler_Packet_A101_KeyMaterial @ 0x005E3D60 → vfn +0x254Connection_OnKeyMaterial @ 0x005A4D50Crypto_ProcessKeyPacket @ 0x401100. Routed by PacketDispatcher @ 0x5F1E10.
/* 0xA101 key material body (195 bytes after opcode) */
+0x00  u8        field_0    // ctx selector: 0 → recv CounterLoad @ 0x23037F0+0xF4
+0x01  u8        field_1    // block_b slice length → ack vector only
+0x02  u8        field_2    // block_a slice len → ack vector;
                             // HMAC inner update length on block_b
+0x03  u8[64]   block_a
+0x43  u8[128]  block_b    // total body = 195 B after opcode
Counter derivation (recv, field_0 == 0): HMAC-SHA256(SHA256(PRNG[128]), block_b[0..field_2])[0..15]Crypto_CounterLoad dword permute → ctx+0xF4. Digest [16..31] feeds key-seed globals. Full chain: CRYPTO_COUNTER.md.
The client also sends a follow-up 0x00A101 (131 B) via NetworkSendKeyFollowUp @ 0x5EC5A0; login ack 0x00A102 — see WIRE_CRYPTO.md.

Admin Channel Details

Admin Whisper Bind — 0xF107 / 0xF109

CONFIRMED May 2026. Full call chain: psgame-chat-native/send/Chat_AdminWhisper_F107_F109_chain.md.
DirectionOpcodePlaintext sizeServer / client evidence
C→S bind0xF1070x17AdminChat_ProcessIncoming @ 0x0048038E; clears packet+0x16 before World_FindUserByName @ 0x00414D40
C→S clear0xF1092 (opcode only)case @ L317 — calls Chat_AdminWhisperHelper @ 0x0047F350; no body read
S→C bind notify0xF1070x17mov $0xF107 @ 0x004803C7 — dual SConnection_Send: target gets admin name, admin gets target name
S→C clear notify0xF1090x17mov $0xF109 @ 0x0047F390 — dual send from Chat_AdminWhisperHelper
Server state: CUser+0x5810 = bound target id (CUser+0x128 of whisper partner). Cleared to 0 on F109 or before rebind. Client UI: recv handlers @ 0x005DE950 / 0x005DE9B0 read char[21] then call vfn +0x344 / +0x348 @ 0x0056BCB0 — a ret 4 stub. ChatWindow_SetWhisperTarget @ 0x0047C690 (vtable +0x198) is not invoked — stock client does not apply the server bind to the whisper UI.

Admin Bound Whisper Relay — 0xF108

CONFIRMED May 2026. Handler: AdminChat_ProcessIncoming case @ asm 0x00480462. Stock Game.exe has no send or recv site for 0xF108.
DirectionOpcodePlaintext sizeNotes
C→S relay0xF108len + 3Requires CUser+0x5810 != 0 (F107 bind); World_FindUserById @ 0x00414D10
S→C to partner0xF102len + 0x19Pattern C dir=0 · admin name @ +0x184
S→C echo admin0xF102len + 0x19Pattern C dir=1 · partner name
Error (no bind / offline)0x11063Same as F102 / F107 miss
The server never emits a downstream 0xF108 packet — bound whisper relay always surfaces to the client as 0xF102 Pattern C.

Server — Recv / Send

Common Validation

Rules applied by Chat_ProcessIncoming @ 0x0047F400 and AdminChat_ProcessIncoming @ 0x0047FD10:
  • Text length: 2 ≤ len ≤ 128len >= 0x81 → kick connection.
  • Global cooldown: CUser+0x581c.
  • Shout cooldown: CUser+0x58e4 = now + 30 s.
  • Megaphone cooldown: CUser+0x58e0 = now + 30 s.
  • Megaphone flag: CUser+0x58dc — next Normal send becomes 0x1108.

Server Flow by Opcode

In (client)Broadcast outServer function
0x1101 Normal0x1101 {opcode, charId, len, msg}Chat_BroadcastNormal (cells mode 7)
0x1101 + megaphone flag0x1108 {opcode, name[21], len, msg}Chat_BroadcastNamed (global)
0x1102 Whisper0x1102 ×2 (target + echo)SConnection_Send direct
0x1103 Trade0x1103 name + textChat_BroadcastTrade
0x1104 Guild0x1104 + 0x0812 allianceChat_BroadcastGuild
0x1105 Party0x1105 charId + textCParty_BroadcastPacket
0x1107 Shout0x1107 charId + textChat_BroadcastShout (mode 5)
0x1108 Megaphone0x1108 name + textChat_BroadcastNamed
0x1111 Area0x1111 name + textChat_BroadcastZone
0x1112 Raid leader0x1112 charId + textCParty_BroadcastPacket
0xF1010xF10Amirrored admin opcodesAdminChat_ProcessIncoming
0xF107 bindS→C ×2 (0xF107 + char[21])AdminChat_ProcessIncoming @ 0x004803C7 · sets CUser+0x5810
0xF108 bound whisperS→C ×2 (0xF102 Pattern C)AdminChat_ProcessIncoming @ 0x00480462 · requires CUser+0x5810
0xF109 clearS→C ×2 (0xF109 + char[21])Chat_AdminWhisperHelper @ 0x0047F350 · clears CUser+0x5810
Client inbound opcodes 0x1109, 0x110A, and 0x110B are server push only. If the client sends any of these, Chat_ProcessIncoming hits the default branch → SConnection_Close(9, 0) @ 0x0047FC24 (kick).

Server Push — 0x1109 / 0x110A / 0x110B

Evidence: psgame-chat-native/send/Chat_PacketBuilder_*.c; client recv handlers cross-checked.
OpcodePatternPlaintext sizeBuilder VASend path
0x1109Dlen + 80x004C6A80 (flag=0) · 0x004C6F50 (flag=1)SConnection_Send @ 0x004ED0E0 or CParty_BroadcastPacket @ 0x0044E950
0x110AE8 (fixed)0x004C8310 (mov 0x110A @ 0x4C8328)Spatial cell iteration → SConnection_Send(..., 8)
0x110BG0x26 (38, fixed)0x004C8520 (landmark 0x004C8539, mov 0x110B @ 0x4C8542)Spatial cell iteration → SConnection_Send(..., 0x26)
0x1109 builders detail:
  • 1109_A (0x004C6A80): flag=0; if sender in party → CParty_BroadcastPacket; else direct SConnection_Send. Caller @ 0x004A22C6.
  • 1109_B (0x004C6F50): flag=1; iterates zone cells (Zone_FloorWorldToCellIndex @ 0x005250C0, stride 0x124) for users within Math_DistanceRadiusCompare @ 0x0041B8A0. Caller @ 0x004A2640.
Text source (CONFIRMED): builder calls ZoneChat_MessageResolver @ 0x004C6970; copies NUL-terminated bytes from return+4. Map populated at startup from data/cn_string.DB (FUN_00408C70 @ 0x00408C70). 0x110A message_id encoding (CONFIRMED): Chat_ScriptWrapper_110A @ 0x004CB3D0 loads a script integer, applies or eax, 0xC00 @ 0x004CB402 before calling Chat_PacketBuilder_110A @ 0x004CB41F. No text is sent on the wire — only the id. Client resolves via GetMsg @ 0x00420DB0 against the same cn_string.DB map.

Megaphone Item → Chat Flow

  1. ItemUseNSend (0x4728E0) — validates item range 0x40–0x67 or 0xACA1–0xACA7.
  2. Emits 0x702, 0x50A, 0x40E (inventory / slot).
  3. Sets flag CUser+0x58dc in ItemUse_UIInventoryHandler @ 0x004736C3 (before ItemUseNSend).
  4. Client sends text as 0x1101 Normal → server repackages as 0x1108 Megaphone.

Outbound Broadcast Layouts

/* Normal / Party / Shout — opcodes 1101, 1105, 1107 */
u16 opcode · u32 charId · u8 len · bytes[len]       // size = len + 7
/* Name + text — Megaphone, Guild, Trade, Area — opcodes 1108, 1104, 1103, 1111 */
u16 opcode · u8 name[21] · u8 len · bytes[len]      // size = len + 0x18
/* Guild alliance broadcast — opcode 0x0812 */
u16 0x812 · u8 name[21] · u8 len · bytes[len] · u32 guildId   // size = len + 0x1C

Reimplementation Confidence

GoalConfidenceCoverage
Hook send / recv with correct opcodes and layouts~95%Send / recv packet bodies, opcode routing
Server chat compatible with stock client~85%Length validation, broadcasts, megaphone flow
End-to-end wire cryptography~85%Envelope + 0xA101 / 0xA102; see WIRE_CRYPTO.md
Standalone cipher without capture~90%Inbound layout + counter derivation closed statically
Pixel-perfect UI clone~65%Out of scope — vtables / UI

Known Uncertainties

TopicStatus
Server outbound opcode for client 0xA101Not mapped
Initial counter bytes (client)CONFIRMEDHMAC(...)[0..15] @ stack+0x38 → permute → 0x23038E4; see CRYPTO_COUNTER.md
0xA101 HMAC inner length on block_bCONFIRMEDfield_2 @ 0x404569 (independent of ack field_1)
0xA101 HMAC pre-keyCONFIRMEDSHA256(PRNG[128]) @ 0x404434, not SHA256(block_b)
char[21] fixed name fieldsCONFIRMED — see CHAR21_SITES.md

Cross-Reference

DocumentContents
WIRE_CRYPTO.mdAES-CTR cipher, envelope, handshake, megaphone flag
CHAT_CHANNEL_MAP.mdHandler VA, vtable, .c file per opcode
CHAR21_SITES.mdAll sites reading / writing the fixed 21-byte name field
CHAT_RE_GAPS.mdLacunas P0/P1/P2, balloon gates, admin recv
game-chat-native/handlers/Client recv evidence
psgame-chat-native/handlers/Chat_ProcessIncoming_0047f400.cServer evidence
tools/ghidra/*.manifestFull VA list

Build docs developers (and LLMs) love