server-re/docs/SHARED_FRAMEWORK.md

139 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Shared server framework ("Magi") — configuration and database access
The server EXEs share one in-house framework. Its classes are named `Magi*`,
and the network sessions are `MG*Session`. This document defines the parts
every binary shares:
- server identity;
- startup modes;
- configuration files;
- the path to the database.
Analyse each new binary against this document, and record in its own
`evidence.md` where it differs, rather than re-deriving the framework.
Status: first pass. **Primary evidence:** `MessageServer_Release_x64.exe`
(`decomp/MessageServer_Release_x64/`). **Cross-binary checks:** strings and RTTI
only, unless a row says otherwise. Field offsets are from MessageServer. Other
binaries share the same code, so they are *expected* to match, but this hasn't
been verified. Every claim is static; nothing here was observed at runtime.
Notation: **O** = observed in decompiled code, **S** = observed in
strings/RTTI only, **I** = inference, **?** = unknown. `MS:0x…` means a
function in `decomp/MessageServer_Release_x64/full/functions/0x….c`.
---
## 1. Framework presence across binaries (S)
| Marker | Present in |
|---|---|
| RTTI `MagiServerOption`, `MagiCustomOption`, `MagiServerFile`, `MagiServerManager` | all 14 server EXEs. The two SMMonitoring EXEs only have `MagiServerManager`. |
| Option-loader keys (`write_thread_count`, `each_option`), the `-AGNET MODE-` banner [sic], and the `DBC_CHAT`/`DBC_EMERGENCY` names | all 14 server EXEs; none in SMMonitoring |
| `Servers2DbcProxy` RTTI (client of the DBC servers) | Auction, Dungeon, GameGateway, Game, GM, Guild, Manager, Message, PVP |
| ADO / `_Connection` strings (direct SQL access) | DBCServer and DBCServer_LOG (4 hits each); 1–2 hits in Auction, Dungeon, Game, Guild, Manager and PVP (**?** — may be incidental) |
**Inference:** only the DBC servers talk to SQL Server. Every other server
reaches the database through ProudNet RMI to a DBC server (§5). This needs
confirming by decompiling the ADO usage in the six non-DBC servers that have
hits.
## 2. Server-kind enum (O, `MS:0x140002930`)
The one-byte server type is stored in the option object (`+0x1e8`) and in
peer/session records. Names below are the wide strings the binary prints.
| Value | Name | Value | Name |
|---|---|---|---|
| 1 | Lobby (= GameServer EXE, D: `ServerFile`) | 0x0c | DBC_GAME |
| 2 | Dungeon | 0x0d | Agent |
| 3 | PVP | 0x11 | DBC_LOG |
| 4 | WAR | 0x12 | DBC_CHAT |
| 5 | Guild | 0x13 | DBC_EMERGENCY |
| 6 | Message | 0x15 | Agentmanager |
| 7 | GM | 0x16 | MiniGame |
| 8 | Gate | 0x17 | `api` peer (no display name; `MS:0x14005dc20`) |
| 9 | Manager | 0x0e–0x10, 0x14 | ? |
| 0x0a | Auction | | |
| 0x0b | Match | 0x18 (24) | PatchServer (D: `ServerFile` only; not shipped) |
The same numbers are stored in `RustyHearts_Auth.ServerOption.Type`, and
`ServerFile` maps each one to an EXE (D; see `CONFIG.md` §5).
Separately, servers also have a numeric **code** (the instance ID). It appears
in XML as `code="61"` and in file names such as `MSG_61.xml`. In the shipped
deployment config every kind has one code: DBC_GAME=1, DBC_LOG=2, DBC_CHAT=3,
DBC_EMERGENCY=4, Msg=61, GM=71, Gate=81, Manager=91, Auction=101, Match=111,
Agent=800, AgentManager=900, Dungeon=2001, PvP=3003, Guild=5001, Lobby=21001
(S, `binaries/Option/*.xml`).
## 3. Startup modes (O, `MS:0x14005c7b0`)
`MagiServerOption::Init(argv1)` records the PID and the start time
(`+0x1ec`, `+0x1f0`), then branches on the first character of the argument:
| `argv[1]` | Mode | What is loaded |
|---|---|---|
| does not start with a digit | **standalone** | `argv[1]` is a path to a per-server XML file, which `MS:0x14005dc20` parses (§4.1) |
| starts with a digit | **agent mode** (prints `-AGNET MODE-`) | `atoi(argv1)` is this server's **code**. `MS:0x14005ceb0` reads `option\total_option.xml` (§4.3). The full server list then arrives from the Agent over RMI: the `MGSAgentSession` vftable slot 7 is `MS:0x140065ab0`. The entry whose code equals our code configures this server (`MS:0x14005c9f0`); every other entry is added as a peer (`MS:0x14005ff50`). |
This matches the Agent side: the Agent launches a server with the numeric
server code as its argument (`decomp/Agent_Release_x64/evidence.md` finding 3).
**ServerInfo record** pushed by the Agent (O, copy constructor `MS:0x140065900`; offsets in bytes):
| Off | Type | Field (I) |
|---|---|---|
| +0x00 | int | world |
| +0x04 | int | code |
| +0x08 | int | ? |
| +0x0c | u8 | server kind (§2) |
| +0x10 | int | private_port |
| +0x14 | int | public_port |
| +0x18 | int | public_udpport |
| +0x1c | int | udp_count |
| +0x20 | u8 | ? |
| +0x28 | `std::wstring` | private_ip |
| +0x50 | `std::wstring` | public_ip |
| +0x78 | `std::wstring` | name |
## 4. Configuration files
Moved to [`CONFIG.md`](CONFIG.md). It covers:
- the per-server XML schema with field offsets;
- `total_option.xml` and `customoption.xml`;
- the database-backed server topology (`RustyHearts_Auth.ServerOption` /
`ServerFile`).
The `MagiServerOption` field layout matches between MessageServer and
DBCServer (O).
## 5. Database access path
Moved to [`DATABASE.md`](DATABASE.md). It covers the RMI → command queue →
`DBReq*` → stored procedure chain, the four connection types, the
RMI → procedure map and the schema of the five databases.
Summary:
- **Clients and connections:** client servers keep 4 `MGDBCMsgSession` pools
(GAME/LOG/CHAT/EMERGENCY), sized by `db_cache session_count`. They send
`SERVERS2DBC` RMIs (262, IDs 0x2ee1–0x2fe6); this table is **identical in
MessageServer and DBCServer**, O. DBCServer runs stored procedures over ADO
and answers with `DBC2SERVERS` (76 RMIs, 0x2af9–0x2b46).
## 6. Other shared protocols seen in MessageServer (O)
| Protocol | IDs | Direction |
|---|---|---|
| `SERVERS2MSG` (stub) / `MSG2SERVERS` (proxy) | 0x3a99–0x3aa0 | servers ↔ MessageServer (`decomp/MessageServer_Release_x64/evidence.md`) |
| `SERVER2AGENT` | 12 proxy RMIs | see the TSV |
| `AGENT2SERVER` (stub) | ? | Agent pushes ServerInfo (§3) |
## 7. Open questions (priority order)
1. AgentManager: confirm that it reads `ServerOption`/`ServerFile` and pushes
the topology (`CONFIG.md` §5).
2. DBCServer_LOG: the LOG RMIs and RustyHearts_Log (`DATABASE.md` §5).
3. Diff the `SERVERS2DBC` table in the remaining client binaries.
4. Semantics of `send`, `auto`, `lock`, `each_option`, `guildlobby`,
`channel`, and of the `api` peer.
5. Server kinds 0x0e–0x10 and 0x14.