avatar

package module
v0.0.0-...-e525491 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2024 License: MIT Imports: 7 Imported by: 0

README

Avatar

Avatar is an emulator for Ultima Online: Renaissance.

Running

$ mkdir logs
$ login 2>>logs/login.log &
$ game 2>>logs/game.log &

Client compatibility

TODO

Building

Requirements:

$ goenv install
$ make

Find login and game in the bin/ directory.

or:

$ OUT_DIR=/some/where/else GOOS=windows GOARCH=amd64 make

Read the Makefile for more options.

Configuration

Provide configuration via a .env file located in the runtime directory or via values present in the runtime environment.

Get started by creating .env:

$ cp .env.example ./bin/.env

Values provided in the runtime environment override values present in the .env file.

Connections
login

By default, login listens on localhost:7775. Change this address by specifying a value for LOGIN_ADDR:

LOGIN_ADDR=10.1.2.3:55940
game

TODO

Storage

Specify a storage provider by setting the value of the STORAGE_PROVIDER environment variable.

  • PostgreSQL: postgres
    • DB_CONNECTION_STRING must also be present.
  • Memory: memory (not recommended)
STORAGE_PROVIDER=postgres
DB_CONNECTION_STRING="user=worker password=foobarbazbat"
Passwords

Specify a password hashing algorithm by setting the value of the PASSWORD_CIPHER environment variable.

  • bcrypt: bcrypt
    • BCRYPT_COST (default: 10) may optionally be present.

You should not change the password hashing algorithm after creating accounts as subsequent password verification would fail.

PASSWORD_CIPHER=bcrypt
BCRYPT_COST=7

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAccountNotFound       = errors.New("account not found")
	ErrDuplicateAccountName  = errors.New("duplicate account name")
	ErrAccountNameTooShort   = errors.New("account name too short")
	ErrDuplicateAccountEmail = errors.New("email address must be unique")
	ErrAccountAlreadyBlocked = errors.New("account is already blocked")
	ErrAccountNotBlocked     = errors.New("account is not blocked")
)

Account error conditions.

View Source
var (
	ErrAccountBlocked     = errors.New("account is blocked")
	ErrInvalidCredentials = errors.New("invalid credentials")
	ErrAccountInUse       = errors.New("account is in use")
)

Account login error conditions.

Functions

This section is empty.

Types

type Account

type Account struct {
	ID             EntityID
	Name           string
	Email          string
	PasswordHash   string
	Blocked        bool
	CreationIP     net.IP
	LastLoginIP    *net.IP
	LastLoggedInAt *time.Time
	CreatedAt      time.Time
	UpdatedAt      *time.Time
	DeletedAt      *time.Time
}

func (Account) Deleted

func (a Account) Deleted() bool

Deleted indicates whether the Account has been deleted.

type AccountRepository

type AccountRepository interface {
	// Get an Account by its ID.
	Get(EntityID) (*Account, error)

	// Create a new Account.
	Create(CreateAccountData) error

	// Update an existing Account.
	Update(EntityID, UpdateAccountData) error

	// Delete an existing Account.
	Delete(EntityID) error

	// FindByName attempts to find a single Account with the specified name.
	// No error is returned if the Account could not be found.
	FindByName(string) (account *Account, err error)

	// FindByEmail attempts to find a single Account with the specified email.
	// No error is returned if the Account could not be found.
	FindByEmail(string) (account *Account, err error)
}

AccountRepository allows for interacting with an Accounts storage provider.

type AccountService

type AccountService struct {
	PasswordService PasswordService
	// contains filtered or unexported fields
}

AccountService provides facilities for working with Accounts.

func NewAccountService

func NewAccountService(
	repo AccountRepository,
	passwordService PasswordService,
) *AccountService

NewAccountService creates a new service capable of managing Accounts.

func (*AccountService) Block

func (as *AccountService) Block(id EntityID) error

Block the Account identified by the provided ID. If no Account could be found or if the Account is already blocked, an error is returned.

func (*AccountService) Create

func (as *AccountService) Create(params CreateAccountParameters) error

Create a new Account.

func (*AccountService) FindByName

func (as *AccountService) FindByName(name string) (*Account, error)

func (*AccountService) Get

func (as *AccountService) Get(id EntityID) (*Account, error)

Get an Account by its ID.

func (*AccountService) Unblock

func (as *AccountService) Unblock(id EntityID) error

Unblock the Account identified by the provided ID. If no Account could be found or if the Account is not blocked, an error is returned.

type ClientState

type ClientState int

ClientState captures the current state of the client.

const (
	// ClientStateUnknown indicates that the current state of the client is not
	// currently known. It is not safe to assume the client can be used.
	ClientStateUnknown ClientState = iota

	// ClientStateDisconnected indicates that the client's connection to the
	// server is no longer valid.
	ClientStateDisconnected

	// ClientStateNew indicates that a client has just recently connected and
	// has not yet been authenticated.
	ClientStateNew

	// ClientStateAuthenticated describes a client has been successfully
	// authenticated.
	ClientStateAuthenticated
)

type CreateAccountData

type CreateAccountData struct {
	Name         string
	Email        string
	PasswordHash string
	CreationIP   net.IP
}

CreateAccountData hold transformed, validated data for creating an Account.

type CreateAccountParameters

type CreateAccountParameters struct {
	Name       string
	Email      string
	Password   string
	CreationIP net.IP
}

CreateAccountParameters holds untransformed and unvalidated data for creating an Account.

type CryptoService

type CryptoService interface {
	// Encrypt src into dst.
	Encrypt(src []byte, dst []byte) error

	// Decrypt src into dst.
	Decrypt(src []byte, dst []byte) error

	// GetSeed returns the Seed used to initialize the CryptoService.
	GetSeed() Seed
}

A CryptoService is capable of encrypting and decrypting data.

type EntityID

type EntityID int64

EntityID represents a unique identifier for a domain entity.

func (EntityID) String

func (id EntityID) String() string

func (EntityID) Valid

func (id EntityID) Valid() bool

Valid determines whether the ID is valid.

type KeyPair

type KeyPair struct {
	Lo, Hi uint32
}

KeyPair contains a pair of version-specific client encryption keys.

type PasswordService

type PasswordService interface {
	// Hash creates a password hash from the plaintext string.
	Hash(password string) (string, error)

	// Verify that the plaintext password matches the encoded hash.
	Verify(password, hash string) (error, bool)
}

PasswordService is capable of generating and verifying password hashes.

type Seed

type Seed uint32

Seed is a value used to initialize the state of a CryptoService.

type UpdateAccountData

type UpdateAccountData struct {
	Name           string
	Email          string
	PasswordHash   string
	Blocked        bool
	LastLoginIP    *net.IP
	LastLoggedInAt *time.Time
}

UpdateAccountData holds transformed, validated data for updating an Account.

func (UpdateAccountData) FromAccount

func (d UpdateAccountData) FromAccount(a *Account)

FromAccount fills the UpdateAccountData struct from an existing Account.

type UpdateAccountParameters

type UpdateAccountParameters struct {
	Name           string
	Email          string
	Password       string
	LastLoginIP    net.IP
	LastLoggedInAt time.Time
}

UpdateAccountParameters holds untransformed and unvalidated data for updating an Account.

type Version

type Version struct {
	Major    uint32
	Minor    uint32
	Patch    uint32
	Revision uint32
}

Version identifies a unique client revision.

func (Version) String

func (v Version) String() string

Jump to

Keyboard shortcuts

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