Documentation
¶
Overview ¶
Package library keeps Seaglass's game library: what scans found, merged with what the user set (favorites, hidden, titles, controller mode, playtime). It lives in memory and is saved as one JSON file with atomic writes; even thousands of games stay a few megabytes.
Index ¶
- Variables
- func CleanCollections(names []string) []string
- func OwnedKey(store, id string) string
- type Found
- type Game
- type Meta
- type Owned
- type Store
- func (s *Store) ApplyOwned(store string, list []Owned, now time.Time) (added, removed int)
- func (s *Store) ApplyScan(found []Found, now time.Time) (added, removed int)
- func (s *Store) Flush() error
- func (s *Store) ForgetOwned(store string) int
- func (s *Store) Games() []Game
- func (s *Store) Get(id int64) (Game, bool)
- func (s *Store) RenameCollection(old, name string) []int64
- func (s *Store) SetPlayed(fn func(g *Game) (playtime, lastPlayed int64, ok bool)) []int64
- func (s *Store) Update(id int64, fn func(g *Game)) (Game, error)
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("game not found")
ErrNotFound means no game has that id.
Functions ¶
func CleanCollections ¶
CleanCollections tidies collection names: spaces trimmed and collapsed, overlong names cut, empty ones and repeats (in any case) dropped, the first spelling kept.
Types ¶
type Found ¶
type Found struct {
Key, Title, SortTitle string
Source, SourceLabel string
External bool
Emulator, Repacker, DRMFree string
EmuDir string
Dir, Exe, Args, WorkDir string
LaunchURI string
SizeBytes int64
SteamAppID int
GogID, EpicApp string
How, MatchHow string
Confidence int
NeedsReview bool
StorePlaytime int64
StoreLastPlayed int64
PadHint string
}
Found is one game a scan found, already identified.
type Game ¶
type Game struct {
ID int64 `json:"id"`
Key string `json:"key"` // identity: the install folder, lower-cased
Title string `json:"title"`
CustomTitle string `json:"customTitle,omitempty"`
SortTitle string `json:"sortTitle"`
Source string `json:"source"` // steam, epic, gog, ea, ubisoft, battlenet, xbox, installer, shortcut, folder
SourceLabel string `json:"sourceLabel"` // "Steam", "External · RUNE", "Repack · DODI", …
External bool `json:"external"`
Emulator string `json:"emulator,omitempty"`
EmuDir string `json:"emuDir,omitempty"` // where the emulator sits, relative to Dir
Repacker string `json:"repacker,omitempty"`
DRMFree string `json:"drmFree,omitempty"`
Installed bool `json:"installed"`
PadHint string `json:"padHint,omitempty"` // the game ships libScePad or SDL
Dir string `json:"dir"`
Exe string `json:"exe,omitempty"`
Args string `json:"args,omitempty"`
WorkDir string `json:"workDir,omitempty"`
LaunchURI string `json:"launchUri,omitempty"`
UserExe bool `json:"userExe,omitempty"` // the user picked the executable; scans leave it alone
Owned bool `json:"owned,omitempty"` // a connected store account owns it
InstallURI string `json:"installUri,omitempty"` // asks the store to install it
SizeBytes int64 `json:"sizeBytes,omitempty"`
SteamAppID int `json:"steamAppId,omitempty"`
MetaAppID int `json:"metaAppId,omitempty"` // Steam app found by a store search, used only for metadata
GogID string `json:"gogId,omitempty"`
EpicApp string `json:"epicApp,omitempty"`
How string `json:"how"` // how the game was found
MatchHow string `json:"matchHow"` // how its identity was established
Confidence int `json:"confidence"` // 0–100
NeedsReview bool `json:"needsReview"`
Confirmed bool `json:"confirmed,omitempty"` // the user confirmed the match
AddedAt int64 `json:"addedAt"` // unix seconds
Initial bool `json:"initial,omitempty"` // found by the very first scan, so not a "new" find
SeenAt int64 `json:"seenAt"`
LastPlayed int64 `json:"lastPlayed,omitempty"`
Playtime int64 `json:"playtime,omitempty"` // seconds, tracked by Seaglass
// What the store recorded (Steam), refreshed by every scan. The
// interface shows whichever of the two is larger.
StorePlaytime int64 `json:"storePlaytime,omitempty"`
StoreLastPlayed int64 `json:"storeLastPlayed,omitempty"`
Favorite bool `json:"favorite,omitempty"`
Hidden bool `json:"hidden,omitempty"`
PadMode string `json:"padMode,omitempty"` // "" = auto, "native", "steam"
// Collections are the user's own groups ("Co-op", "Finished"); a game
// can be in several.
Collections []string `json:"collections,omitempty"`
Meta *Meta `json:"meta,omitempty"`
}
Game is one game in the library.
func (*Game) DisplayTitle ¶
DisplayTitle is the user's title if set, else the found one.
func (*Game) IsOwnedOnly ¶
IsOwnedOnly reports whether a game is only known from an account (it was never found on this PC).
type Meta ¶
type Meta struct {
Description string `json:"description,omitempty"`
Developers []string `json:"developers,omitempty"`
Publishers []string `json:"publishers,omitempty"`
Genres []string `json:"genres,omitempty"`
ReleaseDate string `json:"releaseDate,omitempty"`
ReleaseYear int `json:"releaseYear,omitempty"`
DualSense string `json:"dualSense,omitempty"` // "yes", "no", "" (unknown)
Controller string `json:"controller,omitempty"`
Cover string `json:"cover,omitempty"` // local art URLs (/art/…)
Hero string `json:"hero,omitempty"`
Backdrop string `json:"backdrop,omitempty"` // 16:9 full-screen background
Tile string `json:"tile,omitempty"` // square: key art with the logo
Logo string `json:"logo,omitempty"`
Icon string `json:"icon,omitempty"`
Accent string `json:"accent,omitempty"` // CSS colour from the art
FetchedAt int64 `json:"fetchedAt,omitempty"`
Source string `json:"source,omitempty"` // where the metadata came from
Version int `json:"version,omitempty"` // meta.Version that fetched it
ArtOverrides []string `json:"artOverrides,omitempty"`
}
Meta is store metadata and art, filled in by the metadata service.
type Owned ¶
type Owned struct {
Store string // steam, gog, epic
ID string // the store's id: Steam app id, GOG product id, Epic app name
Title string
SortTitle string
InstallURI string // asks the store to install it
Playtime int64 // seconds the store recorded
LastPlayed int64 // unix seconds
}
Owned is a game an account owns, from a store (Steam, GOG, Epic).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the library. Safe for concurrent use.
func Open ¶
Open loads the library at path, or starts an empty one. A damaged file is kept aside and the copy saved at the previous start (path.bak) is used instead, when there is one.
func (*Store) ApplyOwned ¶
ApplyOwned merges one store's owned games. A game already in the library (found on this PC, installed or not anymore) is marked owned and gets the install link; other games are added as owned-only, not installed. Owned-only games the account no longer lists are removed, and so is the mark this store gave a found game the account no longer lists.
func (*Store) ApplyScan ¶
ApplyScan merges a scan into the library. Found games are added or refreshed; games no longer found are kept (with their playtime) but marked not installed. User choices are never overwritten.
func (*Store) ForgetOwned ¶
ForgetOwned removes a store's owned-only games and the owned mark it gave the others, whatever their source (the account was disconnected).
func (*Store) RenameCollection ¶
RenameCollection renames a collection in every game that's in it (in any case); an empty name removes the collection. It returns the games that changed.