bnet

package
v1.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2022 License: MPL-2.0 Imports: 20 Imported by: 7

Documentation

Overview

Package bnet implements a mocked BNCS client that can be used to interact with BNCS servers.

Example
package main

import (
	"fmt"

	"github.com/nielsAD/gowarcraft3/network"
	"github.com/nielsAD/gowarcraft3/network/bnet"
)

func main() {
	client, err := bnet.NewClient(&bnet.Config{
		ServerAddr: "europe.battle.net.example",
		Username:   "gowarcraft3",
		Password:   "gowarcraft3",
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer client.Close()

	// Log on
	if err = client.Logon(); err != nil {
		fmt.Println(err)
		return
	}

	// Print incoming chat messages
	client.On(&bnet.Chat{}, func(ev *network.Event) {
		var msg = ev.Arg.(*bnet.Chat)
		fmt.Printf("[%s] %s\n", msg.User.Name, msg.Content)
	})

	// Run() blocks until the connection is closed
	client.Run()
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrCheckRevision        = errors.New("bnet: BNCSUtil call to checkRevision failed")
	ErrExeInfo              = errors.New("bnet: BNCSUtil call to getExeInfo failed")
	ErrKeyDecoder           = errors.New("bnet: BNCSUtil call to keyDecoder failed")
	ErrNLS                  = errors.New("bnet: BNCSUtil call to NLS failed")
	ErrUnexpectedPacket     = errors.New("bnet: Received unexpected packet")
	ErrAuthFail             = errors.New("bnet: Authentication failed")
	ErrInvalidServerSig     = errors.New("bnet: Authentication failed (invalid server signature)")
	ErrInvalidGameVersion   = errors.New("bnet: Authentication failed (game version invalid)")
	ErrCDKeyInvalid         = errors.New("bnet: Authentication failed (CD key invalid)")
	ErrCDKeyInUse           = errors.New("bnet: Authentication failed (CD key in use)")
	ErrCDKeyBanned          = errors.New("bnet: Authentication failed (CD key banned)")
	ErrUnknownAccount       = errors.New("bnet: Authentication failed (account does not exist)")
	ErrInvalidAccount       = errors.New("bnet: Authentication failed (account invalid)")
	ErrPasswordVerification = errors.New("bnet: Authentication failed (server cannot verify password)")
	ErrIncorrectPassword    = errors.New("bnet: Authentication failed (password incorrect)")
	ErrAccountCreate        = errors.New("bnet: Account creation failed")
	ErrAccountNameTaken     = errors.New("bnet: Account creation failed (account name taken)")
	ErrAccountNameIllegal   = errors.New("bnet: Account creation failed (illegal account name)")
)

Errors

View Source
var DefaultConfig = Config{
	Platform: bncs.AuthInfoReq{
		PlatformCode:        protocol.DString("IX86"),
		GameVersion:         w3gs.GameVersion{Product: w3gs.ProductROC, Version: w3gs.CurrentGameVersion},
		LanguageCode:        protocol.DString("enUS"),
		TimeZoneBias:        4294967176,
		MpqLocaleID:         1033,
		UserLanguageID:      1033,
		CountryAbbreviation: "USA",
		Country:             "United States",
	},
	KeepAliveInterval: 30 * time.Second,
	CDKeyOwner:        "gowarcraft3",
	GamePort:          6112,
	BinPath:           dir.InstallDir(),
}

DefaultConfig for bnet.Client

Functions

func AccountCreateResultToError

func AccountCreateResultToError(r bncs.AccountCreateResult) error

AccountCreateResultToError converts bncs.AccountCreateResult to an appropriate error

func AuthResultToError

func AuthResultToError(r bncs.AuthResult) error

AuthResultToError converts bncs.AuthResult to an appropriate error

func CheckRevision

func CheckRevision(valueString string, fileNames []string, mpqNumber int) (uint32, error)

CheckRevision runs CheckRevision part of BNCS authentication for mpqNumber First fileName must be the executable file

func CreateBNCSKeyInfo

func CreateBNCSKeyInfo(cdkey string, clientToken uint32, serverToken uint32) (*bncs.CDKey, error)

CreateBNCSKeyInfo decodes a CD-key, retrieves its relevant values, and calculates a hash suitable for SID_AUTH_CHECK (0x51)

func ExtractMPQNumber

func ExtractMPQNumber(mpqName string) int

ExtractMPQNumber reads an MPQ filename (e.g. IX86ver#.mpq) and returns the int value of that number Returns -1 on failure

func FilterChat added in v1.2.1

func FilterChat(s string) string

FilterChat makes the chat message suitable for bnet. It filters out control characters, replaces emoji with text, and truncates length.

func GetExeInfo

func GetExeInfo(fileName string) (uint32, string, error)

GetExeInfo retrieves version and date/size information from executable file

func LogonProofResultToError

func LogonProofResultToError(r bncs.LogonProofResult) error

LogonProofResultToError converts bncs.LogonProofResult to an appropriate error

func LogonResultToError

func LogonResultToError(r bncs.LogonResult) error

LogonResultToError converts bncs.LogonProofResult to an appropriate error

func VerifyServerSignature added in v1.4.0

func VerifyServerSignature(ip net.IP, sig *[128]byte) bool

VerifyServerSignature received in SID_AUTH_INFO (0x50)

Types

type Channel

type Channel struct {
	Name  string
	Flags bncs.ChatChannelFlags
}

Channel joined event

type Chat

type Chat struct {
	User
	Content string
	Type    bncs.ChatEventType
}

Chat event

type Client

type Client struct {
	network.EventEmitter
	network.BNCSConn

	// Read-only
	UniqueName string

	// Set once before Dial(), read-only after that
	Config
	// contains filtered or unexported fields
}

Client represents a mocked BNCS client Public methods/fields are thread-safe unless explicitly stated otherwise

func NewClient

func NewClient(conf *Config) (*Client, error)

NewClient initializes a Client struct

func (*Client) ChangePassword added in v1.2.0

func (b *Client) ChangePassword(newPassword string) error

ChangePassword of an existing account

ChangePassword sequence:

  1. Client starts with Dial sequence
  2. Client waits for user to enter account information and new password:
  3. C > S [0x55] SID_AUTH_ACCOUNTCHANGE
  4. S > C [0x55] SID_AUTH_ACCOUNTCHANGE
  5. C > S [0x56] SID_AUTH_ACCOUNTCHANGEPROOF
  6. S > C [0x56] SID_AUTH_ACCOUNTCHANGEPROOF
  7. Client can continue with logon ([0x53] SID_AUTH_ACCOUNTLOGON)

func (*Client) Channel

func (b *Client) Channel() string

Channel currently chatting in

func (*Client) CreateAccount

func (b *Client) CreateAccount() error

CreateAccount registers a new account

CreateAccount sequence:

  1. Client starts with Dial sequence
  2. Client waits for user to enter new account information:
  3. C > S [0x52] SID_AUTH_ACCOUNTCREATE
  4. S > C [0x52] SID_AUTH_ACCOUNTCREATE
  5. Client can continue with logon ([0x53] SID_AUTH_ACCOUNTLOGON)

func (*Client) Dial

func (b *Client) Dial() (*network.BNCSConn, error)

Dial opens a new connection to server, verifies game version, and authenticates with CD keys

func (*Client) DialWithConn added in v1.6.0

func (b *Client) DialWithConn(conn net.Conn) (*network.BNCSConn, error)

DialWithConn initializes a connection to server, verifies game version, and authenticates with CD keys

Dial sequence:

  1. C > S [0x50] SID_AUTH_INFO
  2. S > C [0x25] SID_PING
  3. C > S [0x25] SID_PING (optional)
  4. S > C [0x50] SID_AUTH_INFO
  5. C > S [0x51] SID_AUTH_CHECK
  6. S > C [0x51] SID_AUTH_CHECK
  7. Client gets icons file, TOS file, and server list file:
  8. C > S [0x2D] SID_GETICONDATA (optional)
  9. S > C [0x2D] SID_GETICONDATA (optional response)
  10. C > S [0x33] SID_GETFILETIME (returned icons file name) (optional)
  11. C > S [0x33] SID_GETFILETIME ("tos_USA.txt") (optional)
  12. C > S [0x33] SID_GETFILETIME ("bnserver.ini") (optional)
  13. S > C [0x33] SID_GETFILETIME (one for each request)
  14. Connection to BNFTPv2 to do file downloads

func (*Client) Encoding added in v1.5.0

func (b *Client) Encoding() bncs.Encoding

Encoding for bncs packets

func (*Client) InitDefaultHandlers

func (b *Client) InitDefaultHandlers()

InitDefaultHandlers adds the default callbacks for relevant packets

func (*Client) Logon

func (b *Client) Logon() error

Logon opens a new connection to server, logs on, and joins chat

Logon sequence:

  1. Client starts with Dial sequence ([0x50] SID_AUTH_INFO and [0x51] SID_AUTH_CHECK)
  2. Client waits for user to enter account information (standard logon shown, uses SRP):
  3. C > S [0x53] SID_AUTH_ACCOUNTLOGON
  4. S > C [0x53] SID_AUTH_ACCOUNTLOGON
  5. C > S [0x54] SID_AUTH_ACCOUNTLOGONPROOF
  6. S > C [0x54] SID_AUTH_ACCOUNTLOGONPROOF
  7. C > S [0x45] SID_NETGAMEPORT (optional)
  8. C > S [0x0A] SID_ENTERCHAT
  9. S > C [0x0A] SID_ENTERCHAT
  10. C > S [0x44] SID_WARCRAFTGENERAL (WID_TOURNAMENT) (optional)
  11. S > C [0x44] SID_WARCRAFTGENERAL (WID_TOURNAMENT) (optional response)
  12. C > S [0x46] SID_NEWS_INFO (optional)
  13. S > C [0x46] SID_NEWS_INFO (optional response)
  14. Client waits until user wants to Enter Chat.
  15. C > S [0x0C] SID_JOINCHANNEL (First Join, "W3")
  16. S > C [0x0F] SID_CHATEVENT
  17. A sequence of chat events for entering chat follow.

func (*Client) Run

func (b *Client) Run() error

Run reads packets and emits an event for each received packet Not safe for concurrent invocation

func (*Client) Say

func (b *Client) Say(s string) error

Say sends a chat message May block while rate-limiting packets

func (*Client) User added in v1.2.0

func (b *Client) User(name string) (*User, bool)

User in channel by name

func (*Client) Users

func (b *Client) Users() map[string]User

Users in channel

type Config added in v1.1.0

type Config struct {
	ServerAddr        string
	KeepAliveInterval time.Duration
	Platform          bncs.AuthInfoReq
	BinPath           string
	ExeInfo           string
	ExeVersion        uint32
	ExeHash           uint32
	VerifySignature   bool
	SHA1Auth          bool
	Username          string
	Password          string
	CDKeyOwner        string
	CDKeys            []string
	GamePort          uint16
}

Config for bnet.Client

type JoinError

type JoinError struct {
	Channel string
	Error   bncs.ChatEventType
}

JoinError event

type NLS

type NLS struct {
	// contains filtered or unexported fields
}

NLS provider for SRP

func NewNLS

func NewNLS(username string, password string) (*NLS, error)

NewNLS initializes a new NLS provider for SRP

func (*NLS) AccountCreate

func (n *NLS) AccountCreate() ([]byte, []byte, error)

AccountCreate generates the content for an SID_AUTH_ACCOUNTCREATE packet

func (*NLS) ClientKey

func (n *NLS) ClientKey() (res [32]byte)

ClientKey for SRP exchange

func (*NLS) Free

func (n *NLS) Free()

Free NLS struct

func (*NLS) PasswordProof added in v1.4.0

func (n *NLS) PasswordProof(serverKey *[32]byte, salt *[32]byte) (res [20]byte)

PasswordProof for SRP exchange

func (*NLS) VerifyPassword added in v1.4.0

func (n *NLS) VerifyPassword(proof *[20]byte) bool

VerifyPassword after SRP exchange

type SHA1 added in v1.4.0

type SHA1 struct {
	// contains filtered or unexported fields
}

SHA1 provider for SRP

func NewSHA1 added in v1.4.0

func NewSHA1(password string) *SHA1

NewSHA1 initializes a new SHA1 provider for SRP

func (*SHA1) AccountCreate added in v1.4.0

func (p *SHA1) AccountCreate() ([]byte, []byte, error)

AccountCreate generates the content for an SID_AUTH_ACCOUNTCREATE packet

func (*SHA1) ClientKey added in v1.4.0

func (p *SHA1) ClientKey() (res [32]byte)

ClientKey for SRP exchange

func (*SHA1) Free added in v1.4.0

func (p *SHA1) Free()

Free SHA1 struct

func (*SHA1) PasswordProof added in v1.4.0

func (p *SHA1) PasswordProof(serverKey *[32]byte, salt *[32]byte) (res [20]byte)

PasswordProof for SRP exchange

func (*SHA1) VerifyPassword added in v1.4.0

func (p *SHA1) VerifyPassword(proof *[20]byte) bool

VerifyPassword after SRP exchange

type SRP added in v1.4.0

type SRP interface {
	AccountCreate() ([]byte, []byte, error)
	ClientKey() [32]byte
	PasswordProof(serverKey *[32]byte, salt *[32]byte) [20]byte
	VerifyPassword(proof *[20]byte) bool
	Free()
}

SRP password helper

type SystemMessage

type SystemMessage struct {
	Content string
	Type    bncs.ChatEventType
}

SystemMessage event

type User

type User struct {
	Name       string
	StatString string
	Flags      bncs.ChatUserFlags
	Ping       uint32
	Joined     time.Time
	LastSeen   time.Time
}

User in chat

func (*User) Operator added in v1.1.0

func (u *User) Operator() bool

Operator in channel

func (User) Stat added in v1.1.0

func (u User) Stat() (product protocol.DWordString, icon protocol.DWordString, lvl int, tag protocol.DWordString)

Stat split into (icon, level, clan)

type UserJoined

type UserJoined struct {
	User
	AlreadyInChannel bool
}

UserJoined event

type UserLeft

type UserLeft struct {
	User
}

UserLeft event

type UserUpdate

type UserUpdate struct {
	User
}

UserUpdate event

type Whisper

type Whisper struct {
	Username string
	Content  string
	Flags    bncs.ChatUserFlags
	Ping     uint32
}

Whisper event

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL