mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-14 19:27:09 -04:00
fix: Steam touch controls load the layout Steam picked for DroidDeck's touch controller, including workshop layouts (#840)
This commit is contained in:
1 parent
eda1e9b9c6
commit
f635e92498
2 files changed
+88
-3
No files matched your search
@@ -158,7 +158,8 @@ object SteamTouchConfig {
|
||||
|
||||
fun load(context: Context, appId: Int): Config {
|
||||
val dir = configDir(context)
|
||||
val file = dir?.let { autosaveConfig(it, appId) }
|
||||
val file = dir?.let { deviceConfig(context, it, appId) }
|
||||
?: dir?.let { autosaveConfig(it, appId) }
|
||||
?: loggedConfig(context, appId)?.takeIf { isTouchConfig(it) }
|
||||
?: dir?.let { configsetConfig(context, it, appId) }
|
||||
if (file == null) {
|
||||
@@ -207,11 +208,16 @@ object SteamTouchConfig {
|
||||
null
|
||||
}
|
||||
|
||||
private fun configsetConfig(context: Context, dir: File, appId: Int): File? = try {
|
||||
val set = KeyValues.parse(File(dir, CONFIGSET).readText()).child("controller_config")?.child(appId.toString())
|
||||
private fun configsetConfig(context: Context, dir: File, appId: Int): File? = entryConfig(context, dir, CONFIGSET, appId)
|
||||
|
||||
private fun deviceConfig(context: Context, dir: File, appId: Int): File? = entryConfig(context, dir, DEVICE_CONFIGSET, appId)
|
||||
|
||||
private fun entryConfig(context: Context, dir: File, configset: String, appId: Int): File? = try {
|
||||
val set = KeyValues.parse(File(dir, configset).readText()).child("controller_config")?.child(appId.toString())
|
||||
when {
|
||||
set == null -> null
|
||||
set.string("autosave") == "1" -> File(dir, "$appId/controller_mobile_touch.vdf")
|
||||
set.string("workshop") != null -> workshopConfig(context, set.string("workshop")!!)
|
||||
set.string("template") != null -> File(steamRoot(context), "controller_base/templates/" + set.string("template"))
|
||||
else -> null
|
||||
}?.takeIf { it.isFile }
|
||||
@@ -219,7 +225,16 @@ object SteamTouchConfig {
|
||||
null
|
||||
}
|
||||
|
||||
internal fun workshopConfig(context: Context, id: String): File? {
|
||||
if (!id.all(Char::isDigit)) return null
|
||||
return File(steamRoot(context), "steamapps/workshop/content/$CONFIGS_APP/$id").listFiles()
|
||||
?.filter { it.isFile && (it.name.endsWith(".vdf") || it.name.endsWith(".bin")) }
|
||||
?.maxByOrNull { it.lastModified() }
|
||||
}
|
||||
|
||||
private const val CONFIGSET = "configset_controller_mobile_touch.vdf"
|
||||
private const val DEVICE_CONFIGSET = "configset_MT-DROIDDECK0001.vdf"
|
||||
private const val CONFIGS_APP = 241100
|
||||
|
||||
|
||||
private fun availability(mappings: KeyValues.Node): Map<Int, Set<Int>> {
|
||||
@@ -363,10 +378,20 @@ object SteamTouchConfig {
|
||||
tmp.writeText(text)
|
||||
if (!tmp.renameTo(target)) return null
|
||||
selectAutosave(dir, appId)
|
||||
dropDeviceEntry(dir, appId)
|
||||
Log.i(TAG, "steam touch: saved layouts ${sets.keys} for app $appId to ${target.path}")
|
||||
return target
|
||||
}
|
||||
|
||||
private fun dropDeviceEntry(dir: File, appId: Int) {
|
||||
val file = File(dir, DEVICE_CONFIGSET)
|
||||
if (!file.isFile) return
|
||||
val text = file.readText()
|
||||
val block = Regex("""\n\s*"$appId"\s*\{[^}]*\}""")
|
||||
if (!block.containsMatchIn(text)) return
|
||||
File(file.path + ".tmp").apply { writeText(text.replace(block, "")) }.renameTo(file)
|
||||
}
|
||||
|
||||
private fun selectAutosave(dir: File, appId: Int) {
|
||||
val file = File(dir, CONFIGSET)
|
||||
val text = if (file.isFile) file.readText() else "\"controller_config\"\n{\n}\n"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.droiddeck.launcher.input
|
||||
|
||||
import com.droiddeck.launcher.runtime.LinuxRuntime
|
||||
import java.io.File
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [33])
|
||||
class SteamTouchConfigFilesTest {
|
||||
private val context = RuntimeEnvironment.getApplication()
|
||||
private val steam = File(LinuxRuntime.rootDir(context), "root/.local/share/Steam")
|
||||
private val dir = File(steam, "steamapps/common/Steam Controller Configs/123/config").apply { mkdirs() }
|
||||
|
||||
@After fun tearDown() { steam.deleteRecursively() }
|
||||
|
||||
private fun touch(title: String) = "\"controller_mappings\"\n{\n\t\"title\"\t\t\"$title\"\n\t\"controller_type\"\t\t\"controller_mobile_touch\"\n}\n"
|
||||
|
||||
private fun configset(name: String, vararg entries: Pair<String, String>) = File(dir, name).writeText(
|
||||
"\"controller_config\"\n{\n" + entries.joinToString("") { (app, line) -> "\t\"$app\"\n\t{\n\t\t$line\n\t}\n" } + "}\n",
|
||||
)
|
||||
|
||||
private fun autosave(app: Int, title: String) = File(dir, "$app/controller_mobile_touch.vdf").apply { parentFile!!.mkdirs(); writeText(touch(title)) }
|
||||
|
||||
private fun workshop(id: String, title: String) =
|
||||
File(steam, "steamapps/workshop/content/241100/$id/123_legacy.bin").apply { parentFile!!.mkdirs(); writeText(touch(title)) }
|
||||
|
||||
@Test fun theDevicesWorkshopPickWinsOverAnOlderAutosave() {
|
||||
autosave(204360, "old autosave")
|
||||
val picked = workshop("1764689049", "official")
|
||||
configset("configset_controller_mobile_touch.vdf", "204360" to "\"autosave\"\t\t\"1\"")
|
||||
configset("configset_MT-DROIDDECK0001.vdf", "204360" to "\"workshop\"\t\t\"1764689049\"")
|
||||
assertEquals(picked, SteamTouchConfig.load(context, 204360).file)
|
||||
}
|
||||
|
||||
@Test fun aWorkshopPickInTheTypeConfigsetIsRead() {
|
||||
val picked = workshop("42", "community")
|
||||
configset("configset_controller_mobile_touch.vdf", "413150" to "\"workshop\"\t\t\"42\"")
|
||||
assertEquals(picked, SteamTouchConfig.load(context, 413150).file)
|
||||
}
|
||||
|
||||
@Test fun savingAnEditDropsTheDevicePickSoTheEditLoads() {
|
||||
workshop("1764689049", "official")
|
||||
configset("configset_MT-DROIDDECK0001.vdf", "204360" to "\"workshop\"\t\t\"1764689049\"", "8400" to "\"workshop\"\t\t\"7\"")
|
||||
val config = SteamTouchConfig.load(context, 204360)
|
||||
val saved = SteamTouchConfig.saveLayouts(context, 204360, config, mapOf(1 to emptyList()))
|
||||
assertEquals(File(dir, "204360/controller_mobile_touch.vdf"), saved)
|
||||
val device = File(dir, "configset_MT-DROIDDECK0001.vdf").readText()
|
||||
assertFalse(device.contains("\"204360\""))
|
||||
assertTrue(device.contains("\"8400\""))
|
||||
assertEquals(saved, SteamTouchConfig.load(context, 204360).file)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user