scan

package
v1.7.1 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: AGPL-3.0 Imports: 28 Imported by: 0

Documentation

Overview

Package scan finds installed games on this PC: store installs, installer entries (repacks), shortcuts and plain game folders, and recognises unofficial copies (Steam emulators, cracks) and the Steam app they are.

Index

Constants

View Source
const UplayEmu = "Uplay emulator"

UplayEmu is the name shown for a Ubisoft game running on a Uplay emulator.

Variables

This section is empty.

Functions

func Aliases

func Aliases(s string) []string

Aliases writes out a folder name in the ways it's commonly shortened: a known short name ("SkyrimSE", "L4D2"), a shortened first word ("AC Valhalla", "MHWilds") or a shortened edition ("Mafia 2 DE"). Nothing when there's nothing to write out.

func AutoFolders

func AutoFolders() []string

AutoFolders are common places repacks and standalone games install to, on every fixed drive, that exist on this PC.

func CleanTitle

func CleanTitle(s string) string

CleanTitle turns an installer or folder name into a game title: "Baldurs.Gate.3-RUNE" → "Baldurs Gate 3", "Hades [FitGirl Repack]" → "Hades", "Elden.Ring.v1.10-FitGirl" → "Elden Ring".

func EpicManifestDir

func EpicManifestDir() string

EpicManifestDir is where the Epic Games Launcher records installed games.

func ExpandAbbrev

func ExpandAbbrev(s string) string

ExpandAbbrev writes out a title that starts with a well-known abbreviation: "GTA V" → "Grand Theft Auto V", "RDR2" → "Red Dead Redemption 2". Other titles come back as they are.

func LooseKey

func LooseKey(s string) string

LooseKey is a more forgiving Normalize for names that don't match exactly, as folder names often don't: apostrophes, possessive and plural s, Roman numerals, a leading "The" and a leading brand ("Marvel's") don't count, so "Assassin Creed Black Flag Resynced" and "Assassin's Creed: Black Flag Resynced" get the same key, as do "Baldurs Gate III" and "Baldur's Gate 3".

func Normalize

func Normalize(s string) string

Normalize keeps only letters and digits (any script), lower-cased, so "Game™: Edition" and "game edition" compare equal.

func NotAGame

func NotAGame(title string) bool

NotAGame reports whether a name is a folder or app that isn't a game ("Tools", "Discord", "Steam"), so it's never matched or looked up.

func PickExe

func PickExe(dir, title string) string

PickExe chooses the executable that most likely starts the game in dir. Unlike picking the process the game ends up running as, launching prefers Unreal's small bootstrapper in the root over the Shipping binary, since the bootstrapper passes the right arguments along.

func SortTitle

func SortTitle(s string) string

SortTitle drops leading articles so "The Sims 4" sorts under S.

func SteamAccounts

func SteamAccounts(root string) []string

SteamAccounts returns the userdata folder of the account Steam uses on this PC: the one signed in now, else the one that signs in automatically, else the last one used. All known accounts if unsure.

func SteamDir

func SteamDir() string

SteamDir returns Steam's install folder ("" if Steam isn't installed), with the capitalisation the file system uses (Steam keeps it lower-cased in the registry).

func SteamLibraries

func SteamLibraries(root string) []string

SteamLibraries returns Steam's own folder plus every library folder listed in its libraryfolders.vdf.

func SteamWatchDirs

func SteamWatchDirs() []string

SteamWatchDirs are the folders whose changes mean Steam installed or removed something.

func StripEdition

func StripEdition(s string) string

StripEdition drops an edition from a title: "The Witcher 3: Wild Hunt - Complete Edition" → "The Witcher 3: Wild Hunt".

func WithoutRemake added in v1.7.0

func WithoutRemake(s string) string

WithoutRemake drops "Remake" from the end of a title: stores sell most remakes under the plain name ("Resident Evil 4 Remake" is "Resident Evil 4" on Steam, the original "Resident Evil 4 (2005)"). "" when there's none. It's a last try: some remakes do keep the word.

Types

type Candidate

type Candidate struct {
	Title        string // as the source names it
	TitleTrusted bool   // the title comes from a store or installer record, not a folder name
	Dir          string // install folder
	Exe          string // executable that starts the game ("" when a LaunchURI does)
	Args         string
	WorkDir      string
	LaunchURI    string // store link that starts the game (steam://rungameid/…)
	Source       Source
	How          string // human-readable: how it was found

	SteamAppID int
	GogID      string
	EpicApp    string // namespace:catalogItem:appName
	UbisoftID  string

	Publisher string // from the installer entry
	Repacker  string // "DODI", "FitGirl", … when a repacker installed it
	SizeBytes int64

	// Playtime the store recorded (Steam's localconfig.vdf).
	StorePlaytime   int64 // seconds
	StoreLastPlayed int64 // unix seconds

	Emulator  string // "RUNE", "CODEX", "Goldberg", … ; "" when none was found
	EmuMarker string // the file that gave it away
	EmuDir    string // folder (relative to Dir) where the marker or steam_settings was found
	AppIDFrom string // file the Steam AppID was read from (unofficial copies)
	DRMFree   string // "GOG" when a GOG game info file was found outside a GOG install
	PadHint   string // "libScePad" or "SDL": the game handles a DualSense itself
}

Candidate is one game found on this PC.

func (*Candidate) Unofficial

func (c *Candidate) Unofficial() bool

Unofficial reports whether the copy runs on an emulator or was installed by a repacker.

type Emulation

type Emulation struct {
	Emulator  string // "RUNE", "Goldberg", …; "" when the copy looks official
	Marker    string // the file that gave it away
	AppID     int    // Steam app id the emulator is set up as
	AppIDFrom string
	Gog       *gogInfo // a GOG game info file, when present
	GogFile   string
	PadHint   string // "libScePad" (Sony's DualSense library) or "SDL" when the game ships one
	// EmuDir is the folder, relative to the game folder, where the emulator
	// marker (or steam_settings) was found; "." for the game folder itself.
	EmuDir string
}

Emulation is what unofficial-copy detection found in a game folder.

func DetectEmulation

func DetectEmulation(dir string, signed func(string) bool) Emulation

DetectEmulation looks through a game folder for Steam emulators, cracks and GOG game info files. signed reports whether a DLL carries a valid signature; nil skips that check.

type Options

type Options struct {
	Folders          []string // watched folders from Settings
	AutoFolders      bool     // also look in common game folders on every drive
	DetectUnofficial bool     // look for Steam emulators and cracks in game folders
	Signed           func(path string) bool
}

Options control a scan.

type Result

type Result struct {
	Games    []Candidate
	Took     time.Duration
	PerStore map[Source]int
}

Result is one scan's outcome.

func Run

func Run(ctx context.Context, o Options) Result

Run scans this PC. Every source is best-effort: one failing never stops the others.

type Source

type Source string

Source is where a game was found.

const (
	Steam     Source = "steam"
	Epic      Source = "epic"
	GOG       Source = "gog"
	EA        Source = "ea"
	Ubisoft   Source = "ubisoft"
	BattleNet Source = "battlenet"
	Xbox      Source = "xbox"
	Installer Source = "installer" // a Windows uninstall entry (repacks, standalone installers)
	Shortcut  Source = "shortcut"  // a desktop or Start menu shortcut
	Folder    Source = "folder"    // a subfolder of a watched folder
)

func (Source) Store

func (s Source) Store() bool

Store reports whether s is a store's own library.

type SteamStat

type SteamStat struct {
	Playtime   int64 // seconds
	LastPlayed int64 // unix seconds
}

SteamStat is what Steam recorded for one game.

Jump to

Keyboard shortcuts

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