Files
Erupe/cmd/protbot/conn/conn.go
Houmgaor 0e84377e21 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).
2026-02-20 02:49:23 +01:00

53 lines
1.2 KiB
Go

package conn
import (
"fmt"
"net"
)
// MHFConn wraps a CryptConn and provides convenience methods for MHF connections.
type MHFConn struct {
*CryptConn
RawConn net.Conn
}
// DialWithInit connects to addr and sends the 8 NULL byte initialization
// required by sign and entrance servers.
func DialWithInit(addr string) (*MHFConn, error) {
conn, err := net.Dial("tcp", addr)
if err != nil {
return nil, fmt.Errorf("dial %s: %w", addr, err)
}
// Sign and entrance servers expect 8 NULL bytes to initialize the connection.
_, err = conn.Write(make([]byte, 8))
if err != nil {
conn.Close()
return nil, fmt.Errorf("write init bytes to %s: %w", addr, err)
}
return &MHFConn{
CryptConn: NewCryptConn(conn),
RawConn: conn,
}, nil
}
// DialDirect connects to addr without sending initialization bytes.
// Used for channel server connections.
func DialDirect(addr string) (*MHFConn, error) {
conn, err := net.Dial("tcp", addr)
if err != nil {
return nil, fmt.Errorf("dial %s: %w", addr, err)
}
return &MHFConn{
CryptConn: NewCryptConn(conn),
RawConn: conn,
}, nil
}
// Close closes the underlying connection.
func (c *MHFConn) Close() error {
return c.RawConn.Close()
}