Skip to content

Commit c458bcb

Browse files
committed
RegEditLinux: Find VRChat install location for registry parsing
Fixes VRChat config warnings not working when VRChat is installed at a library location other than the default.
1 parent 95daec6 commit c458bcb

1 file changed

Lines changed: 72 additions & 6 deletions

File tree

  • server/desktop/src/main/java/dev/slimevr/desktop/games/vrchat

server/desktop/src/main/java/dev/slimevr/desktop/games/vrchat/RegEdit.kt

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import java.io.FileReader
1212
import java.io.InvalidObjectException
1313
import java.nio.ByteBuffer
1414
import java.nio.ByteOrder
15+
import java.nio.file.Path
1516
import kotlin.io.path.Path
1617
import kotlin.io.path.exists
1718

@@ -142,13 +143,78 @@ class RegEditLinux : AbstractRegEdit() {
142143
}
143144

144145
companion object {
145-
const val USER_REG_SUBPATH = "steamapps/compatdata/438100/pfx/user.reg"
146-
val USER_REG_PATH =
147-
System.getenv("HOME")?.let {
148-
Path(it, ".steam", "root", USER_REG_SUBPATH).let { if (it.exists()) it else null }
149-
?: Path(it, ".steam", "debian-installation", USER_REG_SUBPATH).let { if (it.exists()) it else null }
150-
?: Path(it, ".var", "app", "com.valvesoftware.Steam", "data", "Steam", USER_REG_SUBPATH).let { if (it.exists()) it else null }
146+
private fun findAppLibraryLocation(steamPath: Path, appId: Int): Path? {
147+
val keyValueRegex = Regex(""""(\w+)"[ \t]*(?:"(.+)")?""")
148+
try {
149+
BufferedReader(FileReader(steamPath.resolve("config/libraryfolders.vdf").toFile())).use { reader ->
150+
var depth = 0
151+
var currentLibraryPath: Path? = null
152+
153+
while (reader.ready()) {
154+
val line = reader.readLine().trim()
155+
if (line == "{") {
156+
depth += 1
157+
continue
158+
}
159+
if (line == "}") {
160+
depth -= 1
161+
continue
162+
}
163+
164+
keyValueRegex.matchEntire(line)?.let {
165+
val key = it.groupValues[1]
166+
val value = it.groupValues[2]
167+
168+
when (depth) {
169+
0 -> {
170+
require(key == "libraryfolders") { "root key must be libraryfolders" }
171+
}
172+
173+
1 -> {
174+
// start of a library node
175+
}
176+
177+
2 -> {
178+
// in a library node
179+
if (key == "path") {
180+
currentLibraryPath = Path(value)
181+
} else if (key == "apps") {
182+
// start of apps node
183+
require(currentLibraryPath != null) { "path must come before apps in node" }
184+
}
185+
}
186+
187+
3 -> {
188+
// in apps node
189+
val curAppId = try {
190+
key.toInt()
191+
} catch (_: NumberFormatException) {
192+
null
193+
}
194+
if (curAppId != null && curAppId == appId) {
195+
assert(currentLibraryPath != null)
196+
return currentLibraryPath
197+
}
198+
}
199+
}
200+
}
201+
}
202+
LogManager.warning("[VRChatRegEdit] Couldn't find library folder for appid $appId")
203+
}
204+
} catch (e: Exception) {
205+
LogManager.severe("[VRChatRegEdit] Error parsing Steam libraryfolders", e)
151206
}
207+
return null
208+
}
209+
210+
const val USER_REG_SUBPATH = "steamapps/compatdata/438100/pfx/user.reg"
211+
val STEAM_PATH = System.getenv("HOME")?.let { home ->
212+
Path(home, ".steam", "root").takeIf { it.exists() }
213+
?: Path(home, ".steam", "debian-installation").takeIf { it.exists() }
214+
?: Path(home, ".var", "app", "com.valvesoftware.Steam", "data", "Steam").takeIf { it.exists() }
215+
}
216+
val USER_REG_PATH: Path? = if (STEAM_PATH != null) findAppLibraryLocation(STEAM_PATH, 438100)?.resolve(USER_REG_SUBPATH) else null
217+
152218
val KEY_VALUE_PATTERN = Regex(""""(.+)"=(.+)""")
153219

154220
val HEX_FORMAT = HexFormat {

0 commit comments

Comments
 (0)