library

package
v1.9.1 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: AGPL-3.0 Imports: 11 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("game not found")

ErrNotFound means no game has that id.

Functions

func CleanCollections

func CleanCollections(names []string) []string

CleanCollections tidies collection names: spaces trimmed and collapsed, overlong names cut, empty ones and repeats (in any case) dropped, the first spelling kept.

func OwnedKey

func OwnedKey(store, id string) string

OwnedKey is the library key of an owned-only game.

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

func (g *Game) DisplayTitle() string

DisplayTitle is the user's title if set, else the found one.

func (*Game) IsOwnedOnly

func (g *Game) IsOwnedOnly() bool

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
	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

func Open(path string) (*Store, error)

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

func (s *Store) ApplyOwned(store string, list []Owned, now time.Time) (added, removed int)

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

func (s *Store) ApplyScan(found []Found, now time.Time) (added, removed int)

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) Flush

func (s *Store) Flush() error

Flush writes the library to disk now.

func (*Store) ForgetOwned

func (s *Store) ForgetOwned(store string) int

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) Games

func (s *Store) Games() []Game

Games returns copies of all games, sorted by title.

func (*Store) Get

func (s *Store) Get(id int64) (Game, bool)

Get returns a copy of one game.

func (*Store) RenameCollection

func (s *Store) RenameCollection(old, name string) []int64

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.

func (*Store) SetPlayed added in v1.8.0

func (s *Store) SetPlayed(fn func(g *Game) (playtime, lastPlayed int64, ok bool)) []int64

SetPlayed sets each game's playtime and last play to what fn returns (ok false leaves the game alone) and returns the games that changed.

func (*Store) Update

func (s *Store) Update(id int64, fn func(g *Game)) (Game, error)

Update changes one game and schedules a save.

Jump to

Keyboard shortcuts

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