mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-27 10:03:06 +01:00
feat(protbot): add headless MHF protocol bot as cmd/protbot
Copy MHBridge into the Erupe module as cmd/protbot/ so it can be built, tested, and maintained alongside the server. The bot implements the full sign → entrance → channel login flow and supports lobby entry, chat, session setup, and quest enumeration. The conn/ package keeps its own Blowfish crypto primitives to avoid importing erupe-ce/config (which requires a config file at init).
This commit is contained in:
50
cmd/protbot/scenario/session.go
Normal file
50
cmd/protbot/scenario/session.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"erupe-ce/cmd/protbot/protocol"
|
||||
)
|
||||
|
||||
// SetupSession performs the post-login session setup: ISSUE_LOGKEY, RIGHTS_RELOAD, LOADDATA.
|
||||
// Returns the loaddata response blob for inspection.
|
||||
func SetupSession(ch *protocol.ChannelConn, charID uint32) ([]byte, error) {
|
||||
// Step 1: Issue logkey.
|
||||
ack := ch.NextAckHandle()
|
||||
fmt.Printf("[session] Sending MSG_SYS_ISSUE_LOGKEY (ackHandle=%d)...\n", ack)
|
||||
if err := ch.SendPacket(protocol.BuildIssueLogkeyPacket(ack)); err != nil {
|
||||
return nil, fmt.Errorf("issue logkey send: %w", err)
|
||||
}
|
||||
resp, err := ch.WaitForAck(ack, 10*time.Second)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("issue logkey ack: %w", err)
|
||||
}
|
||||
fmt.Printf("[session] ISSUE_LOGKEY ACK (error=%d, %d bytes)\n", resp.ErrorCode, len(resp.Data))
|
||||
|
||||
// Step 2: Rights reload.
|
||||
ack = ch.NextAckHandle()
|
||||
fmt.Printf("[session] Sending MSG_SYS_RIGHTS_RELOAD (ackHandle=%d)...\n", ack)
|
||||
if err := ch.SendPacket(protocol.BuildRightsReloadPacket(ack)); err != nil {
|
||||
return nil, fmt.Errorf("rights reload send: %w", err)
|
||||
}
|
||||
resp, err = ch.WaitForAck(ack, 10*time.Second)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("rights reload ack: %w", err)
|
||||
}
|
||||
fmt.Printf("[session] RIGHTS_RELOAD ACK (error=%d, %d bytes)\n", resp.ErrorCode, len(resp.Data))
|
||||
|
||||
// Step 3: Load save data.
|
||||
ack = ch.NextAckHandle()
|
||||
fmt.Printf("[session] Sending MSG_MHF_LOADDATA (ackHandle=%d)...\n", ack)
|
||||
if err := ch.SendPacket(protocol.BuildLoaddataPacket(ack)); err != nil {
|
||||
return nil, fmt.Errorf("loaddata send: %w", err)
|
||||
}
|
||||
resp, err = ch.WaitForAck(ack, 30*time.Second)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loaddata ack: %w", err)
|
||||
}
|
||||
fmt.Printf("[session] LOADDATA ACK (error=%d, %d bytes)\n", resp.ErrorCode, len(resp.Data))
|
||||
|
||||
return resp.Data, nil
|
||||
}
|
||||
Reference in New Issue
Block a user