feat(chat): route retail lifestone commands
Separate retail client actions, ACE server commands, and ordinary chat at the shared router. Port lifestone/lif/ls from the named retail registry through a typed App controller to game action 0x0063, keep unknown verbs on ACE Talk, and cover both UI backends plus exact outbound bytes. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
5090aa7217
commit
5a45a7ac7f
19 changed files with 604 additions and 78 deletions
|
|
@ -0,0 +1,110 @@
|
|||
# Retail client-command routing and lifestone recall
|
||||
|
||||
Date: 2026-07-13
|
||||
|
||||
## Scope
|
||||
|
||||
This note records the retail path used for chat-bar commands and the first
|
||||
ported client command, `@lifestone` (`@lif`, `@ls`). It deliberately separates
|
||||
commands the retail client executes from ACE administrator commands that the
|
||||
server consumes as Talk text.
|
||||
|
||||
## Named-retail sources
|
||||
|
||||
- `ChatInterface::ProcessCommand @ 0x004F5100`
|
||||
- `ClientCommunicationSystem::OnChatCommand @ 0x00581320`
|
||||
- `ClientCommunicationSystem::DoLifestone @ 0x0056FC70`
|
||||
- `ClientCommunicationSystem::HelpLifestone @ 0x00578500`
|
||||
- `CM_Character::Event_TeleToLifestone @ 0x006A1B90`
|
||||
- Command-table construction at `0x005838F7` through `0x00583A2B`
|
||||
- Alias data at `0x007E17E4` (`ls`), `0x007E17E8` (`lif`), and
|
||||
`0x007E17EC` (`lifestone`)
|
||||
|
||||
Source file:
|
||||
`docs/research/named-retail/acclient_2013_pseudo_c.txt`.
|
||||
|
||||
## Cross-references
|
||||
|
||||
- ACE consumes server/admin commands such as `@ci` from the Talk game action.
|
||||
That is a different path from retail client commands.
|
||||
- acdream already has the exact lifestone action builder in
|
||||
`AcDream.Core.Net.Messages.InteractRequests.BuildTeleToLifestone`.
|
||||
- holtburger's chat parser is useful for chat aliases, but the named retail
|
||||
command registry is authoritative for client-command ownership and aliases.
|
||||
|
||||
## Retail pseudocode
|
||||
|
||||
### Chat submission
|
||||
|
||||
```text
|
||||
ChatInterface.ProcessCommand():
|
||||
text = read chat input
|
||||
communicationSystem.OnChatCommand(text, currentCommandSource)
|
||||
append text to input history
|
||||
```
|
||||
|
||||
```text
|
||||
ClientCommunicationSystem.OnChatCommand(text, source):
|
||||
allow plugin to inspect/replace the input
|
||||
remember the current source and trimmed command line
|
||||
|
||||
if first character is '/':
|
||||
replace it with '@'
|
||||
return DoCommand()
|
||||
|
||||
if first character is '@':
|
||||
return DoCommand()
|
||||
|
||||
if first character denotes an emote shortcut:
|
||||
rewrite to '@emote ...'
|
||||
return DoCommand()
|
||||
|
||||
otherwise:
|
||||
route as ordinary speech according to the current talk focus
|
||||
```
|
||||
|
||||
### Lifestone command registration
|
||||
|
||||
```text
|
||||
register "lifestone" -> DoLifestone, HelpLifestone
|
||||
register "lif" -> DoLifestone, HelpLifestone
|
||||
register "ls" -> DoLifestone, HelpLifestone
|
||||
```
|
||||
|
||||
The registry uses case-insensitive command keys.
|
||||
|
||||
### Lifestone command execution
|
||||
|
||||
```text
|
||||
ClientCommunicationSystem.DoLifestone(argumentCount, arguments):
|
||||
if argumentCount == 0:
|
||||
CM_Character.Event_TeleToLifestone()
|
||||
else:
|
||||
add the command's usage/error text to the chat scroll
|
||||
return handled
|
||||
```
|
||||
|
||||
```text
|
||||
CM_Character.Event_TeleToLifestone():
|
||||
sequence = Proto_UI.GetNextUICounter()
|
||||
packet = OrderHdr(gameActionEnvelope, sequence, payloadLength = 12)
|
||||
packet.action = 0x0063
|
||||
sent = Proto_UI.SendToWeenie(packet)
|
||||
if not sent:
|
||||
Proto_UI.UICounterFailedSend(sequence)
|
||||
return sent
|
||||
```
|
||||
|
||||
## Port contract
|
||||
|
||||
1. Both `/` and `@` prefixes are accepted for retail client commands.
|
||||
2. `lifestone`, `lif`, and `ls` match case-insensitively.
|
||||
3. The command accepts no arguments. Invalid arguments display usage locally
|
||||
and send neither chat nor a game action.
|
||||
4. A valid command publishes a typed client action. The App layer executes it
|
||||
through `WorldSession`; UI code never touches the network session.
|
||||
5. Unknown command verbs remain server commands: `/foo` is canonicalized to
|
||||
`@foo` and sent through Talk so ACE remains authoritative for its command
|
||||
set.
|
||||
6. The wire body is the existing 12-byte game-action envelope with opcode
|
||||
`0x0063`; no command text is sent for lifestone recall.
|
||||
Loading…
Add table
Add a link
Reference in a new issue