mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
fix: review fixes for the x86-64 Steam client
- The library cache is saved only by the newest scan, like the list it feeds. - A session records the Steam client it ran (steam-client.txt), and an abandoned session's Steam logs are copied from that client. - Console logs from the same game and mod in two libraries get distinct names in the VAC report. - Client CPU pinning also recognises FEXInterpreter as the launcher. - pl, ru, uk, cs, bg: the VAC hint names the game as what is protected.
This commit is contained in:
1 parent
a53fd11779
commit
eb8634ea22
13 files changed
+66
-12
No files matched your search
@@ -1926,7 +1926,7 @@ class MainActivity : ComponentActivity() {
|
||||
val scannedX64 = scannedArch == "x86_64"
|
||||
val games = if (ready) Library.launchableGames(this, arch = scannedArch) else emptyList()
|
||||
val all = games.distinctBy { it.gameId }
|
||||
if (ready) com.droiddeck.launcher.frontend.LibraryCache.save(this, all, scannedX64)
|
||||
if (ready && scanGeneration == libraryScanGeneration) com.droiddeck.launcher.frontend.LibraryCache.save(this, all, scannedX64)
|
||||
val endedSession = SessionState.sessionId.takeIf { !SessionState.running && it != null && it != componentSweepSession }
|
||||
if (ready && (!componentSweepDone || endedSession != null)) {
|
||||
componentSweepDone = true
|
||||
|
||||
@@ -188,6 +188,16 @@ object SessionArtifacts {
|
||||
return record
|
||||
}
|
||||
|
||||
private const val CLIENT_FILE = "steam-client.txt"
|
||||
|
||||
fun recordClient(dir: File, arch: String) {
|
||||
runCatching { File(dir, CLIENT_FILE).writeText("$arch\n") }
|
||||
}
|
||||
|
||||
/** The Steam client a session ran, when it recorded one. */
|
||||
internal fun recordedClient(dir: File): String? =
|
||||
runCatching { File(dir, CLIENT_FILE).readText().trim() }.getOrNull()?.takeIf { it == "arm64" || it == "x86_64" }
|
||||
|
||||
private fun copySteamLogs(context: Context, dir: File, record: Record, steamArch: String? = null) {
|
||||
val logs = File(steamArch?.let { SessionPrefs.steamRoot(context, it) } ?: SessionPrefs.activeSteamRoot(context), "logs")
|
||||
if (!logs.isDirectory) return
|
||||
@@ -231,7 +241,7 @@ object SessionArtifacts {
|
||||
)
|
||||
val record = Record(dir)
|
||||
if (newest) {
|
||||
copySteamLogs(context, dir, record)
|
||||
copySteamLogs(context, dir, record, recordedClient(dir))
|
||||
VacDiagnostics.collect(context, dir)
|
||||
}
|
||||
SessionLogCapture.dumpCrashBuffer(File(dir, "crash.log"))
|
||||
|
||||
@@ -587,7 +587,10 @@ class SessionService : Service() {
|
||||
guest.add("GLIBC_TUNABLES=glibc.pthread.rseq=0:glibc.malloc.top_pad=16777216")
|
||||
if (SessionState.mode == MODE_STEAM) guest.add("BL_MANGOAPP=" + (if (SessionPrefs.mangoapp(this)) "1" else "0"))
|
||||
SessionState.steamClientArch = if (steamHere) SessionPrefs.steamClientArch(this) else null
|
||||
SessionState.steamClientArch?.let { guest.add("BL_STEAM_CLIENT_ARCH=$it") }
|
||||
SessionState.steamClientArch?.let { arch ->
|
||||
guest.add("BL_STEAM_CLIENT_ARCH=$arch")
|
||||
SessionPaths.current()?.let { SessionArtifacts.recordClient(it, arch) }
|
||||
}
|
||||
if (SessionState.mode == MODE_STEAM) {
|
||||
guest.add("BL_GAMESCOPE_STRETCH_16X9=" + (if (SessionPrefs.stretch16x9(this)) "1" else "0"))
|
||||
}
|
||||
|
||||
@@ -103,8 +103,9 @@ object VacDiagnostics {
|
||||
report.appendLine(" No console.log was written this session. Only Source-engine games write one,")
|
||||
report.appendLine(" and only when started with -condebug (this setting adds it).")
|
||||
}
|
||||
consoles.forEach { log ->
|
||||
val name = consoleName(log)
|
||||
val names = consoleNames(consoles)
|
||||
consoles.forEachIndexed { i, log ->
|
||||
val name = names[i]
|
||||
val lines = tail(log, armedSizes[canonical(log)] ?: 0L)
|
||||
File(out, "$name-console.log").bufferedWriter().use { w ->
|
||||
lines.forEach { w.write(LogRedactor.redact(it)); w.newLine() }
|
||||
@@ -173,6 +174,15 @@ object VacDiagnostics {
|
||||
return roots.filter { it.isDirectory }.distinctBy { runCatching { it.canonicalPath }.getOrDefault(it.path) }
|
||||
}
|
||||
|
||||
/** Two libraries can hold the same game and mod folder; a repeated name takes a tag from the log's path. */
|
||||
internal fun consoleNames(logs: List<File>): List<String> {
|
||||
val used = HashSet<String>()
|
||||
return logs.map { log ->
|
||||
val base = consoleName(log)
|
||||
if (used.add(base)) base else "$base-%08x".format(canonical(log).hashCode()).also { used.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun consoleName(log: File): String {
|
||||
val mod = log.parentFile
|
||||
val game = mod?.parentFile?.let { if (it.name == "game") it.parentFile else it }
|
||||
|
||||
@@ -2341,7 +2341,7 @@
|
||||
<string name="mode_client_arch_arm64">ARM64</string>
|
||||
<string name="mode_client_arch_x64">x86-64</string>
|
||||
<string name="setup_vac_diag">Диагностика на VAC</string>
|
||||
<string name="setup_vac_diag_hint">Игрите на Source записват конзолата си (-condebug); vac.txt в дневниците на сесията показва дали е защитено или не</string>
|
||||
<string name="setup_vac_diag_hint">Игрите на Source записват конзолата си (-condebug); vac.txt в дневниците на сесията показва дали играта е защитена от VAC</string>
|
||||
<string name="load_starting_steam_x64">Стартиране на Steam x86-64</string>
|
||||
<string name="storage_game_x64">%1$s · x86-64</string>
|
||||
<string name="storage_tool_x64_client">Използва се от клиента на Steam x86-64</string>
|
||||
|
||||
@@ -2391,7 +2391,7 @@
|
||||
<string name="mode_client_arch_arm64">ARM64</string>
|
||||
<string name="mode_client_arch_x64">x86-64</string>
|
||||
<string name="setup_vac_diag">Diagnostika VAC</string>
|
||||
<string name="setup_vac_diag_hint">Hry na Source zaznamenávají svou konzoli (-condebug); vac.txt v protokolech relace uvádí, zda je zabezpečeno, nebo ne</string>
|
||||
<string name="setup_vac_diag_hint">Hry na Source zaznamenávají svou konzoli (-condebug); vac.txt v protokolech relace uvádí, zda je hra chráněna VAC</string>
|
||||
<string name="load_starting_steam_x64">Spouštění Steamu x86-64</string>
|
||||
<string name="storage_game_x64">%1$s · x86-64</string>
|
||||
<string name="storage_tool_x64_client">Používá klient Steam x86-64</string>
|
||||
|
||||
@@ -2391,7 +2391,7 @@
|
||||
<string name="mode_client_arch_arm64">ARM64</string>
|
||||
<string name="mode_client_arch_x64">x86-64</string>
|
||||
<string name="setup_vac_diag">Diagnostyka VAC</string>
|
||||
<string name="setup_vac_diag_hint">Gry na Source zapisują swoją konsolę (-condebug); vac.txt w logach sesji pokazuje, czy jest zabezpieczone</string>
|
||||
<string name="setup_vac_diag_hint">Gry na Source zapisują swoją konsolę (-condebug); vac.txt w logach sesji pokazuje, czy gra jest chroniona przez VAC</string>
|
||||
<string name="load_starting_steam_x64">Uruchamianie Steam x86-64</string>
|
||||
<string name="storage_game_x64">%1$s · x86-64</string>
|
||||
<string name="storage_tool_x64_client">Używane przez klienta Steam x86-64</string>
|
||||
|
||||
@@ -2385,7 +2385,7 @@
|
||||
<string name="mode_client_arch_arm64">ARM64</string>
|
||||
<string name="mode_client_arch_x64">x86-64</string>
|
||||
<string name="setup_vac_diag">Диагностика VAC</string>
|
||||
<string name="setup_vac_diag_hint">Игры на Source записывают консоль (-condebug); vac.txt в журналах сессии показывает, защищено или нет</string>
|
||||
<string name="setup_vac_diag_hint">Игры на Source записывают консоль (-condebug); vac.txt в журналах сессии показывает, защищена ли игра VAC</string>
|
||||
<string name="load_starting_steam_x64">Запуск Steam x86-64</string>
|
||||
<string name="storage_game_x64">%1$s · x86-64</string>
|
||||
<string name="storage_tool_x64_client">Используется клиентом Steam x86-64</string>
|
||||
|
||||
@@ -2391,7 +2391,7 @@
|
||||
<string name="mode_client_arch_arm64">ARM64</string>
|
||||
<string name="mode_client_arch_x64">x86-64</string>
|
||||
<string name="setup_vac_diag">Діагностика VAC</string>
|
||||
<string name="setup_vac_diag_hint">Ігри на Source записують свою консоль (-condebug); vac.txt у журналах сеансу показує, захищено чи ні</string>
|
||||
<string name="setup_vac_diag_hint">Ігри на Source записують свою консоль (-condebug); vac.txt у журналах сеансу показує, чи захищена гра VAC</string>
|
||||
<string name="load_starting_steam_x64">Запуск Steam x86-64</string>
|
||||
<string name="storage_game_x64">%1$s · x86-64</string>
|
||||
<string name="storage_tool_x64_client">Використовується клієнтом Steam x86-64</string>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.droiddeck.launcher.session
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
class SessionClientRecordTest {
|
||||
@get:Rule val tmp = TemporaryFolder()
|
||||
|
||||
@Test fun aSessionFolderKeepsTheClientItRan() {
|
||||
val dir = tmp.newFolder("2026-10-18-01-steam")
|
||||
assertNull(SessionArtifacts.recordedClient(dir))
|
||||
SessionArtifacts.recordClient(dir, "x86_64")
|
||||
assertEquals("x86_64", SessionArtifacts.recordedClient(dir))
|
||||
java.io.File(dir, "steam-client.txt").writeText("something else\n")
|
||||
assertNull(SessionArtifacts.recordedClient(dir))
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,17 @@ class VacDiagnosticsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun theSameGameInTwoLibrariesGetsTwoConsoleNames() {
|
||||
val a = java.io.File("/lib1/steamapps/common/Team Fortress 2/tf/console.log")
|
||||
val b = java.io.File("/lib2/steamapps/common/Team Fortress 2/tf/console.log")
|
||||
val c = java.io.File("/lib1/steamapps/common/Half-Life 2/hl2/console.log")
|
||||
val names = VacDiagnostics.consoleNames(listOf(a, b, c))
|
||||
assertEquals("Team Fortress 2-tf", names[0])
|
||||
assertTrue(names[1].startsWith("Team Fortress 2-tf-") && names[1] != names[0])
|
||||
assertEquals("Half-Life 2-hl2", names[2])
|
||||
assertEquals(names, VacDiagnostics.consoleNames(listOf(a, b, c)))
|
||||
}
|
||||
|
||||
@Test fun tailReadsAllOfAReplacedFile() {
|
||||
val log = java.io.File.createTempFile("console", ".log")
|
||||
try {
|
||||
|
||||
@@ -1032,7 +1032,7 @@ BUSCONF
|
||||
if [ "$beat" -le 720 ] && [ -n "${BL_CLIENT_CPUS:-}" ]; then
|
||||
for _d in /proc/[0-9]*; do
|
||||
{ IFS= read -r -d '' _c && { IFS= read -r -d '' _c1 || _c1=; }; } < "$_d/cmdline" 2>/dev/null || continue
|
||||
case $_c in FEX|*/FEX) _c=$_c1 ;; esac
|
||||
case $_c in FEX|*/FEX|FEXInterpreter|*/FEXInterpreter) _c=$_c1 ;; esac
|
||||
case $_c in *steamwebhelper*|*steamrtarm64/steam|*steamrt64/steam|*gamescope*) ;; *) continue ;; esac
|
||||
_t=("$_d"/task/*)
|
||||
_p=${_d#/proc/}
|
||||
|
||||
@@ -950,7 +950,7 @@ fi
|
||||
if [ -n "${BL_CLIENT_CPUS:-}" ] && command -v taskset >/dev/null 2>&1; then
|
||||
(
|
||||
while sleep 5; do
|
||||
for pid in $(ps -A -o PID,ARGS | awk '($2 == "FEX" || $2 ~ /\/FEX$/) && ($3 ~ /steamrt64\/steam$/ || $3 ~ /steamwebhelper$/) {print $1} $2 ~ /steamrtarm64\/steamwebhelper$/ {print $1}'); do
|
||||
for pid in $(ps -A -o PID,ARGS | awk '($2 ~ /^(.*\/)?FEX(Interpreter)?$/) && ($3 ~ /steamrt64\/steam$/ || $3 ~ /steamwebhelper$/) {print $1} $2 ~ /steamrtarm64\/steamwebhelper$/ {print $1}'); do
|
||||
taskset -a -p -c "$BL_CLIENT_CPUS" "$pid" >/dev/null 2>&1
|
||||
done
|
||||
done
|
||||
|
||||
Reference in new issue
Block a user