diff --git a/internal/presets/savestats.go b/internal/presets/savestats.go index f6de67cc..7ef2fa3c 100644 --- a/internal/presets/savestats.go +++ b/internal/presets/savestats.go @@ -152,6 +152,12 @@ func measureOne(path string, deadline time.Time) (count int, bytes int64, latest if d.IsDir() { return nil } + // Not part of any save (Steam's remotecache.vdf): a folder holding + // only that is a game Steam knows of, not a save, and was tracked as + // one — twenty-odd games with nothing to sync. + if delta.NeverSynced(d.Name()) { + return nil + } fi, err := d.Info() if err != nil { return nil diff --git a/internal/presets/savestats_test.go b/internal/presets/savestats_test.go index 1d8b544d..8f7d5e41 100644 --- a/internal/presets/savestats_test.go +++ b/internal/presets/savestats_test.go @@ -211,3 +211,17 @@ func TestMeasure_FolderHoldingOnlyAJunctionIsEmpty(t *testing.T) { saves[0].FileCount) } } + +// A Steam userdata folder holding only Steam's own remotecache.vdf is not a +// save: measured, it is empty, and so it is never offered as a new game. +func TestMeasure_OnlyLauncherFilesIsEmpty(t *testing.T) { + dir := t.TempDir() + if err := os.WriteFile(filepath.Join(dir, "remotecache.vdf"), []byte("steam"), 0o666); err != nil { + t.Fatal(err) + } + saves := []DiscoveredSave{{SavePath: dir}} + Measure(saves) + if !saves[0].IsEmpty() { + t.Errorf("measured %d file(s): a folder of Steam's bookkeeping counts as a save", saves[0].FileCount) + } +}