The admin bound-whisper system is a three-opcode chain exclusive to GM/admin users in Shaiya Core V9. OpcodeDocumentation 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.
0xF107 binds an admin to a named player, storing the target’s id at CUser+0x5810. Opcode 0xF108 then relays text to that bound partner — the server resolves the target by id, not by name, and emits dual S→C 0xF102 (Pattern C) packets to both parties. Finally, 0xF109 clears the bind and notifies both sides. Stock Game.exe has no send site for 0xF108 and exposes no UI for the bind — the relay is intended for external GM tools only.
Prerequisites
A prior0xF107 bind is required before 0xF108 will relay anything.
| Condition | Checked at | Consequence on fail |
|---|---|---|
CUser+0x5810 != 0 | AdminChat_ProcessIncoming case 0xF108 @ 0x00480462 | S→C 0x1106, plain size 3, to admin |
World_FindUserById returns non-NULL | Same case, after id lookup | S→C 0x1106, plain size 3, to admin |
2 ≤ msg_len ≤ 0x80 | Length check in same case | len ≤ 1 → silent drop; len > 0x80 → kick FUN_004ec760(9,0) @ 0x004805AF |
F107 — Bind Flow
0xF107 associates the sending admin’s session with a target player by name and notifies both parties.
C→S Wire Layout — Pattern H
| Field | Size | Notes |
|---|---|---|
| Plaintext size | 0x17 (23) | push 0x17 before every SConnection_Send @ 0x004ED0E0 |
target_name | 21 | do/while copy until '\0'; no tail memset |
Client sends C→S 0xF107 + char[21] name
Server clears packet+0x16 before lookup
AdminChat_ProcessIncoming @ 0x0048038E writes 0x00 to packet+0x16 (last byte of the name region) before calling World_FindUserByName @ 0x00414D40. This guards against unterminated input from the wire.Server sets CUser+0x5810
admin+0x5810 = target+0x128 (the target’s character/session id). If a previous bind exists (+0x5810 != 0), Chat_AdminWhisperHelper @ 0x0047F350 is called first to clear the old bind.Server emits dual S→C 0xF107 — Pattern H
SConnection_Send calls @ 0x004803C7 go out:- Target receives admin’s name (Pattern H,
ecx = target CUser). - Admin receives target’s name (Pattern H,
ecx = admin CUser).
0x17.F108 — Bound Relay Flow
0xF108 carries the actual whisper text. The C→S packet carries no target name — the server resolves the destination from CUser+0x5810.
C→S Wire Layout — Pattern I
| Field | Size | Notes |
|---|---|---|
| Plaintext size | len + 3 | No target name field — partner id sourced from CUser+0x5810 |
msg_len | 1 | Minimum 2, maximum 128 (0x80) |
S→C Relay — 0xF102 Pattern C
The server never emits0xF108 to any client. Both relay sends use opcode 0xF102:
| Send | VA | Recipient | dir value |
|---|---|---|---|
| 1st | 0x004804FC | Bound user (World_FindUserById on admin+0x5810) | 0 |
| 2nd | 0x00480572 | Admin (this CUser) | 1 |
len + 0x19 (25). Evidence: add $0x19,%edi @ 0x004804EC / 0x00480564.
Admin tool sends C→S 0xF108 + u8 len + text
Game.exe has zero mov $0xF108 in .text (confirmed by objdump).Server validates bind and length
AdminChat_ProcessIncoming case @ 0x00480462 checks admin+0x5810 != 0 and 2 ≤ len ≤ 0x80. Any violation returns 0x1106 or kicks the connection.Server resolves bound partner by id
World_FindUserById @ 0x00414D10 is called with admin+0x5810. If the partner has gone offline since bind, the server returns 0x1106.Server builds S→C 0xF102 dir=0 to partner
CUser+0x184) is copied into the Pattern C packet and sent to the bound user. Plain size len + 0x19.Optional: monitor log via Chat_BuildOutgoing_F502
CUser+0x5820 (GM monitor session target id) is non-zero and the session is active, Chat_BuildOutgoing_F502 @ 0x0047F260 is called before the admin echo.PacketDispatcher @ 0x005F1E10 in Game.exe lists cases for 0xF107 and 0xF109 but has no case for 0xF108. Zero instances of mov $0xF108 appear in either bin/Game.exe or bin/ps_game.exe under objdump grep.Full Call Path
F109 — Clear Flow
0xF109 is an opcode-only command: it carries no body beyond the 2-byte opcode. It clears CUser+0x5810 and notifies both bound parties.
C→S Wire Layout
Server calls Chat_AdminWhisperHelper @ 0x0047F350
admin+0x5810 to 0, then calls World_FindUserById @ 0x00415480 to resolve the previously-bound partner.Full Direction Table
| Direction | Opcode | Plain size | Notes |
|---|---|---|---|
| C→S | 0xF107 | 0x17 (23) | Pattern H — bind by name |
| S→C | 0xF107 | 0x17 (23) | Pattern H — dual notify (target + admin) |
| C→S | 0xF108 | len + 3 | Pattern I — text only; no target name on wire |
| S→C | 0xF102 | len + 0x19 | Pattern C — relay to partner (dir=0) and admin echo (dir=1) |
| C→S | 0xF109 | 2 | Opcode only — no body |
| S→C | 0xF109 | 0x17 (23) | Pattern H — dual notify (bound + admin) |
F108 vs F102 vs 0x1102 Comparison
| Aspect | 0x1102 | 0xF102 | 0xF108 |
|---|---|---|---|
| Handler | Chat_ProcessIncoming | AdminChat_ProcessIncoming | AdminChat_ProcessIncoming |
| C→S target field | target[21] on wire | target[21] on wire | None — uses +0x5810 bind |
| Server lookup | World_FindUserByName | World_FindUserByName | World_FindUserById |
| Requires F107 bind | No | No | Yes |
| S→C opcode | 0x1102 | 0xF102 | 0xF102 (relay) |
| Client recv handler | Handler_ChatWhisper | Handler_Chat_Admin_F102 @ 0x005E5920 | (none — server never sends F108) |
| Client send site (stock) | PacketSend_Whisper | Admin chat send path | Absent |
CUser State Fields
| Offset | Type | Description |
|---|---|---|
+0x5810 | u32 | Bound whisper-partner id — set to target+0x128 on F107; cleared to 0 on F109 or pre-clear |
+0x128 | u32 | Character/session id used for bind storage and World_FindUserById lookups |
+0x184 | char[] | Display name — source for the name[21] field in all outbound Pattern C relays |
+0x5820 | u32 | GM monitor session target id — when non-zero enables Chat_BuildOutgoing_F502 log |
Error Paths
| Condition | Server action | Evidence |
|---|---|---|
admin+0x5810 == 0 (no bind) | S→C 0x1106, plain size 3, to admin | asm 0x00480587 |
World_FindUserById returns NULL | S→C 0x1106, plain size 3, to admin | asm 0x00480491 → 0x00480587 |
len > 0x80 | Kick FUN_004ec760(9,0) @ 0x004805AF | Shared admin validation |
len ≤ 1 | Silent return (no send) | asm 0x0048047F → 0x004805B9 |