Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 121 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ edition = "2024"
[dependencies]
anyhow = "1.0.98"
chrono = { version = "0.4.41", features = ["serde"] }
clap = { version = "4.5.40", features = ["derive"] }
env_logger = "0.11.8"
futures = "0.3.31"
inquire = "0.7.5"
log = "0.4.27"
reqwest = { version = "0.12.15", features = ["json", "stream"] }
self-replace = "1.5.0"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
tempfile = "3.20.0"
thiserror = "2.0.12"
tokio = { version = "1.45.0", features = ["full"] }
uuid = { version = "1.16.0", features = ["serde"] }
windows = { version = "0.61.3", features = [
"Win32_System_Console",
"Win32_System_Services",
] }
windows-registry = "0.5.3"
windows-result = "0.3.4"

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Valthrun Loader

The Valthrun Loader automatically maps the [Valthrun Kernel Driver](https://github.com/valthrun/valthrun-driver-kernel) using [KDMapper](https://github.com/TheCruZ/kdmapper) and starts the [Valthrun Overlay](https://github.com/valthrun/valthrun).
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use winres::WindowsResource;

fn main() -> Result<(), Box<dyn std::error::Error>> {
{
let git_hash = if Path::new("../.git").exists() {
let git_hash = if Path::new(".git").exists() {
match { Command::new("git").args(&["rev-parse", "HEAD"]).output() } {
Ok(output) => String::from_utf8(output.stdout).expect("the git hash to be utf-8"),
Err(error) => {
Expand Down
21 changes: 15 additions & 6 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::{
util::{self},
utils::{self},
version::{self},
};

Expand Down Expand Up @@ -110,9 +110,18 @@ pub async fn get_latest_artifact_version(
http: &Client,
artifact_slug: &str,
) -> anyhow::Result<Version> {
let artifact = get_artifact(http, &artifact_slug).await?.artifact;
let track_response =
get_track(http, &artifact_slug, &artifact.default_track.to_string()).await?;
let artifact = get_artifact(http, artifact_slug).await?.artifact;

get_latest_artifact_track_version(http, artifact_slug, &artifact.default_track.to_string())
.await
}

pub async fn get_latest_artifact_track_version(
http: &Client,
artifact_slug: &str,
track_slug: &str,
) -> anyhow::Result<Version> {
let track_response = get_track(http, &artifact_slug, &track_slug).await?;

let latest_version = track_response
.versions
Expand All @@ -137,7 +146,7 @@ pub async fn download_latest_artifact_version(
.await
.context("get stored version hash")?;

let output_path = util::get_downloads_path()
let output_path = utils::get_downloads_path()
.context("get downloads path")?
.join(output_name);

Expand All @@ -146,7 +155,7 @@ pub async fn download_latest_artifact_version(
.is_none_or(|hash| !version::compare_hashes(&hash, &latest_version.version_hash));

if should_download {
util::download_file(
utils::download_file(
http,
format!(
"https://valth.run/api/artifacts/{}/{}/{}/download",
Expand Down
48 changes: 48 additions & 0 deletions src/commands/launch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use anyhow::Context;

use crate::{api, components, game, utils};

pub async fn launch(http: &reqwest::Client, enhancer: components::Enhancer) -> anyhow::Result<()> {
for artifact in enhancer.required_artifacts() {
log::info!("Downloading {}", artifact.name());

api::download_latest_artifact_version(http, artifact.slug(), artifact.file_name())
.await
.context("failed to download {}")?;
}

// TODO: Make it game-independent to also allow PUBG, for example
if game::is_running()
.await
.context("failed to check if game is running")?
{
log::info!("Counter-Strike 2 is already running.");
} else {
log::info!("Counter-Strike 2 is not running.");

if utils::confirm_default("Do you want to launch the game?", true)? {
log::info!("Waiting for Counter-Strike 2 to start");
game::launch_and_wait()
.await
.context("failed to wait for cs2 to launch")?;
}
}

utils::invoke_ps_command(&format!(
"Start-Process -FilePath '{}' -WorkingDirectory '{}'",
utils::get_downloads_path()?
.join(enhancer.artifact_to_execute().file_name())
.display(),
std::env::current_exe()
.context("get current exe")?
.parent()
.context("get parent path")?
.display()
))
.await
.context("failed to start overlay")?;

log::info!("Valthrun will now load. Have fun!");

Ok(())
}
43 changes: 43 additions & 0 deletions src/commands/map_driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use anyhow::Context;

use crate::{api, driver, fixes, utils};

pub async fn map_driver(http: &reqwest::Client) -> anyhow::Result<()> {
log::info!("Downloading Kernel Driver");

api::download_latest_artifact_version(http, "kernel-driver", "kernel_driver.sys")
.await
.context("failed to download kernel driver")?;

log::info!("Downloading KDMapper");

utils::download_file(
&http,
"https://github.com/sinjs/kdmapper/releases/latest/download/kdmapper.exe",
&utils::get_downloads_path()?.join("kdmapper.exe"),
)
.await
.context("failed to download kdmapper")?;

for service in [c"faceit", c"vgc", c"vgk", c"ESEADriver2"] {
if fixes::is_service_running(service).context("check service running")? {
log::warn!(
"Running service '{}' may interfere with the Valthrun Kernel Driver.",
service.to_str()?
);
utils::confirm_default("Do you want to stop it?", true)?;

fixes::stop_service(service.to_str()?)
.await
.context("stop service")?;
}
}

driver::ui_map_driver(&http)
.await
.context("failed to map driver")?;

log::info!("Driver successfully mapped");

Ok(())
}
5 changes: 5 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod map_driver;
pub use map_driver::*;

mod launch;
pub use launch::*;
Loading
Loading