mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 19:11:08 +00:00
fix: find Steam libraries whose installs have no appmanifest
This commit is contained in:
1 parent
9f6c73442b
commit
be5f1560b2
3 files changed
+50
-2
No files matched your search
@@ -186,6 +186,9 @@ object AddedGames {
|
||||
|
||||
private fun entryFolders(context: Context): Set<String> = AddedExes.list(context).map { it.folder }.toSet()
|
||||
|
||||
private fun libraryDepotInstalls(context: Context): List<File> =
|
||||
SteamLibraries.list(context).flatMap { SteamLibraries.depotInstalls(File(it.path, "steamapps/common")) }
|
||||
|
||||
internal fun isSteamLibraryFolder(name: String): Boolean =
|
||||
name.equals("steamapps", ignoreCase = true) || name == com.droiddeck.launcher.session.GameStorage.X64_CARD_DIR
|
||||
|
||||
@@ -213,6 +216,7 @@ object AddedGames {
|
||||
if (folder.path in removed || !folder.isDirectory) continue
|
||||
scanGame(context, folder, out, single = entry)
|
||||
}
|
||||
for (folder in libraryDepotInstalls(context)) if (folder.path !in removed) scanGame(context, folder, out)
|
||||
for (folder in StoreInstallRoot.gameFolders(context)) if (StoreInstallRoot.isFinished(folder)) scanGame(context, folder, out)
|
||||
for (game in com.droiddeck.launcher.runtime.BattleNet.games(context)) {
|
||||
if (game.folder.path !in removed) com.droiddeck.launcher.runtime.BattleNet.shortcut(context, game)?.let(out::add)
|
||||
@@ -259,6 +263,7 @@ object AddedGames {
|
||||
entries.map { File(it.folder) }.filter(::owns).maxByOrNull { canonical(it).length }?.let { return it }
|
||||
SessionPrefs.removedAddedGames(context).map { File(it) }.filter { owns(it) && groupGames(it) == null }.maxByOrNull { canonical(it).length }?.let { return it }
|
||||
StoreInstallRoot.gameFolders(context).firstOrNull(::holds)?.let { return it }
|
||||
libraryDepotInstalls(context).firstOrNull(::holds)?.let { return it }
|
||||
val removed = SessionPrefs.removedAddedGames(context)
|
||||
val dirs = listOfNotNull(
|
||||
GameStorage.effective(context)?.let { File(it.path, "steamapps/common") },
|
||||
@@ -376,6 +381,7 @@ object AddedGames {
|
||||
}
|
||||
AddedExes.list(context).filter { it.folder !in removed }.forEach { out.add(canonical(File(it.folder))) }
|
||||
StoreInstallRoot.gameFolders(context).forEach { out.add(canonical(it)) }
|
||||
libraryDepotInstalls(context).filter { it.path !in removed }.forEach { out.add(canonical(it)) }
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
@@ -126,8 +126,20 @@ object SteamLibraries {
|
||||
return out
|
||||
}
|
||||
|
||||
internal fun gameCount(library: File): Int =
|
||||
File(library, "steamapps").list()?.count { it.startsWith("appmanifest_") && it.endsWith(".acf") } ?: 0
|
||||
internal fun gameCount(library: File): Int {
|
||||
val steamapps = File(library, "steamapps")
|
||||
val manifests = steamapps.list()?.count { it.startsWith("appmanifest_") && it.endsWith(".acf") } ?: return 0
|
||||
return manifests + depotInstalls(File(steamapps, "common")).size
|
||||
}
|
||||
|
||||
/** Finished downloads another client left without a Steam manifest; the importer registers them from depot.config. */
|
||||
fun depotInstalls(common: File): List<File> {
|
||||
val managed = AddedGames.steamInstallDirs(common)
|
||||
return common.listFiles { f ->
|
||||
f.isDirectory && f.name.lowercase() !in managed &&
|
||||
File(f, ".download_complete").isFile && File(f, ".DepotDownloader/depot.config").isFile
|
||||
}.orEmpty().sortedBy { it.name.lowercase() }
|
||||
}
|
||||
|
||||
fun rename(context: Context, id: String, label: String) {
|
||||
val name = clean(label).takeIf { it.isNotEmpty() } ?: return
|
||||
|
||||
@@ -89,6 +89,36 @@ class SteamLibrariesTest {
|
||||
assertEquals(setOf(shallow, deep), withGames.toSet())
|
||||
}
|
||||
|
||||
private fun depotInstall(common: File, name: String, complete: Boolean = true): File = File(common, name).apply {
|
||||
File(this, ".DepotDownloader").mkdirs()
|
||||
File(this, ".DepotDownloader/depot.config").writeText("""{"installedManifestIDs":{"43":99}}""")
|
||||
File(this, "$name.exe").writeBytes(ByteArray(4))
|
||||
if (complete) File(this, ".download_complete").writeText("")
|
||||
}
|
||||
|
||||
@Test fun finishedDownloadsWithoutManifestsCountAsGames() {
|
||||
val steam = File(tmp.newFolder("card"), "Other/Steam")
|
||||
val common = File(steam, "steamapps/common").apply { mkdirs() }
|
||||
assertEquals(0, SteamLibraries.gameCount(steam))
|
||||
val done = depotInstall(common, "Done")
|
||||
depotInstall(common, "Partial", complete = false)
|
||||
depotInstall(common, "Managed")
|
||||
File(steam, "steamapps/appmanifest_42.acf").writeText("\"AppState\"\n{\n\t\"installdir\"\t\t\"Managed\"\n}\n")
|
||||
assertEquals(listOf(done), SteamLibraries.depotInstalls(common))
|
||||
assertEquals(2, SteamLibraries.gameCount(steam))
|
||||
assertEquals(steam, SteamLibraries.innerLibrary(steam.parentFile))
|
||||
}
|
||||
|
||||
@Test fun addedLibrariesImportFinishedDownloadsWithoutManifests() {
|
||||
SessionPrefs.setGameStorage(app, SessionPrefs.GAME_STORAGE_OFF, "")
|
||||
val steam = tmp.newFolder("Steam")
|
||||
val game = depotInstall(File(steam, "steamapps/common"), "Game")
|
||||
val lib = added(steam.path)
|
||||
val scanned = AddedGames.scan(app).single()
|
||||
assertEquals(game, scanned.folder)
|
||||
assertEquals("${lib.guest}/steamapps/common/Game", AddedGames.guestPath(app, scanned.folder))
|
||||
}
|
||||
|
||||
@Test fun unreadableOrInvalidEntriesAreDropped() {
|
||||
assertTrue(SteamLibraries.parse("{oops").isEmpty())
|
||||
assertEquals(listOf("2"), SteamLibraries.parse("""[{"id":"../x","path":"/a"},{"id":"2","path":"/b","label":""}]""").map { it.id })
|
||||
|
||||
Reference in new issue
Block a user