Skip to content

Commit 855ca37

Browse files
committed
fix: check for necessary vcomp140 library when launching native client
As someone that just reinstalled windows and didn't launch the native client via the Jagex Launcher, I lacked the necessary Visual C++ Redistributable and its libraries, and thus was unable to boot the native client. This commit gives a clean error indicating what went wrong if that were to happen.
1 parent c5675fe commit 855ca37

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

proxy/src/main/kotlin/net/rsprox/proxy/ProxyService.kt

+47-3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import net.rsprox.proxy.config.registerConnection
4747
import net.rsprox.proxy.connection.ClientTypeDictionary
4848
import net.rsprox.proxy.connection.ProxyConnectionContainer
4949
import net.rsprox.proxy.downloader.JagexNativeClientDownloader
50+
import net.rsprox.proxy.exceptions.MissingLibraryException
5051
import net.rsprox.proxy.filters.DefaultPropertyFilterSetStore
5152
import net.rsprox.proxy.futures.asCompletableFuture
5253
import net.rsprox.proxy.http.GamePackProvider
@@ -514,6 +515,8 @@ public class ProxyService(
514515
path = null,
515516
port = port,
516517
character,
518+
operatingSystem,
519+
ClientType.RuneLite,
517520
)
518521
logger.debug { "Waiting for client to connect to the server socket..." }
519522
gamePackProvider.prefetch()
@@ -554,22 +557,46 @@ public class ProxyService(
554557
OperatingSystem.WINDOWS -> {
555558
val directory = path.parent.toFile()
556559
val absolutePath = path.absolutePathString()
557-
createProcess(listOf(absolutePath), directory, path, port, character)
560+
createProcess(
561+
listOf(absolutePath),
562+
directory,
563+
path,
564+
port,
565+
character,
566+
operatingSystem,
567+
ClientType.Native,
568+
)
558569
}
559570

560571
OperatingSystem.MAC -> {
561572
// The patched file is at /.rsprox/clients/osclient.app/Contents/MacOS/osclient-patched
562573
// We need to however execute the /.rsprox/clients/osclient.app "file"
563574
val rootDirection = path.parent.parent.parent
564575
val absolutePath = "${File.separator}${rootDirection.absolutePathString()}"
565-
createProcess(listOf("open", absolutePath), null, path, port, character)
576+
createProcess(
577+
listOf("open", absolutePath),
578+
null,
579+
path,
580+
port,
581+
character,
582+
operatingSystem,
583+
ClientType.Native,
584+
)
566585
}
567586

568587
OperatingSystem.UNIX -> {
569588
try {
570589
val directory = path.parent.toFile()
571590
val absolutePath = path.absolutePathString()
572-
createProcess(listOf("wine", absolutePath), directory, path, port, character)
591+
createProcess(
592+
listOf("wine", absolutePath),
593+
directory,
594+
path,
595+
port,
596+
character,
597+
operatingSystem,
598+
ClientType.Native,
599+
)
573600
} catch (e: IOException) {
574601
throw RuntimeException("wine is required to run the enhanced client on unix", e)
575602
}
@@ -585,6 +612,8 @@ public class ProxyService(
585612
path: Path?,
586613
port: Int,
587614
character: JagexCharacter?,
615+
operatingSystem: OperatingSystem,
616+
clientType: ClientType,
588617
) {
589618
logger.debug { "Attempting to create process $command" }
590619
val builder =
@@ -629,12 +658,27 @@ public class ProxyService(
629658
// case will be hit here. The 500 millisecond wait time is a requirement to hit it, otherwise it'll still
630659
// be alive by the time it hits that.
631660
if (!process.isAlive) {
661+
if (operatingSystem == OperatingSystem.WINDOWS && clientType == ClientType.Native) {
662+
checkVisualCPlusPlusRedistributable()
663+
}
632664
throw IllegalStateException("Unable to launch process: $path, error code: ${process.waitFor()}")
633665
}
634666
if (path != null) logger.debug { "Successfully launched $path" }
635667
processes[port] = process.children().toList() + process.toHandle()
636668
}
637669

670+
private fun checkVisualCPlusPlusRedistributable() {
671+
val rootPath = Path(System.getenv("SYSTEMROOT") ?: return)
672+
val vcomp140 = rootPath.resolve("System32").resolve("vcomp140.dll")
673+
if (vcomp140.notExists()) {
674+
throw MissingLibraryException(
675+
"VCOMP140.dll is missing. " +
676+
"Install Visual C++ Redistributable to obtain the necessary libraries via " +
677+
"https://www.microsoft.com/en-ca/download/details.aspx?id=48145",
678+
)
679+
}
680+
}
681+
638682
private fun createConfigurationDirectories(path: Path) {
639683
runCatching("Unable to create configuration directory: $path") {
640684
Files.createDirectories(path)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.rsprox.proxy.exceptions
2+
3+
public class MissingLibraryException(
4+
string: String,
5+
) : RuntimeException(string)

0 commit comments

Comments
 (0)