servermanager package - github.com/cj123/assetto-server-manager - Go Packages

servermanager

package module
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2019 License: MIT Imports: 54 Imported by: 0

README

Assetto Server Manager

Build Status

A web interface to manage an Assetto Corsa Server.

Features

  • Quick Race Mode
  • Custom Race Mode with saved presets
  • Live Timings for current sessions
  • Results pages for all previous sessions, with the ability to apply penalties
  • Content Management - Upload tracks, weather and cars
  • Sol Integration - Sol weather is compatible, including 24 hour time cycles (session start may advance/reverse time really fast before it syncs up - requires drivers to launch from content manager)
  • Championship mode - configure multiple race events and keep track of driver, class and team points
  • Automatic event looping
  • Server Logs / Options Editing
  • Accounts system with different permissions levels
  • Linux and Windows Support!

If you like Assetto Server Manager, please consider supporting us with a donation!

Installation

Manual
  1. Download the latest release from the releases page
  2. Extract the release
  3. Edit the config.yml to suit your preferences
  4. Either:
    • Copy the server folder from your Assetto Corsa install into the directory you configured in config.yml, or
    • Make sure that you have steamcmd installed and in your $PATH and have configured the steam username and password in the config.yml file.
  5. Start the server using ./server-manager (on Linux) or by running server-manager.exe (on Windows)
Docker

A docker image is available under the name seejy/assetto-server-manager. We recommend using docker-compose to set up a docker environment for the server manager. This docker image has steamcmd pre-installed.

See Manual to set up server manager without Docker.

Note: if you are using a directory volume for the server install (as is shown below), be sure to make the directory before running docker-compose up - otherwise its permissions may be incorrect.

You will need a config.yml file to mount into the docker container.

An example docker-compose.yml looks like this:

version: "3"

services:
  server-manager:
    image: seejy/assetto-server-manager:latest
    ports:
    # the port that the server manager runs on
    - "8772:8772"
    # the port that the assetto server runs on (may vary depending on your configuration inside server manager)
    - "9600:9600"
    - "9600:9600/udp"
    # the port that the assetto server HTTP API runs on.
    - "8081:8081"
    # you may also wish to bind your configured UDP plugin ports here. 
    volumes: 
    # volume mount the entire server install so that 
    # content etc persists across restarts
    - ./server-install:/home/assetto/server-manager/assetto
    
    # volume mount the config
    - ./config.yml:/home/assetto/server-manager/config.yml
Post Installation

We recommend uploading your entire Assetto Corsa content/tracks folder to get the full features of Server Manager. This includes things like track images, all the correct layouts and any mod tracks you may have installed.

Also, we recommend installing Sol locally and uploading your Sol weather files to Server Manager as well so you can try out Day/Night cycles and cool weather!

Credits & Thanks

Assetto Corsa Server Manager would not have been possible without the following people:

  • Henry Spencer - Twitter / GitHub
  • Callum Jones - Twitter / GitHub
  • Joseph Elton
  • The Pizzabab Championship
  • ACServerManager and its authors, for inspiration and reference on understanding the AC configuration files

Screenshots

Check out the screenshots folder!

Documentation

Index

Constants

View Source
const (
	CurrentMigrationVersion = 7
)
View Source
const MOTDFilename = "motd.txt"
View Source
const MaxLogSizeBytes = 1e6

Variables

View Source
var (
	ErrSessionNotFound    = errors.New("servermanager: session not found")
	ErrResultFileNotFound = errors.New("servermanager: results files not found")
)
View Source
var (
	IsHosted           = os.Getenv("HOSTED") == "true"
	MaxClientsOverride = formValueAsInt(os.Getenv("MAX_CLIENTS_OVERRIDE"))
	IsPremium          = "false"
)
View Source
var (
	ErrNoSteamCMD = errors.New("servermanager: steamcmd was not found in $PATH")

	// ServerInstallPath is where the assetto corsa server should be/is installed
	ServerInstallPath = "assetto"

	ServerConfigPath = "cfg"
)
View Source
var AvailableSessionsClosedChampionship = []SessionType{
	SessionTypeRace,
	SessionTypeQualifying,
	SessionTypePractice,
}
View Source
var BuildTime string

BuildTime is the time Server Manager was built at

View Source
var ChampionshipClassColors = []string{
	"#9ec6f5",
	"#91d8af",
	"#dba8ed",
	"#e3a488",
	"#e3819a",
	"#908ba1",
	"#a2b5b9",
	"#a681b4",
	"#c1929d",
	"#999ecf",
}

ChampionshipClassColors are sequentially selected to indicate different classes within a Championship

View Source
var ChampionshipEventStartTimers map[string]*time.Timer
View Source
var ConfigIniDefault = ServerConfig{
	GlobalServerConfig: GlobalServerConfig{
		Name:                      "Assetto Corsa Server",
		Password:                  "",
		AdminPassword:             "",
		UDPPort:                   9600,
		TCPPort:                   9600,
		HTTPPort:                  8081,
		ClientSendIntervalInHertz: 18,
		SendBufferSize:            0,
		ReceiveBufferSize:         0,
		KickQuorum:                85,
		VotingQuorum:              80,
		VoteDuration:              20,
		BlacklistMode:             1,
		RegisterToLobby:           1,
		UDPPluginLocalPort:        0,
		UDPPluginAddress:          "",
		AuthPluginAddress:         "",
		NumberOfThreads:           2,
	},

	CurrentRaceConfig: CurrentRaceConfig{
		Cars:                      "lotus_evora_gtc",
		Track:                     "ks_silverstone",
		TrackLayout:               "gp",
		SunAngle:                  48,
		PickupModeEnabled:         1,
		LoopMode:                  1,
		SleepTime:                 1,
		RaceOverTime:              180,
		FuelRate:                  100,
		DamageMultiplier:          0,
		TyreWearRate:              100,
		AllowedTyresOut:           3,
		ABSAllowed:                1,
		TractionControlAllowed:    1,
		StabilityControlAllowed:   0,
		AutoClutchAllowed:         0,
		TyreBlanketsAllowed:       1,
		ForceVirtualMirror:        0,
		LegalTyres:                "H;M;S",
		LockedEntryList:           0,
		RacePitWindowStart:        0,
		RacePitWindowEnd:          0,
		ReversedGridRacePositions: 0,
		TimeOfDayMultiplier:       0,
		QualifyMaxWaitPercentage:  200,
		RaceGasPenaltyDisabled:    1,
		MaxBallastKilograms:       50,
		WindBaseSpeedMin:          3,
		WindBaseSpeedMax:          15,
		MaxClients:                18,
		WindBaseDirection:         30,
		WindVariationDirection:    15,
		StartRule:                 2,
		RaceExtraLap:              0,
		MaxContactsPerKilometer:   -1,
		ResultScreenTime:          90,

		Sessions: map[SessionType]SessionConfig{
			SessionTypePractice: {
				Name:   "Practice",
				Time:   10,
				IsOpen: 1,
			},
			SessionTypeQualifying: {
				Name:   "Qualify",
				Time:   10,
				IsOpen: 1,
			},
			SessionTypeRace: {
				Name:     "Race",
				IsOpen:   1,
				WaitTime: 60,
				Laps:     5,
			},
		},

		DynamicTrack: DynamicTrackConfig{
			SessionStart:    100,
			Randomness:      0,
			SessionTransfer: 100,
			LapGain:         10,
		},

		Weather: map[string]*WeatherConfig{
			"WEATHER_0": {
				Graphics:               "3_clear",
				BaseTemperatureAmbient: 26,
				BaseTemperatureRoad:    11,
				VariationAmbient:       1,
				VariationRoad:          1,
			},
		},
	},
}

ConfigIniDefault is the default server config (ish) as supplied via the assetto corsa server.

View Source
var CustomRaceStartTimers map[string]*time.Timer
View Source
var DefaultChampionshipPoints = ChampionshipPoints{
	Places: []int{
		25,
		18,
		15,
		12,
		10,
		8,
		6,
		4,
		2,
		1,
	},
	BestLap:              0,
	PolePosition:         0,
	SecondRaceMultiplier: 1,
}

DefaultChampionshipPoints is the Formula 1 points system.

View Source
var DefaultTrackSurfacePresets = []TrackSurfacePreset{
	{
		Name:            "Dusty",
		SessionStart:    86,
		SessionTransfer: 50,
		Randomness:      1,
		LapGain:         30,
		Description:     "A very slippery track, improves fast with more laps.",
	},
	{
		Name:            "Old",
		SessionStart:    89,
		SessionTransfer: 80,
		Randomness:      3,
		LapGain:         50,
		Description:     "Old tarmac. Bad grip that won't get better soon.",
	},
	{
		Name:            "Slow",
		SessionStart:    96,
		SessionTransfer: 80,
		Randomness:      1,
		LapGain:         300,
		Description:     "A slow track that doesn't improve much.",
	},
	{
		Name:            "Green",
		SessionStart:    95,
		SessionTransfer: 90,
		Randomness:      2,
		LapGain:         132,
		Description:     "A clean track, gets better with more laps.",
	},
	{
		Name:            "Fast",
		SessionStart:    98,
		SessionTransfer: 80,
		Randomness:      2,
		LapGain:         700,
		Description:     "Very grippy track right from the start.",
	},
	{
		Name:            "Optimum",
		SessionStart:    100,
		SessionTransfer: 100,
		Randomness:      0,
		LapGain:         1,
		Description:     "Perfect track for hotlapping.",
	},
}
View Source
var ErrAccountNeedsPassword = errors.New("servermanager: account needs to set a password")
View Source
var ErrAccountNotFound = errors.New("servermanager: account not found")
View Source
var ErrChampionshipNotFound = errors.New("servermanager: championship not found")
View Source
var ErrClassNotFound = errors.New("servermanager: championship class not found")
View Source
var (
	ErrCustomRaceNotFound = errors.New("servermanager: custom race not found")
)
View Source
var ErrEntryListTooBig = errors.New("servermanager: EntryList exceeds MaxClients setting")
View Source
var ErrInvalidChampionshipEvent = errors.New("servermanager: invalid championship event")
View Source
var ErrInvalidUsernameOrPassword = errors.New("servermanager: invalid username or password")
View Source
var ErrMetaValueNotSet = errors.New("servermanager: value not set")
View Source
var ErrMustSubmitCar = errors.New("servermanager: you must set a car")
View Source
var ErrNoActiveEvent = errors.New("servermanager: no active championship event")
View Source
var ErrNoOpenUDPConnection = errors.New("servermanager: no open UDP connection found")
View Source
var ErrResultsPageNotFound = errors.New("servermanager: results page not found")
View Source
var ErrServerAlreadyRunning = errors.New("servermanager: assetto corsa server is already running")
View Source
var OpenAccount = &Account{
	Name:  "Free Access",
	Group: GroupRead,
}

Functions

func AddErrFlashQuick

func AddErrFlashQuick(w http.ResponseWriter, r *http.Request, message string)

func AddFlashQuick

func AddFlashQuick(w http.ResponseWriter, r *http.Request, message string)

Helper function to get message session and add a flash

func AdminAccess

func AdminAccess(r *http.Request) func() bool

func AdminAccessMiddleware

func AdminAccessMiddleware(next http.Handler) http.Handler

func BuildICalEvent added in v1.2.1

func BuildICalEvent(event ScheduledEvent) *components.Event

func CarNameFromFilepath

func CarNameFromFilepath(path string) (string, error)

CarNameFromFilepath takes a filepath e.g. content/cars/rss_formula_rss_4/data.acd and returns the car name, e.g. in this case: rss_formula_rss_4.

func DeleteAccess added in v1.2.0

func DeleteAccess(r *http.Request) func() bool

func DeleteAccessMiddleware added in v1.2.0

func DeleteAccessMiddleware(next http.Handler) http.Handler

func FileServer

func FileServer(r chi.Router, path string, root http.FileSystem)

func FreeUDPPort

func FreeUDPPort() (int, error)

func InitWithStore added in v1.2.0

func InitWithStore(store Store)

func InitialiseScheduledChampionshipEvents added in v1.1.0

func InitialiseScheduledChampionshipEvents() error

func InitialiseScheduledCustomRaces added in v1.1.0

func InitialiseScheduledCustomRaces() error

func InstallAssettoCorsaServer

func InstallAssettoCorsaServer(login, password string, force bool) error

InstallAssettoCorsaServer takes a steam login and password and runs steamcmd to install the assetto server. If the "ServerInstallPath" exists, this function will exit without installing - unless force == true.

func LiveMapCallback added in v1.1.0

func LiveMapCallback(message udp.Message)

func LiveTimingCallback added in v1.1.0

func LiveTimingCallback(response udp.Message)

func LoadTyresFromACDINI

func LoadTyresFromACDINI(data []byte) (map[string]string, error)

LoadTyresFromACDINI reads the tyres.ini file from within the data.acd of a car and finds all available tyre compounds.

func LoggedIn

func LoggedIn(r *http.Request) func() bool

func LoopCallback added in v1.1.0

func LoopCallback(message udp.Message)

callback check for udp end session, load result file, check session type against sessionTypes if session matches last session in sessionTypes then stop server and clear sessionTypes

func LoopRaces

func LoopRaces()

func Migrate added in v1.2.0

func Migrate(store Store) error

func MustLoginMiddleware

func MustLoginMiddleware(requiredGroup Group, next http.Handler) http.Handler

MustLoginMiddleware determines whether an account needs to log in to access a given Group page

func ReadAccess

func ReadAccess(r *http.Request) func() bool

func ReadAccessMiddleware

func ReadAccessMiddleware(next http.Handler) http.Handler

func Router

func Router(fs http.FileSystem) chi.Router

func SetAssettoInstallPath

func SetAssettoInstallPath(installPath string)

func WriteAccess

func WriteAccess(r *http.Request) func() bool

func WriteAccessMiddleware

func WriteAccessMiddleware(next http.Handler) http.Handler

Types

type Account

type Account struct {
	ID uuid.UUID

	Created time.Time
	Updated time.Time
	Deleted time.Time

	Name  string
	Group Group

	PasswordHash string
	PasswordSalt string

	DefaultPassword string
}

func AccountFromRequest added in v1.2.0

func AccountFromRequest(r *http.Request) *Account

func NewAccount added in v1.2.0

func NewAccount() *Account

func (Account) HasGroupPrivilege

func (a Account) HasGroupPrivilege(g Group) bool

func (Account) NeedsPasswordReset added in v1.2.0

func (a Account) NeedsPasswordReset() bool

type AccountManager added in v1.2.0

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

func NewAccountManager added in v1.2.0

func NewAccountManager(store Store) *AccountManager

type AccountsConfig added in v1.2.0

type AccountsConfig struct {
	AdminPasswordOverride string `yaml:"admin_password_override"`
}

type ActiveChampionship

type ActiveChampionship struct {
	ChampionshipID, EventID uuid.UUID
	SessionType             SessionType

	NumLapsCompleted   int
	NumRaceStartEvents int
	// contains filtered or unexported fields
}

type AssetHelper

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

func NewAssetHelper

func NewAssetHelper(baseURL, prefix, suffix string, query map[string]string) *AssetHelper

func (*AssetHelper) GetURL

func (a *AssetHelper) GetURL(location string) string

type AssettoServerProcess

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

AssettoServerProcess manages the assetto corsa server process.

func NewAssettoServerProcess added in v1.2.0

func NewAssettoServerProcess() *AssettoServerProcess

func (*AssettoServerProcess) Done added in v1.2.0

func (as *AssettoServerProcess) Done() <-chan struct{}

func (*AssettoServerProcess) EventType added in v1.2.0

func (as *AssettoServerProcess) EventType() ServerEventType

func (*AssettoServerProcess) IsRunning

func (as *AssettoServerProcess) IsRunning() bool

IsRunning of the server. returns true if running

func (*AssettoServerProcess) Logs

func (as *AssettoServerProcess) Logs() string

Logs outputs the server logs

func (*AssettoServerProcess) Restart

func (as *AssettoServerProcess) Restart() error

Restart the assetto server.

func (*AssettoServerProcess) SendUDPMessage added in v1.2.1

func (as *AssettoServerProcess) SendUDPMessage(message udp.Message) error

func (*AssettoServerProcess) Start

func (as *AssettoServerProcess) Start(cfg ServerConfig, forwardingAddress string, forwardListenPort int) error

Start the assetto server. If it's already running, an ErrServerAlreadyRunning is returned.

func (*AssettoServerProcess) Stop

func (as *AssettoServerProcess) Stop() error

Stop the assetto server.

func (*AssettoServerProcess) UDPCallback added in v1.2.1

func (as *AssettoServerProcess) UDPCallback(message udp.Message)

type BoltStore added in v1.2.0

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

func (*BoltStore) DeleteAccount added in v1.2.0

func (rs *BoltStore) DeleteAccount(id string) error

func (*BoltStore) DeleteChampionship added in v1.2.0

func (rs *BoltStore) DeleteChampionship(id string) error

func (*BoltStore) DeleteCustomRace added in v1.2.0

func (rs *BoltStore) DeleteCustomRace(race *CustomRace) error

func (*BoltStore) FindAccountByID added in v1.2.0

func (rs *BoltStore) FindAccountByID(id string) (*Account, error)

func (*BoltStore) FindAccountByName added in v1.2.0

func (rs *BoltStore) FindAccountByName(name string) (*Account, error)

func (*BoltStore) FindCustomRaceByID added in v1.2.0

func (rs *BoltStore) FindCustomRaceByID(uuid string) (*CustomRace, error)

func (*BoltStore) GetMeta added in v1.2.0

func (rs *BoltStore) GetMeta(key string, out interface{}) error

func (*BoltStore) ListAccounts added in v1.2.0

func (rs *BoltStore) ListAccounts() ([]*Account, error)

func (*BoltStore) ListChampionships added in v1.2.0

func (rs *BoltStore) ListChampionships() ([]*Championship, error)

func (*BoltStore) ListCustomRaces added in v1.2.0

func (rs *BoltStore) ListCustomRaces() ([]*CustomRace, error)

func (*BoltStore) ListEntrants added in v1.2.0

func (rs *BoltStore) ListEntrants() ([]*Entrant, error)

func (*BoltStore) ListPrevFrames added in v1.2.0

func (rs *BoltStore) ListPrevFrames() ([]string, error)

func (*BoltStore) LoadChampionship added in v1.2.0

func (rs *BoltStore) LoadChampionship(id string) (*Championship, error)

func (*BoltStore) LoadServerOptions added in v1.2.0

func (rs *BoltStore) LoadServerOptions() (*GlobalServerConfig, error)

func (*BoltStore) SetMeta added in v1.2.0

func (rs *BoltStore) SetMeta(key string, value interface{}) error

func (*BoltStore) UpsertAccount added in v1.2.0

func (rs *BoltStore) UpsertAccount(a *Account) error

func (*BoltStore) UpsertChampionship added in v1.2.0

func (rs *BoltStore) UpsertChampionship(c *Championship) error

func (*BoltStore) UpsertCustomRace added in v1.2.0

func (rs *BoltStore) UpsertCustomRace(race *CustomRace) error

func (*BoltStore) UpsertEntrant added in v1.2.0

func (rs *BoltStore) UpsertEntrant(entrant Entrant) error

func (*BoltStore) UpsertLiveFrames added in v1.2.0

func (rs *BoltStore) UpsertLiveFrames(frameLinks []string) error

func (*BoltStore) UpsertServerOptions added in v1.2.0

func (rs *BoltStore) UpsertServerOptions(so *GlobalServerConfig) error

type Car

type Car struct {
	Name  string
	Skins []string
	Tyres map[string]string
}

func (Car) PrettyName

func (c Car) PrettyName() string

type CarSetups added in v1.2.0

type CarSetups map[string]map[string][]string

CarSetups is a map of car name to the setups for that car. it is a map of car name => track name => []setup

func ListSetups added in v1.2.0

func ListSetups() (CarSetups, error)

type Cars

type Cars []Car

func ListCars

func ListCars() (Cars, error)

func (Cars) AsMap

func (cs Cars) AsMap() map[string][]string

type Championship

type Championship struct {
	ID      uuid.UUID
	Name    string
	Created time.Time
	Updated time.Time
	Deleted time.Time

	// Raw html can be attached to championships, used to share tracks/cars etc.
	Info template.HTML
	// Deprecated, replaced with Info above.
	Links map[string]string

	// OpenEntrants indicates that entrant names do not need to be specified in the EntryList.
	// As Entrants join a championship, the available Entrant slots will be filled by the information
	// provided by a join message. The EntryList for each class will still need creating, but
	// can omit names/GUIDs/teams as necessary. These can then be edited after the fact.
	OpenEntrants bool

	Classes []*ChampionshipClass
	Events  []*ChampionshipEvent
}

A Championship is a collection of ChampionshipEvents for a group of Entrants. Each Entrant in a Championship is awarded Points for their position in a ChampionshipEvent.

func NewChampionship

func NewChampionship(name string) *Championship

NewChampionship creates a Championship with a given name, creating a UUID for the championship as well.

func (*Championship) AddClass

func (c *Championship) AddClass(class *ChampionshipClass)

AddClass to the championship

func (*Championship) AllEntrants

func (c *Championship) AllEntrants() EntryList

AllEntrants returns the list of all entrants in the championship (across ALL classes)

func (*Championship) EnhanceResults added in v1.2.0

func (c *Championship) EnhanceResults(results *SessionResults)

EnhanceResults takes a set of SessionResults and attaches Championship information to them.

func (*Championship) EventByID

func (c *Championship) EventByID(id string) (*ChampionshipEvent, error)

EventByID finds a ChampionshipEvent by its ID string.

func (*Championship) FindClassForCarModel

func (c *Championship) FindClassForCarModel(model string) (*ChampionshipClass, error)

func (*Championship) GetPlayerSummary added in v1.1.0

func (c *Championship) GetPlayerSummary(guid string) string

func (*Championship) HasScheduledEvents added in v1.2.1

func (c *Championship) HasScheduledEvents() bool

func (*Championship) IsMultiClass

func (c *Championship) IsMultiClass() bool

IsMultiClass is true if the Championship has more than one Class

func (*Championship) NumEntrants

func (c *Championship) NumEntrants() int

NumEntrants is the number of entrants across all Classes in a Championship.

func (*Championship) Progress

func (c *Championship) Progress() float64

Progress of the Championship as a percentage

func (*Championship) ValidCarIDs

func (c *Championship) ValidCarIDs() []string

ValidCarIDs returns a set of all of the valid cars in the Championship - that is, the smallest possible list of Cars driven by the Entrants.

type ChampionshipClass

type ChampionshipClass struct {
	ID   uuid.UUID
	Name string

	Entrants EntryList
	Points   ChampionshipPoints
}

ChampionshipClass contains a Name, Entrants (including Cars, Skins) and Points for those Entrants

func NewChampionshipClass

func NewChampionshipClass(name string) *ChampionshipClass

NewChampionshipClass creates a championship class with the default points

func (*ChampionshipClass) AttachEntrantToResult added in v1.2.0

func (c *ChampionshipClass) AttachEntrantToResult(entrant *Entrant, results *SessionResults)

func (*ChampionshipClass) DriverInClass added in v1.2.0

func (c *ChampionshipClass) DriverInClass(result *SessionResult) bool

func (*ChampionshipClass) PointForPos

func (c *ChampionshipClass) PointForPos(i int) float64

PointForPos uses the Championship's Points to determine what number should be awarded to a given position

func (*ChampionshipClass) ResultsForClass

func (c *ChampionshipClass) ResultsForClass(results []*SessionResult) (filtered []*SessionResult)

func (*ChampionshipClass) Standings

func (c *ChampionshipClass) Standings(events []*ChampionshipEvent) []*ChampionshipStanding

Standings returns the current Driver Standings for the Championship.

func (*ChampionshipClass) TeamStandings

func (c *ChampionshipClass) TeamStandings(events []*ChampionshipEvent) []*TeamStanding

TeamStandings returns the current position of Teams in the Championship.

func (*ChampionshipClass) ValidCarIDs

func (c *ChampionshipClass) ValidCarIDs() []string

ValidCarIDs returns a set of all cars chosen within the given class

type ChampionshipEvent

type ChampionshipEvent struct {
	ID uuid.UUID

	RaceSetup CurrentRaceConfig
	EntryList EntryList

	Sessions map[SessionType]*ChampionshipSession

	StartedTime   time.Time
	CompletedTime time.Time
	Scheduled     time.Time
	// contains filtered or unexported fields
}

A ChampionshipEvent is a given RaceSetup with Sessions.

func NewChampionshipEvent

func NewChampionshipEvent() *ChampionshipEvent

NewChampionshipEvent creates a ChampionshipEvent with an ID

func (*ChampionshipEvent) Cars added in v1.2.0

func (cr *ChampionshipEvent) Cars(c *Championship) []string

func (*ChampionshipEvent) CombineEntryLists added in v1.2.0

func (cr *ChampionshipEvent) CombineEntryLists(championship *Championship) EntryList

func (*ChampionshipEvent) Completed

func (cr *ChampionshipEvent) Completed() bool

Completed ChampionshipEvents have a non-zero CompletedTime

func (*ChampionshipEvent) GetEntryList added in v1.2.1

func (cr *ChampionshipEvent) GetEntryList() EntryList

func (*ChampionshipEvent) GetID added in v1.2.1

func (cr *ChampionshipEvent) GetID() uuid.UUID

func (*ChampionshipEvent) GetRaceSetup added in v1.2.1

func (cr *ChampionshipEvent) GetRaceSetup() CurrentRaceConfig

func (*ChampionshipEvent) GetScheduledTime added in v1.2.1

func (cr *ChampionshipEvent) GetScheduledTime() time.Time

func (*ChampionshipEvent) GetSummary added in v1.2.1

func (cr *ChampionshipEvent) GetSummary() string

func (*ChampionshipEvent) GetURL added in v1.2.1

func (cr *ChampionshipEvent) GetURL() string

func (*ChampionshipEvent) InProgress

func (cr *ChampionshipEvent) InProgress() bool

InProgress indicates whether a ChampionshipEvent has been started but not stopped

func (*ChampionshipEvent) LastSession

func (cr *ChampionshipEvent) LastSession() SessionType

LastSession returns the last configured session in the championship, in the following order: Race, Qualifying, Practice, Booking

type ChampionshipManager

type ChampionshipManager struct {
	*RaceManager
	// contains filtered or unexported fields
}

func NewChampionshipManager

func NewChampionshipManager(rm *RaceManager) *ChampionshipManager

func (*ChampionshipManager) BuildChampionshipEventOpts

func (cm *ChampionshipManager) BuildChampionshipEventOpts(r *http.Request) (map[string]interface{}, error)

func (*ChampionshipManager) BuildChampionshipOpts

func (cm *ChampionshipManager) BuildChampionshipOpts(r *http.Request) (map[string]interface{}, error)

func (*ChampionshipManager) BuildICalFeed added in v1.2.1

func (cm *ChampionshipManager) BuildICalFeed(championshipID string, w io.Writer) error

func (*ChampionshipManager) CancelEvent

func (cm *ChampionshipManager) CancelEvent(championshipID string, eventID string) error

func (*ChampionshipManager) ChampionshipEventCallback

func (cm *ChampionshipManager) ChampionshipEventCallback(message udp.Message)

func (*ChampionshipManager) DeleteChampionship

func (cm *ChampionshipManager) DeleteChampionship(id string) error

func (*ChampionshipManager) DeleteEvent

func (cm *ChampionshipManager) DeleteEvent(championshipID string, eventID string) error

func (*ChampionshipManager) GetChampionshipAndEvent added in v1.1.0

func (cm *ChampionshipManager) GetChampionshipAndEvent(championshipID string, eventID string) (*Championship, *ChampionshipEvent, error)

func (*ChampionshipManager) HandleCreateChampionship

func (cm *ChampionshipManager) HandleCreateChampionship(r *http.Request) (championship *Championship, edited bool, err error)

func (*ChampionshipManager) ImportEvent added in v1.2.0

func (cm *ChampionshipManager) ImportEvent(championshipID string, eventID string, r *http.Request) error

func (*ChampionshipManager) ListAvailableResultsFilesForEvent added in v1.2.0

func (cm *ChampionshipManager) ListAvailableResultsFilesForEvent(championshipID string, eventID string) (*ChampionshipEvent, []SessionResults, error)

func (*ChampionshipManager) ListChampionships

func (cm *ChampionshipManager) ListChampionships() ([]*Championship, error)

func (*ChampionshipManager) LoadChampionship

func (cm *ChampionshipManager) LoadChampionship(id string) (*Championship, error)

func (*ChampionshipManager) RestartActiveEvent added in v1.2.0

func (cm *ChampionshipManager) RestartActiveEvent() error

func (*ChampionshipManager) RestartEvent

func (cm *ChampionshipManager) RestartEvent(championshipID string, eventID string) error

func (*ChampionshipManager) SaveChampionshipEvent

func (cm *ChampionshipManager) SaveChampionshipEvent(r *http.Request) (championship *Championship, event *ChampionshipEvent, edited bool, err error)

func (*ChampionshipManager) ScheduleEvent added in v1.1.0

func (cm *ChampionshipManager) ScheduleEvent(championshipID string, eventID string, date time.Time, action string) error

func (*ChampionshipManager) StartEvent

func (cm *ChampionshipManager) StartEvent(championshipID string, eventID string) error

func (*ChampionshipManager) StartPracticeEvent

func (cm *ChampionshipManager) StartPracticeEvent(championshipID string, eventID string) error

Start a 2hr long Practice Event based off the existing championship event with eventID

func (*ChampionshipManager) StopActiveEvent added in v1.2.0

func (cm *ChampionshipManager) StopActiveEvent() error

func (*ChampionshipManager) UpsertChampionship

func (cm *ChampionshipManager) UpsertChampionship(c *Championship) error

type ChampionshipPoints

type ChampionshipPoints struct {
	Places       []int
	BestLap      int
	PolePosition int

	SecondRaceMultiplier float64
}

ChampionshipPoints represent the potential points for positions as well as other awards in a Championship.

type ChampionshipSession

type ChampionshipSession struct {
	StartedTime   time.Time
	CompletedTime time.Time

	Results *SessionResults
}

A ChampionshipSession contains information found from the live portion of the Championship tool

func (*ChampionshipSession) Completed

func (ce *ChampionshipSession) Completed() bool

Completed ChampionshipSessions have a non-zero CompletedTime

func (*ChampionshipSession) InProgress

func (ce *ChampionshipSession) InProgress() bool

InProgress indicates whether a ChampionshipSession has been started but not stopped

type ChampionshipStanding

type ChampionshipStanding struct {
	Car *SessionCar

	// Teams is a map of Team Name to how many Events per team were completed.
	Teams  map[string]int
	Points float64
}

ChampionshipStanding is the current number of Points an Entrant in the Championship has.

func NewChampionshipStanding added in v1.2.0

func NewChampionshipStanding(car *SessionCar) *ChampionshipStanding

func (*ChampionshipStanding) AddEventForTeam added in v1.2.0

func (cs *ChampionshipStanding) AddEventForTeam(team string)

func (*ChampionshipStanding) TeamSummary added in v1.2.0

func (cs *ChampionshipStanding) TeamSummary() string

type Collision

type Collision struct {
	Type     string
	Time     int64
	OtherCar uint8
	Speed    float32
}

type Configuration

type Configuration struct {
	HTTP     HTTPConfig        `yaml:"http"`
	Steam    SteamConfig       `yaml:"steam"`
	Store    StoreConfig       `yaml:"store"`
	LiveMap  LiveMapConfig     `yaml:"live_map"`
	Server   ServerExtraConfig `yaml:"server"`
	Accounts AccountsConfig    `yaml:"accounts"`
}

func ReadConfig

func ReadConfig(location string) (conf *Configuration, err error)

type ContentFile

type ContentFile struct {
	Name     string `json:"name"`
	FileType string `json:"type"`
	FilePath string `json:"filepath"`
	Data     string `json:"dataBase64"`
	Size     int    `json:"size"`
}

type CurrentRaceConfig

type CurrentRaceConfig struct {
	Cars                      string `ini:"CARS" show:"quick" input:"multiSelect" formopts:"CarOpts" help:"Models of cars allowed in the server"`
	Track                     string `ini:"TRACK" show:"quick" input:"dropdown" formopts:"TrackOpts" help:"Track name"`
	TrackLayout               string `` /* 128-byte string literal not displayed */
	SunAngle                  int    `ini:"SUN_ANGLE" help:"Angle of the position of the sun"`
	LegalTyres                string `ini:"LEGAL_TYRES" help:"List of tyres short names that are allowed"`
	FuelRate                  int    `ini:"FUEL_RATE" min:"0" help:"Fuel usage from 0 (no fuel usage) to XXX (100 is the realistic one)"`
	DamageMultiplier          int    `ini:"DAMAGE_MULTIPLIER" min:"0" max:"100" help:"Damage from 0 (no damage) to 100 (full damage)"`
	TyreWearRate              int    `ini:"TYRE_WEAR_RATE" min:"0" help:"Tyre wear from 0 (no tyre wear) to XXX (100 is the realistic one)"`
	AllowedTyresOut           int    `ini:"ALLOWED_TYRES_OUT" help:"TODO: I have no idea"`
	ABSAllowed                int    `` /* 133-byte string literal not displayed */
	TractionControlAllowed    int    `` /* 129-byte string literal not displayed */
	StabilityControlAllowed   int    `ini:"STABILITY_ALLOWED" input:"checkbox" help:"Stability assist 0 -> OFF; 1 -> ON"`
	AutoClutchAllowed         int    `ini:"AUTOCLUTCH_ALLOWED" input:"checkbox" help:"Autoclutch assist 0 -> OFF; 1 -> ON"`
	TyreBlanketsAllowed       int    `` /* 147-byte string literal not displayed */
	ForceVirtualMirror        int    `` /* 126-byte string literal not displayed */
	LockedEntryList           int    `ini:"LOCKED_ENTRY_LIST" input:"checkbox" help:"Only players already included in the entry list can join the server"`
	RacePitWindowStart        int    `ini:"RACE_PIT_WINDOW_START" help:"pit window opens at lap/minute specified"`
	RacePitWindowEnd          int    `ini:"RACE_PIT_WINDOW_END" help:"pit window closes at lap/minute specified"`
	ReversedGridRacePositions int    `` /* 216-byte string literal not displayed */
	TimeOfDayMultiplier       int    `ini:"TIME_OF_DAY_MULT" help:"multiplier for the time of day"`
	QualifyMaxWaitPercentage  int    `` /* 205-byte string literal not displayed */
	RaceGasPenaltyDisabled    int    `` /* 195-byte string literal not displayed */
	MaxBallastKilograms       int    `ini:"MAX_BALLAST_KG" help:"the max total of ballast that can be added through the admin command"`
	RaceExtraLap              int    `ini:"RACE_EXTRA_LAP" input:"checkbox" help:"If the race is timed, force an extra lap after the leader has crossed the line"`
	MaxContactsPerKilometer   int    `ini:"MAX_CONTACTS_PER_KM" help:"Maximum number times you can make contact with another car in 1 kilometer."`
	ResultScreenTime          int    `ini:"RESULT_SCREEN_TIME" help:"Seconds of result screen between racing sessions"`

	PickupModeEnabled int `` /* 210-byte string literal not displayed */
	LoopMode          int `ini:"LOOP_MODE" input:"checkbox" help:"the server restarts from the first track, to disable this set it to 0"`

	MaxClients   int `ini:"MAX_CLIENTS" help:"max number of clients (must be <= track's number of pits)"`
	SleepTime    int `ini:"SLEEP_TIME" help:"TODO"`
	RaceOverTime int `` /* 128-byte string literal not displayed */
	StartRule    int `` /* 173-byte string literal not displayed */

	IsSol int `` /* 138-byte string literal not displayed */

	WindBaseSpeedMin       int `ini:"WIND_BASE_SPEED_MIN" help:"Min speed of the session possible"`
	WindBaseSpeedMax       int `ini:"WIND_BASE_SPEED_MAX" help:"Max speed of session possible (max 40)"`
	WindBaseDirection      int `ini:"WIND_BASE_DIRECTION" help:"base direction of the wind (wind is pointing at); 0 = North, 90 = East etc"`
	WindVariationDirection int `ini:"WIND_VARIATION_DIRECTION" help:"variation (+ or -) of the base direction"`

	DynamicTrack DynamicTrackConfig `ini:"-"`

	Sessions Sessions                  `ini:"-"`
	Weather  map[string]*WeatherConfig `ini:"-"`
}

func (*CurrentRaceConfig) AddSession

func (c *CurrentRaceConfig) AddSession(sessionType SessionType, config SessionConfig)

func (*CurrentRaceConfig) AddWeather

func (c *CurrentRaceConfig) AddWeather(weather *WeatherConfig)

func (CurrentRaceConfig) HasMultipleRaces added in v1.1.0

func (c CurrentRaceConfig) HasMultipleRaces() bool

func (CurrentRaceConfig) HasSession

func (c CurrentRaceConfig) HasSession(sess SessionType) bool

func (*CurrentRaceConfig) RemoveSession

func (c *CurrentRaceConfig) RemoveSession(sessionType SessionType)

func (*CurrentRaceConfig) RemoveWeather

func (c *CurrentRaceConfig) RemoveWeather(weather *WeatherConfig)

type CustomRace

type CustomRace struct {
	Name          string
	Created       time.Time
	Updated       time.Time
	Deleted       time.Time
	Scheduled     time.Time
	UUID          uuid.UUID
	Starred, Loop bool

	RaceConfig CurrentRaceConfig
	EntryList  EntryList
}

func (*CustomRace) GetEntryList added in v1.2.1

func (cr *CustomRace) GetEntryList() EntryList

func (*CustomRace) GetID added in v1.2.1

func (cr *CustomRace) GetID() uuid.UUID

func (*CustomRace) GetRaceSetup added in v1.2.1

func (cr *CustomRace) GetRaceSetup() CurrentRaceConfig

func (*CustomRace) GetScheduledTime added in v1.2.1

func (cr *CustomRace) GetScheduledTime() time.Time

func (*CustomRace) GetSummary added in v1.2.1

func (cr *CustomRace) GetSummary() string

func (*CustomRace) GetURL added in v1.2.1

func (cr *CustomRace) GetURL() string

type DynamicTrackConfig

type DynamicTrackConfig struct {
	SessionStart    int `ini:"SESSION_START" help:"% level of grip at session start"`
	Randomness      int `ini:"RANDOMNESS" help:"level of randomness added to the start grip"`
	SessionTransfer int `` /* 281-byte string literal not displayed */
	LapGain         int `ini:"LAP_GAIN" help:"how many laps are needed to add 1% grip"`
}

type Entrant

type Entrant struct {
	InternalUUID uuid.UUID `ini:"-"`

	Name string `ini:"DRIVERNAME"`
	Team string `ini:"TEAM"`
	GUID string `ini:"GUID"`

	Model string `ini:"MODEL"`
	Skin  string `ini:"SKIN"`

	Ballast       int    `ini:"BALLAST"`
	SpectatorMode int    `ini:"SPECTATOR_MODE"`
	Restrictor    int    `ini:"RESTRICTOR"`
	FixedSetup    string `ini:"FIXED_SETUP"`

	TransferTeamPoints bool `ini:"-" json:"-"`
	OverwriteAllEvents bool `ini:"-" json:"-"`
}

func NewEntrant added in v1.2.0

func NewEntrant() *Entrant

func (Entrant) ID

func (e Entrant) ID() string

func (Entrant) OverwriteProperties added in v1.2.0

func (e Entrant) OverwriteProperties(other *Entrant)

type EntryList

type EntryList map[string]*Entrant

func (EntryList) Add

func (e EntryList) Add(entrant *Entrant)

Add an Entrant to the EntryList

func (EntryList) AsSlice

func (e EntryList) AsSlice() []*Entrant

func (EntryList) Delete

func (e EntryList) Delete(entrant *Entrant)

Remove an Entrant from the EntryList

func (EntryList) Entrants

func (e EntryList) Entrants() string

func (EntryList) FindEntrantByInternalUUID added in v1.2.0

func (e EntryList) FindEntrantByInternalUUID(internalUUID uuid.UUID) *Entrant

func (EntryList) PrettyList added in v1.2.0

func (e EntryList) PrettyList() []*Entrant

func (EntryList) Write

func (e EntryList) Write() error

Write the EntryList to the server location

type Form

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

func NewForm

func NewForm(i interface{}, dropdownOpts map[string][]string, visibility string, forceShowAllOptions bool) *Form

func (Form) Fields

func (f Form) Fields() []FormElement

func (Form) Submit

func (f Form) Submit(r *http.Request) error

type FormElement

type FormElement interface {
	HTML() template.HTML
}

type FormHeader

type FormHeader struct {
	Name string
}

func (FormHeader) HTML

func (fh FormHeader) HTML() template.HTML

type FormOption

type FormOption struct {
	Name     string
	Key      string
	Type     string
	HelpText string
	Value    interface{}
	Min, Max string
	Hidden   bool

	Opts map[string]bool
}

func (FormOption) HTML

func (f FormOption) HTML() template.HTML

type GlobalServerConfig

type GlobalServerConfig struct {
	Name                      string `ini:"NAME" help:"Server Name"`
	Password                  string `ini:"PASSWORD" input:"password" help:"Server password"`
	AdminPassword             string `` /* 225-byte string literal not displayed */
	UDPPort                   int    `ini:"UDP_PORT" show:"open" min:"0" max:"65535" help:"UDP port number: open this port on your server's firewall"`
	TCPPort                   int    `ini:"TCP_PORT" show:"open" min:"0" max:"65535" help:"TCP port number: open this port on your server's firewall"`
	HTTPPort                  int    `` /* 135-byte string literal not displayed */
	UDPPluginLocalPort        int    `ini:"UDP_PLUGIN_LOCAL_PORT" show:"open" min:"0" max:"65535" help:"The port on which to listen for UDP messages from a plugin"`
	UDPPluginAddress          string `ini:"UDP_PLUGIN_ADDRESS" show:"open" help:"The address of the plugin to which UDP messages are sent"`
	AuthPluginAddress         string `ini:"AUTH_PLUGIN_ADDRESS" show:"open" help:"The address of the auth plugin"`
	RegisterToLobby           int    `ini:"REGISTER_TO_LOBBY" show:"open" input:"checkbox" help:"Register the AC Server to the main lobby"`
	ClientSendIntervalInHertz int    `` /* 228-byte string literal not displayed */
	SendBufferSize            int    `ini:"SEND_BUFFER_SIZE" show:"open" help:""`
	ReceiveBufferSize         int    `ini:"RECV_BUFFER_SIZE" show:"open" help:""`
	KickQuorum                int    `ini:"KICK_QUORUM" help:"Percentage that is required for the kick vote to pass"`
	VotingQuorum              int    `ini:"VOTING_QUORUM" min:"0" max:"100" help:"Percentage that is required for the session vote to pass"`
	VoteDuration              int    `ini:"VOTE_DURATION" min:"0" help:"Vote length in seconds"`
	BlacklistMode             int    `` /* 294-byte string literal not displayed */
	NumberOfThreads           int    `ini:"NUM_THREADS" show:"open" min:"1" help:"Number of threads to run on"`
	WelcomeMessage            string `ini:"WELCOME_MESSAGE" show:"-" help:"Path to the file that contains the server welcome message"`

	FreeUDPPluginLocalPort int    `ini:"-" show:"-"`
	FreeUDPPluginAddress   string `ini:"-" show:"-"`
}

type Group

type Group string
const (
	GroupRead   Group = "read"
	GroupWrite  Group = "write"
	GroupDelete Group = "delete"
	GroupAdmin  Group = "admin"
)

type HTTPConfig

type HTTPConfig struct {
	Hostname   string `yaml:"hostname"`
	SessionKey string `yaml:"session_key"`
	BaseURL    string `yaml:"server_manager_base_URL"`
}

type JSONStore added in v1.2.0

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

func (*JSONStore) DeleteAccount added in v1.2.0

func (rs *JSONStore) DeleteAccount(id string) error

func (*JSONStore) DeleteChampionship added in v1.2.0

func (rs *JSONStore) DeleteChampionship(id string) error

func (*JSONStore) DeleteCustomRace added in v1.2.0

func (rs *JSONStore) DeleteCustomRace(race *CustomRace) error

func (*JSONStore) FindAccountByID added in v1.2.0

func (rs *JSONStore) FindAccountByID(id string) (*Account, error)

func (*JSONStore) FindAccountByName added in v1.2.0

func (rs *JSONStore) FindAccountByName(name string) (*Account, error)

func (*JSONStore) FindCustomRaceByID added in v1.2.0

func (rs *JSONStore) FindCustomRaceByID(uuid string) (*CustomRace, error)

func (*JSONStore) GetMeta added in v1.2.0

func (rs *JSONStore) GetMeta(key string, out interface{}) error

func (*JSONStore) ListAccounts added in v1.2.0

func (rs *JSONStore) ListAccounts() ([]*Account, error)

func (*JSONStore) ListChampionships added in v1.2.0

func (rs *JSONStore) ListChampionships() ([]*Championship, error)

func (*JSONStore) ListCustomRaces added in v1.2.0

func (rs *JSONStore) ListCustomRaces() ([]*CustomRace, error)

func (*JSONStore) ListEntrants added in v1.2.0

func (rs *JSONStore) ListEntrants() ([]*Entrant, error)

func (*JSONStore) ListPrevFrames added in v1.2.0

func (rs *JSONStore) ListPrevFrames() ([]string, error)

func (*JSONStore) LoadChampionship added in v1.2.0

func (rs *JSONStore) LoadChampionship(id string) (*Championship, error)

func (*JSONStore) LoadServerOptions added in v1.2.0

func (rs *JSONStore) LoadServerOptions() (*GlobalServerConfig, error)

func (*JSONStore) SetMeta added in v1.2.0

func (rs *JSONStore) SetMeta(key string, value interface{}) error

func (*JSONStore) UpsertAccount added in v1.2.0

func (rs *JSONStore) UpsertAccount(a *Account) error

func (*JSONStore) UpsertChampionship added in v1.2.0

func (rs *JSONStore) UpsertChampionship(c *Championship) error

func (*JSONStore) UpsertCustomRace added in v1.2.0

func (rs *JSONStore) UpsertCustomRace(race *CustomRace) error

func (*JSONStore) UpsertEntrant added in v1.2.0

func (rs *JSONStore) UpsertEntrant(entrant Entrant) error

func (*JSONStore) UpsertLiveFrames added in v1.2.0

func (rs *JSONStore) UpsertLiveFrames(frameLinks []string) error

func (*JSONStore) UpsertServerOptions added in v1.2.0

func (rs *JSONStore) UpsertServerOptions(so *GlobalServerConfig) error

type LiveCar

type LiveCar struct {
	// Static Car Info
	DriverName, DriverGUID string
	CarMode, CarSkin       string

	// Live Info
	LapNum int

	Loaded     bool
	LoadedTime int64

	LastLap                 string
	BestLap                 string
	BestLapTime             time.Duration
	LastLapCompleteTime     time.Time
	LastLapCompleteTimeUnix int64
	Pos                     int
	Split                   string

	Collisions []Collision
}

type LiveCarWID

type LiveCarWID struct {
	Car *LiveCar
	ID  uint8
}

type LiveMapConfig added in v1.1.0

type LiveMapConfig struct {
	IntervalMs int `yaml:"refresh_interval_ms"`
}

func (*LiveMapConfig) IsEnabled added in v1.1.0

func (l *LiveMapConfig) IsEnabled() bool

type LiveTiming

type LiveTiming struct {
	// Server Info, static
	ServerName, Track, TrackConfig, Name string
	Type, AmbientTemp, RoadTemp          uint8
	Time, Laps, WaitTime                 uint16
	WeatherGraphics                      string
	ElapsedMilliseconds                  int32
	SessionStarted                       int64

	Cars        map[uint8]*LiveCar  // map[carID]LiveCar
	DeletedCars map[string]*LiveCar // map[carID]LiveCar

	// Live data
	LapNum int
	// contains filtered or unexported fields
}

Live timing output format

type RaceManager

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

func NewRaceManager

func NewRaceManager(raceStore Store) *RaceManager

func (*RaceManager) BuildCustomRaceFromForm

func (rm *RaceManager) BuildCustomRaceFromForm(r *http.Request) (*CurrentRaceConfig, error)

func (*RaceManager) BuildEntryList

func (rm *RaceManager) BuildEntryList(r *http.Request, start, length int) (EntryList, error)

func (*RaceManager) BuildRaceOpts

func (rm *RaceManager) BuildRaceOpts(r *http.Request) (map[string]interface{}, error)

BuildRaceOpts builds a quick race form

func (*RaceManager) CurrentRace

func (rm *RaceManager) CurrentRace() (*ServerConfig, EntryList)

func (*RaceManager) DeleteCustomRace

func (rm *RaceManager) DeleteCustomRace(uuid string) error

func (*RaceManager) GetLiveFrames added in v1.2.0

func (rm *RaceManager) GetLiveFrames() ([]string, error)

func (*RaceManager) ListCustomRaces

func (rm *RaceManager) ListCustomRaces() (recent, starred, looped, scheduled []*CustomRace, err error)

func (*RaceManager) LoadServerOptions

func (rm *RaceManager) LoadServerOptions() (*GlobalServerConfig, error)

func (*RaceManager) SaveCustomRace

func (rm *RaceManager) SaveCustomRace(name string, config CurrentRaceConfig, entryList EntryList, starred bool) (*CustomRace, error)

func (*RaceManager) SaveEntrantsForAutoFill added in v1.2.0

func (rm *RaceManager) SaveEntrantsForAutoFill(entryList EntryList) error

func (*RaceManager) SaveServerOptions

func (rm *RaceManager) SaveServerOptions(so *GlobalServerConfig) error

func (*RaceManager) ScheduleRace added in v1.1.0

func (rm *RaceManager) ScheduleRace(uuid string, date time.Time, action string) error

func (*RaceManager) SetupCustomRace

func (rm *RaceManager) SetupCustomRace(r *http.Request) error

func (*RaceManager) SetupQuickRace

func (rm *RaceManager) SetupQuickRace(r *http.Request) error

func (*RaceManager) StartCustomRace

func (rm *RaceManager) StartCustomRace(uuid string, forceRestart bool) error

func (*RaceManager) ToggleLoopCustomRace

func (rm *RaceManager) ToggleLoopCustomRace(uuid string) error

func (*RaceManager) ToggleStarCustomRace

func (rm *RaceManager) ToggleStarCustomRace(uuid string) error

func (*RaceManager) UpsertLiveFrames added in v1.2.0

func (rm *RaceManager) UpsertLiveFrames(links []string) error

type Renderer

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

Renderer is the template engine.

var (
	ViewRenderer *Renderer

	Debug = os.Getenv("DEBUG") == "true"
)

func NewRenderer

func NewRenderer(loader TemplateLoader, reload bool) (*Renderer, error)

func (*Renderer) LoadTemplate

func (tr *Renderer) LoadTemplate(w http.ResponseWriter, r *http.Request, view string, data map[string]interface{}) error

LoadTemplate reads a template from templates and renders it with data to the given io.Writer

func (*Renderer) MustLoadTemplate

func (tr *Renderer) MustLoadTemplate(w http.ResponseWriter, r *http.Request, view string, data map[string]interface{})

MustLoadTemplate asserts that a LoadTemplate call must succeed or be dealt with via the http.ResponseWriter

type ScheduledEvent added in v1.2.1

type ScheduledEvent interface {
	GetID() uuid.UUID
	GetRaceSetup() CurrentRaceConfig
	GetScheduledTime() time.Time
	GetSummary() string
	GetURL() string
	GetEntryList() EntryList
}

type ServerAccountOptions added in v1.2.0

type ServerAccountOptions struct {
	IsOpen bool
}

type ServerConfig

type ServerConfig struct {
	GlobalServerConfig GlobalServerConfig `ini:"SERVER"`
	CurrentRaceConfig  CurrentRaceConfig  `ini:"SERVER"`
}

func (ServerConfig) Write

func (sc ServerConfig) Write() error

type ServerEventType added in v1.2.0

type ServerEventType string
const (
	EventTypeRace         ServerEventType = "RACE"
	EventTypeChampionship ServerEventType = "CHAMPIONSHIP"
)

type ServerExtraConfig added in v1.1.2

type ServerExtraConfig struct {
	RunOnStart []string `yaml:"run_on_start"`
}

type ServerProcess

type ServerProcess interface {
	Logs() string
	Start(cfg ServerConfig, forwardingAddress string, forwardListenPort int) error
	Stop() error
	Restart() error
	IsRunning() bool
	EventType() ServerEventType
	UDPCallback(message udp.Message)
	SendUDPMessage(message udp.Message) error

	Done() <-chan struct{}
}
var AssettoProcess ServerProcess

type SessionCar

type SessionCar struct {
	BallastKG  int           `json:"BallastKG"`
	CarID      int           `json:"CarId"`
	Driver     SessionDriver `json:"Driver"`
	Model      string        `json:"Model"`
	Restrictor int           `json:"Restrictor"`
	Skin       string        `json:"Skin"`
}

type SessionConfig

type SessionConfig struct {
	Name     string `ini:"NAME" show:"quick"`
	Time     int    `ini:"TIME" show:"quick" help:"session length in minutes"`
	Laps     int    `ini:"LAPS" show:"quick" help:"number of laps in the race"`
	IsOpen   int    `ini:"IS_OPEN" input:"checkbox" help:"0 = no join, 1 = free join, 2 = free join until 20 seconds to the green light"`
	WaitTime int    `ini:"WAIT_TIME" help:"seconds before the start of the session"`
}

type SessionDriver

type SessionDriver struct {
	GUID      string    `json:"Guid"`
	GuidsList []string  `json:"GuidsList"`
	Name      string    `json:"Name"`
	Nation    string    `json:"Nation"`
	Team      string    `json:"Team"`
	ClassID   uuid.UUID `json:"ClassID"`
}

func (*SessionDriver) AssignEntrant added in v1.2.0

func (sd *SessionDriver) AssignEntrant(entrant *Entrant, classID uuid.UUID)

type SessionEvent

type SessionEvent struct {
	CarID         int            `json:"CarId"`
	Driver        *SessionDriver `json:"Driver"`
	ImpactSpeed   float64        `json:"ImpactSpeed"`
	OtherCarID    int            `json:"OtherCarId"`
	OtherDriver   *SessionDriver `json:"OtherDriver"`
	RelPosition   *SessionPos    `json:"RelPosition"`
	Type          string         `json:"Type"`
	WorldPosition *SessionPos    `json:"WorldPosition"`
}

func (*SessionEvent) GetRelPosition

func (se *SessionEvent) GetRelPosition() string

func (*SessionEvent) GetWorldPosition

func (se *SessionEvent) GetWorldPosition() string

type SessionLap

type SessionLap struct {
	BallastKG  int       `json:"BallastKG"`
	CarID      int       `json:"CarId"`
	CarModel   string    `json:"CarModel"`
	Cuts       int       `json:"Cuts"`
	DriverGUID string    `json:"DriverGuid"`
	DriverName string    `json:"DriverName"`
	LapTime    int       `json:"LapTime"`
	Restrictor int       `json:"Restrictor"`
	Sectors    []int     `json:"Sectors"`
	Timestamp  int       `json:"Timestamp"`
	Tyre       string    `json:"Tyre"`
	ClassID    uuid.UUID `json:"ClassID"`
}

func (*SessionLap) DidCheat

func (sl *SessionLap) DidCheat(averageTime time.Duration) bool

func (*SessionLap) GetLapTime

func (sl *SessionLap) GetLapTime() time.Duration

func (*SessionLap) GetSector

func (sl *SessionLap) GetSector(x int) time.Duration

type SessionPos

type SessionPos struct {
	X float64 `json:"X"`
	Y float64 `json:"Y"`
	Z float64 `json:"Z"`
}

type SessionResult

type SessionResult struct {
	BallastKG    int           `json:"BallastKG"`
	BestLap      int           `json:"BestLap"`
	CarID        int           `json:"CarId"`
	CarModel     string        `json:"CarModel"`
	DriverGUID   string        `json:"DriverGuid"`
	DriverName   string        `json:"DriverName"`
	Restrictor   int           `json:"Restrictor"`
	TotalTime    int           `json:"TotalTime"`
	HasPenalty   bool          `json:"HasPenalty"`
	PenaltyTime  time.Duration `json:"PenaltyTime"`
	LapPenalty   int           `json:"LapPenalty"`
	Disqualified bool          `json:"Disqualified"`
	ClassID      uuid.UUID     `json:"ClassID"`
}

type SessionResults

type SessionResults struct {
	Cars           []*SessionCar    `json:"Cars"`
	Events         []*SessionEvent  `json:"Events"`
	Laps           []*SessionLap    `json:"Laps"`
	Result         []*SessionResult `json:"Result"`
	TrackConfig    string           `json:"TrackConfig"`
	TrackName      string           `json:"TrackName"`
	Type           string           `json:"Type"`
	Date           time.Time        `json:"Date"`
	SessionFile    string           `json:"SessionFile"`
	ChampionshipID string           `json:"ChampionshipID"`
}

func ListAllResults added in v1.2.0

func ListAllResults() ([]SessionResults, error)

func LoadResult

func LoadResult(fileName string) (*SessionResults, error)

func (*SessionResults) FastestLap

func (s *SessionResults) FastestLap() *SessionLap

func (*SessionResults) GetAverageLapTime

func (s *SessionResults) GetAverageLapTime(guid string) time.Duration

func (*SessionResults) GetCrashes

func (s *SessionResults) GetCrashes(guid string) int

func (*SessionResults) GetCuts

func (s *SessionResults) GetCuts(driverGuid string) int

func (*SessionResults) GetDate

func (s *SessionResults) GetDate() string

func (*SessionResults) GetDrivers

func (s *SessionResults) GetDrivers() string

func (*SessionResults) GetLaps

func (s *SessionResults) GetLaps(driverGUID string) int

func (*SessionResults) GetLastLapTime

func (s *SessionResults) GetLastLapTime(driverGuid string) time.Duration

func (*SessionResults) GetNumSectors

func (s *SessionResults) GetNumSectors() []int

func (*SessionResults) GetPosForLap

func (s *SessionResults) GetPosForLap(guid string, lapNum int64) int

lapNum is the drivers current lap

func (*SessionResults) GetTeamName

func (s *SessionResults) GetTeamName(driverGUID string) string

func (*SessionResults) GetTime

func (s *SessionResults) GetTime(timeINT int, driverGUID string, total bool) time.Duration

func (*SessionResults) IsDriversFastestLap

func (s *SessionResults) IsDriversFastestLap(guid string, time, cuts int) bool

func (*SessionResults) IsDriversFastestSector

func (s *SessionResults) IsDriversFastestSector(guid string, sector, time, cuts int) bool

func (*SessionResults) IsFastestLap

func (s *SessionResults) IsFastestLap(time, cuts int) bool

func (*SessionResults) IsFastestSector

func (s *SessionResults) IsFastestSector(sector, time, cuts int) bool

type SessionType

type SessionType string
const (
	SessionTypeBooking    SessionType = "BOOK"
	SessionTypePractice   SessionType = "PRACTICE"
	SessionTypeQualifying SessionType = "QUALIFY"
	SessionTypeRace       SessionType = "RACE"

	// SessionTypeSecondRace is a convenience const to allow for checking of
	// reversed grid positions signifying a second race.
	SessionTypeSecondRace SessionType = "RACEx2"
)

func (SessionType) String

func (s SessionType) String() string

type Sessions added in v1.2.1

type Sessions map[SessionType]SessionConfig

func (Sessions) AsSlice added in v1.2.1

func (s Sessions) AsSlice() []SessionConfig

type SteamConfig

type SteamConfig struct {
	Username       string `yaml:"username"`
	Password       string `yaml:"password"`
	InstallPath    string `yaml:"install_path"`
	ForceUpdate    bool   `yaml:"force_update"`
	ExecutablePath string `yaml:"executable_path"`
}

type Store added in v1.2.0

type Store interface {
	// Custom Races
	UpsertCustomRace(race *CustomRace) error
	FindCustomRaceByID(uuid string) (*CustomRace, error)
	ListCustomRaces() ([]*CustomRace, error)
	DeleteCustomRace(race *CustomRace) error

	// Entrants
	UpsertEntrant(entrant Entrant) error
	ListEntrants() ([]*Entrant, error)

	// Server Options
	UpsertServerOptions(so *GlobalServerConfig) error
	LoadServerOptions() (*GlobalServerConfig, error)

	// Championships
	UpsertChampionship(c *Championship) error
	ListChampionships() ([]*Championship, error)
	LoadChampionship(id string) (*Championship, error)
	DeleteChampionship(id string) error

	// Live Timings
	UpsertLiveFrames([]string) error
	ListPrevFrames() ([]string, error)

	// Meta
	SetMeta(key string, value interface{}) error
	GetMeta(key string, out interface{}) error

	// Accounts
	ListAccounts() ([]*Account, error)
	UpsertAccount(a *Account) error
	FindAccountByName(name string) (*Account, error)
	FindAccountByID(id string) (*Account, error)
	DeleteAccount(id string) error
}

func NewBoltStore added in v1.2.0

func NewBoltStore(db *bbolt.DB) Store

func NewJSONStore added in v1.2.0

func NewJSONStore(dir string) Store

type StoreConfig

type StoreConfig struct {
	Type string `yaml:"type"`
	Path string `yaml:"path"`
}

func (*StoreConfig) BuildStore

func (s *StoreConfig) BuildStore() (Store, error)

type TeamStanding

type TeamStanding struct {
	Team   string
	Points float64
}

TeamStanding is the current number of Points a Team has.

type TemplateLoader

type TemplateLoader interface {
	Init() error
	Templates(funcs template.FuncMap) (map[string]*template.Template, error)
}

func NewFilesystemTemplateLoader

func NewFilesystemTemplateLoader(dir string) TemplateLoader

type Track

type Track struct {
	Name    string
	Layouts []string
}

func ListTracks

func ListTracks() ([]Track, error)

func (*Track) LayoutsCSV

func (t *Track) LayoutsCSV() string

func (Track) PrettyName

func (t Track) PrettyName() string

type TrackInfo

type TrackInfo struct {
	Name        string      `json:"name"`
	City        string      `json:"city"`
	Country     string      `json:"country"`
	Description string      `json:"description"`
	Geotags     []string    `json:"geotags"`
	Length      json.Number `json:"length"`
	Pitboxes    json.Number `json:"pitboxes"`
	Run         string      `json:"run"`
	Tags        []string    `json:"tags"`
	Width       json.Number `json:"width"`
}

func GetTrackInfo

func GetTrackInfo(name, layout string) (*TrackInfo, error)

type TrackMapData added in v1.1.0

type TrackMapData struct {
	Width       float64 `ini:"WIDTH"`
	Height      float64 `ini:"HEIGHT"`
	Margin      float64 `ini:"MARGIN"`
	ScaleFactor float64 `ini:"SCALE_FACTOR"`
	OffsetX     float64 `ini:"X_OFFSET"`
	OffsetZ     float64 `ini:"Z_OFFSET"`
	DrawingSize float64 `ini:"DRAWING_SIZE"`
}

func LoadTrackMapData added in v1.1.0

func LoadTrackMapData(track, trackLayout string) (*TrackMapData, error)

func (*TrackMapData) Event added in v1.1.0

func (*TrackMapData) Event() udp.Event

type TrackSurfacePreset

type TrackSurfacePreset struct {
	Name            string
	Description     string
	SessionStart    int
	SessionTransfer int
	Randomness      int
	LapGain         int
}

type Tyres

type Tyres map[string]map[string]string

func ListTyres

func ListTyres() (Tyres, error)

ListTyres reads tyres from the TyreFiles and returns them as a map of car => tyre short name => tyre long name

func (Tyres) Name

func (t Tyres) Name(search string, cars []string) string

type Weather

type Weather map[string]string

func ListWeather

func ListWeather() (Weather, error)

type WeatherConfig

type WeatherConfig struct {
	Graphics               string `ini:"GRAPHICS" help:"exactly one of the folder names that you find in the 'content\\weather'' directory"`
	BaseTemperatureAmbient int    `ini:"BASE_TEMPERATURE_AMBIENT" help:"ambient temperature"` // 0-36
	BaseTemperatureRoad    int    ``                                                          // 0-36
	/* 215-byte string literal not displayed */
	VariationAmbient int `` /* 130-byte string literal not displayed */
	VariationRoad    int `ini:"VARIATION_ROAD" help:"variation of the road's temperature. Like the ambient one"`

	CMGraphics          string `ini:"__CM_GRAPHICS" help:"Graphics folder name"`
	CMWFXType           int    `ini:"__CM_WFX_TYPE" help:"Weather ini file number, inside weather.ini"`
	CMWFXUseCustomTime  int    `ini:"__CM_WFX_USE_CUSTOM_TIME" help:"If Sol is active then this should be too"`
	CMWFXTime           int    `ini:"__CM_WFX_TIME" help:"Seconds after 12 noon, usually leave at 0 and use unix timestamp instead"`
	CMWFXTimeMulti      int    `ini:"__CM_WFX_TIME_MULT" help:"Time speed multiplier, default to 1x"`
	CMWFXUseCustomDate  int    `ini:"__CM_WFX_USE_CUSTOM_DATE" help:"If Sol is active then this should be too"`
	CMWFXDate           int    `ini:"__CM_WFX_DATE" help:"Unix timestamp (UTC + 10)"`
	CMWFXDateUnModified int    `ini:"__CM_WFX_DATE_UNMODIFIED" help:"Unix timestamp (UTC + 10), without multiplier correction"`
}

func (WeatherConfig) TrimName

func (w WeatherConfig) TrimName(name string) string

func (WeatherConfig) UnixToTime

func (w WeatherConfig) UnixToTime(unix int) time.Time

Directories

Path Synopsis
cmd
server-manager command
pkg
acd
This code would not have been possible without the two following projects: * AcTools (and Content Manager) - https://github.com/gro-ove/actools - Licensed under the Microsoft Public License (Ms-PL) * Luigi Auriemma's QuickBMS, specifically the "Assetto Corsa ACD" script.
This code would not have been possible without the two following projects: * AcTools (and Content Manager) - https://github.com/gro-ove/actools - Licensed under the Microsoft Public License (Ms-PL) * Luigi Auriemma's QuickBMS, specifically the "Assetto Corsa ACD" script.
udp

Jump to

Keyboard shortcuts

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