TheDocumentation 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.
char[21] is a fixed 21-byte player name field used across multiple Shaiya Core V9 chat opcodes. Its physical encoding is five u32 little-endian values followed by one u8 — always exactly 21 bytes on the wire, with no length prefix and no null terminator sent. All offsets below are plaintext bytes after the u16 LE opcode (tap at SConnection_Send / post-decrypt recv). See WIRE_CAPTURE_GUIDE.md for breakpoint locations.
| Binary | MD5 | ImageBase |
|---|---|---|
Game.exe | c1edd96639ad81835624b9c4516ac781 | 0x00400000 |
ps_game.exe | 91b212afbe6623382713772489dc82ce | 0x00400000 |
Wire Layouts Involving char[21]
| Pattern | Direction / Opcodes | Layout (offsets after opcode) | Plaintext size |
|---|---|---|---|
| B | S→C 1103, 1104, 1108, 1111; admin F103, F104 | +0x02 char name[21] · +0x17 u8 len · +0x18 text[len] | len + 0x18 (24 B min) |
| C | S→C 1102; admin F102 | +0x02 u8 dir · +0x03 char name[21] · +0x18 u8 len · +0x19 text[len] | len + 0x19 (25 B min) |
| H | S→C F107, F109; C→S F107 | +0x02 char name[21] (name only, no text) | 0x17 (23 B, fixed) |
| I | C→S F108 (bound whisper relay) | +0x02 u8 len · +0x03 text[len] — no name field; partner from CUser+0x5810 | len + 3 |
| C→S whisper | C→S 1102 / F102 | +0x02 target[21] (5×u32 LE + u8) · +0x17 u8 len · +0x18 text[len] | len + 0x18 (24 B min) |
| Alliance | S→C 0x0812 | Pattern B + +0x18+len u32 guildId appended | len + 0x1C (28 B min) |
Client Recv Sites
Every recv handler below callsPacketRead_String @ 0x005F4780 with count = 0x15 (21) to consume the name field. The function performs a fixed memcpy of up to param_2 bytes — there is no null terminator on the wire; underflow zero-fills only the destination buffer.
CONFIRMED —
PacketRead_String @ 0x005F4780 always consumes exactly 21 bytes on recv (push 0x15 · call 0x005F4780). Evidence: game-chat-native/recv/PacketRead_String_005f4780.c + cross-checked against all handlers below.| Opcode | Handler VA | Evidence (.c file) |
|---|---|---|
0x1102 | 0x005E5180 | game-chat-native/handlers/Handler_ChatWhisper_005e5180.c |
0x1103 | 0x005E5250 | handlers/Handler_ChatTrade_005e5250.c |
0x1104 | 0x005E5310 | handlers/Handler_ChatGuild_005e5310.c |
0x1108 | 0x005E5540 | handlers/Handler_ChatMegaphone_005e5540.c |
0x1111 | 0x005E57D0 | handlers/Handler_Chat_Area_1111_005e57d0.c |
0xF102 | 0x005E5920 | handlers/Handler_Chat_Admin_F102_005e5920.c |
0xF103 | 0x005E59F0 | handlers/Handler_Chat_Admin_F103_005e59f0.c |
0xF104 | 0x005E5AB0 | handlers/Handler_Chat_Admin_F104_005e5ab0.c |
0xF107 | 0x005DE950 | handlers/Handler_Chat_Admin_F107_005de950.c |
0xF109 | 0x005DE9B0 | handlers/Handler_Chat_Admin_F109_005de9b0.c |
0xF107 / 0xF109 read char[21] then call vfn +0x344 / +0x348 @ 0x0056BCB0 — a ret 4 stub. No UI output.
Opcodes That Do NOT Use char[21]
| Opcode | Payload instead |
|---|---|
0x1101, 0x1105, 0x1107 | Pattern A — u32 id (entity / char id) |
0x1109 | Pattern D — u8 flag · u32 id · u8 len · text |
0x110A | Pattern E — u32 id · u16 message_id |
0x110B | Pattern G — u32 entity · char[32] label (32 B @ +0x06, read as 0x20) |
0xF105 | Pattern A — u32 id |
0xF106 / 0x1112 | Variable u16le len · text (different layout) |
Client Send Sites
Only one client send function writes achar[21] to the wire. All other send paths use the compact opcode + u8 len + text layout; the server injects the player name from CUser+0x184 during broadcast.
CONFIRMED —
PacketSend_Whisper @ 0x005ED160 is the sole client function that places 21 bytes of name on the wire. Asm evidence: copies param_2[0..4] (5×u32) + byte at param_2+5 → stack buffer; size arg to NetworkSend = msg_len + 0x18.| Path | VA | File | Name on wire? |
|---|---|---|---|
PacketSend_Whisper | 0x005ED160 | send/PacketSend_Whisper_005ed160.c | Yes — target[21] @ +0x02; size msg_len + 0x18 |
PacketSend_Chat | 0x005ED060 | send/PacketSend_Chat_005ed060.c | No — opcode + u8 len + text only |
PacketSend_Guild | 0x005ED220 | send/PacketSend_Guild_005ed220.c | No |
PacketSend_Party | 0x005ED2B0 | send/PacketSend_Party_005ed2b0.c | No |
PacketSend_Zone | 0x005ED340 | send/PacketSend_Zone_005ed340.c | No |
ChatWindow_SendMessage @ 0x0047A5F0 passes param_1_00+0x198 to PacketSend_Whisper (channel case 1). Target is set by ChatWindow_SetWhisperTarget @ 0x0047C690 — null-terminated copy into offset +0x198.
Server Send Sites
The server copies the player name with a null-terminateddo { *dst++ = *src++; } while (*src != '\0'); idiom — there is no memset of the tail region before SConnection_Send. The full 21-byte region (including bytes past the null) is included in the send size.
CONFIRMED — name source is
CUser+0x184; null-terminated do/while copy into stack char[21]. SConnection_Send size args use the full 21-byte region: len + 0x18 for guild @ 0x00432607, len + 0x19 for whisper @ 0x0047F676.| Opcode / pattern | Function VA | File | Name source | SConnection_Send size |
|---|---|---|---|---|
0x1103 Trade | 0x004192F0 → queue | Chat_BroadcastTrade_004192f0.c | via Chat_ProcessIncoming @ 0x0047F400 | len + 0x18 |
0x1104 Guild | 0x00432530 | Chat_BroadcastGuild_00432530.c | param_2 (CUser+0x184) → local_a2[21] | len + 0x18 @ 0x004ED0E0 |
0x0812 Alliance | 0x00432530 | Chat_BroadcastGuild_00432530.c | → acStack_13e[21] | len + 0x1C @ 0x004ED2D0 |
0x1108 Megaphone | 0x004D55B0 | Chat_BroadcastNamed_004d55b0.c | Chat_ProcessIncoming repack | len + 0x18 |
0x1111 Area | 0x00427090 | Chat_BroadcastZone_00427090.c | Chat_ProcessIncoming → local_aa[21] | zone fanout |
0x1102 Whisper S→C | 0x0047F400 | Chat_ProcessIncoming_0047f400.c | sender / target CUser+0x184 | len + 0x19 (×2 dual send) |
0xF104 Admin guild | 0x00432770 | AdminChat_BuildGuildPacket_00432770.c | same as guild | len + 0x18 |
| Admin mirror | 0x0047FD10 | AdminChat_ProcessIncoming_0047fd10.c | same patterns | same |
Server Whisper Forward Patch
CONFIRMED — Before building the S→C Pattern C packet, the server zeroes the last byte of the C→S
target[21] field: *(packet + 0x16) = 0 @ 0x0047F608 (movb $0x0, 0x16(%ebx)). This clears any trailing byte written by the client before World_FindUserByName @ 0x00414D40 uses the name. The text slice is then taken from packet + 0x18 (asm 0x0047F661).PacketRead_String @ 0x005F4780
Padding After '\0' on the Wire
This section records the static analysis verdict for the tail bytes of char[21] when the player name is shorter than 21 characters.
CONFIRMED — Send size includes all 21 name bytes (
len + 0x18 / len + 0x19 everywhere). SConnection_Send always receives the full 21-byte region.CONFIRMED — The server does not
memset the name tail before SConnection_Send. Scan of all five chat-tagged Pattern B direct sends (0x1104 / 0xF104): zero memset(21) / rep stos instructions in the 80-instruction window before call 0x004ED0E0. Sites: guild @ 0x00432615, admin @ 0x00432818, GM relay @ 0x004070BC / 0x0040714E; megaphone indirect @ 0x0047F5AE / 0x0047FEEE.CONFIRMED — MSVC stack prologue does not zero the
name[21] frame before the copy loop. All builders use sub esp, N + cookie xor esp, eax only — no rep stos / xorps frame clear. Examples: Chat_BroadcastGuild @ 0x00432530 (sub $0x14c), Chat_ProcessIncoming @ 0x0047F40E.CONFIRMED — Client recv pre-zeros the local name buffer before calling
PacketRead_String. Handler_ChatGuild @ 0x005E5310: xor eax, eax + five mov [esp+…], eax instructions at 0x005E5324–0x005E5342 before PacketRead_String(..., 0x15).ChatWhisperTradeGuildZoneMega_vfn @ 0x0059BDB0 compares param_4 with a byte loop that stops at '\0' — the null at name[strlen] effectively hides any non-zero tail bytes from the string comparison logic.
Emulator Guidance
Cross-Reference
| Document | Contents |
|---|---|
PACKET_SPEC.md | Full wire layouts, TCP envelope, all opcode patterns |
CHAT_CHANNEL_MAP.md | Handler VA, vtable offset, .c file per opcode |
PADDING_SIMULATION.md | Simulated byte distribution for name tail region |
WIRE_CAPTURE_GUIDE.md | Breakpoints and method for capturing reference packets |
game-chat-native/handlers/ | Client recv handler .c evidence |
psgame-chat-native/handlers/Chat_ProcessIncoming_0047f400.c | Server recv + whisper patch evidence |
psgame-chat-native/send/Chat_BroadcastGuild_00432530.c | Server send + copy idiom evidence |