Skip to content

Commit

Permalink
feat: added support for automatically running gamemode (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
cecilia-sanare authored Mar 18, 2024
1 parent fbc9c93 commit 2657144
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 35 deletions.
33 changes: 16 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@

### Installation

We provide a [binary and deb package](https://github.com/rain-cafe/protontweaks/releases/latest) for installation on platforms that don't have nix.
This will automatically install protontweaks with your systems package manager if its available

```sh
$ curl -fsSL https://protontweaks.com/install.sh | bash
```

#### NixOS

<details>
<summary>NixOS Flake Example</summary>
Expand Down Expand Up @@ -72,27 +78,20 @@ We provide a [binary and deb package](https://github.com/rain-cafe/protontweaks/

### Usage

```sh
$ protontweaks --help
#### Automatic

Crowdsourced tweaks for Steam!
This installs a systemd service that automatically updates your launch options when you install a game.

Usage: protontweaks [COMMAND_ARGS]...
protontweaks <COMMAND>
```sh
$ protontweaks service --install
```

Commands:
list Lists the apps installed on Steam
service Register or Unregister the watch service
run [experimental]: Runs the steam launch command and applies any necessary tweaks
watch [experimental]: Watches for any steam apps to be installed and automatically adds 'protontweaks' to the launch options
help Print this message or the help of the given subcommand(s)
#### Manual

Arguments:
[COMMAND_ARGS]... The steam launch command '%command%'
Add the following to the launch options for a steam game!

Options:
-h, --help Print help
-V, --version Print version
```sh
protontweaks %command%
```

[github-actions-image]: https://img.shields.io/github/actions/workflow/status/rain-cafe/protontweaks/ci.yml?event=push
Expand Down
72 changes: 54 additions & 18 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use owo_colors::OwoColorize;
use protontweaks_api::{app::App, Protontweaks};
use protontweaks_api::{app::App, system::SystemTweaks, Protontweaks};
use std::{collections::HashMap, process::Command};

use clap::Args;
use regex::Regex;

use crate::{apps, utils::command};
use crate::{
apps,
utils::{command, gamemode},
};

#[derive(Debug, Args)]
pub struct CommandArgs {
Expand All @@ -14,9 +17,9 @@ pub struct CommandArgs {
}

pub async fn command(args: CommandArgs) -> Result<(), String> {
let (command, args, app) = parse_command(args).await?;
let (command, args, app, system_tweaks) = parse_command(args).await?;

let tweaks = if let Some(app) = &app {
if let Some(app) = &app {
let (app_tweaks_applied, app_total_tweaks) = apps::apply_safe(app).await;

if app_tweaks_applied == 0 {
Expand All @@ -31,17 +34,17 @@ pub async fn command(args: CommandArgs) -> Result<(), String> {
format!("{app_tweaks_applied} tweaks").bold()
);
}
}

Some(app.flatten().await)
} else {
None
};
let env = &system_tweaks.map_or(HashMap::new(), |tweaks| tweaks.env);

let env = &tweaks.map_or(HashMap::new(), |tweaks| tweaks.env);
let mut command = Command::new(command);

Command::new(command)
.args(args)
.envs(env)
command.args(args).envs(env);

info!("Starting app... {:?}", command);

command
.spawn()
.expect("Failed to run command")
.wait()
Expand All @@ -50,7 +53,9 @@ pub async fn command(args: CommandArgs) -> Result<(), String> {
Ok(())
}

async fn parse_command(args: CommandArgs) -> Result<(String, Vec<String>, Option<App>), String> {
async fn parse_command(
args: CommandArgs,
) -> Result<(String, Vec<String>, Option<App>, Option<SystemTweaks>), String> {
let command_args = args.command_args.unwrap();
let is_proton = command_args
.iter()
Expand Down Expand Up @@ -79,8 +84,26 @@ async fn parse_command(args: CommandArgs) -> Result<(String, Vec<String>, Option
None
};

let command = command::split(&command)?;
return Ok((command[0].clone(), command[1..].to_vec(), app));
let mut command = command::split(&command)?;

let tweaks = if let Some(app) = &app {
Some(app.flatten().await)
} else {
None
};

if let Some(tweaks) = &tweaks {
// TODO: Add config support before enabling this
// if tweaks.settings.mangohud.unwrap_or(false) && mangohud::is_installed().await {
// args.splice(0..0, vec!["mangohud".to_string()]);
// }

if tweaks.settings.gamemode.unwrap_or(true) && gamemode::is_installed().await {
command.splice(0..0, vec!["gamemoderun".to_string()]);
}
}

return Ok((command[0].clone(), command[1..].to_vec(), app, tweaks));
}

#[cfg(test)]
Expand All @@ -89,7 +112,7 @@ pub mod tests {

#[tokio::test]
pub async fn parse_command_should_support_simple_commands() {
let (command, args, app) = parse_command(CommandArgs {
let (command, args, app, system_tweaks) = parse_command(CommandArgs {
command_args: Some(vec!["echo".to_string(), "hello".to_string()]),
})
.await
Expand All @@ -98,11 +121,15 @@ pub mod tests {
assert_eq!(command, "echo");
assert_eq!(args, vec!["hello"]);
assert!(app.is_none(), "Expected app to not be defined!");
assert!(
system_tweaks.is_none(),
"Expected systemTweaks to not be defined!"
);
}

#[tokio::test]
pub async fn parse_command_should_support_unified_commands() {
let (command, args, app) = parse_command(CommandArgs {
let (command, args, app, system_tweaks) = parse_command(CommandArgs {
command_args: Some(vec!["echo hello".to_string()]),
})
.await
Expand All @@ -111,6 +138,10 @@ pub mod tests {
assert_eq!(command, "echo");
assert_eq!(args, vec!["hello"]);
assert!(app.is_none(), "Expected app to not be defined!");
assert!(
system_tweaks.is_none(),
"Expected systemTweaks to not be defined!"
);
}

#[tokio::test]
Expand All @@ -130,7 +161,7 @@ pub mod tests {
"'/home/ceci/.local/share/Steam/steamapps/common/They Are Billions/TheyAreBillions.exe'"
].iter_mut().map(|x| x.to_string()).collect::<Vec<String>>();

let (command, args, app) = parse_command(CommandArgs {
let (command, args, app, system_tweaks) = parse_command(CommandArgs {
command_args: Some(command_args),
})
.await
Expand All @@ -143,5 +174,10 @@ pub mod tests {

assert_eq!(app.tweaks.env.len(), 0);
assert_eq!(app.tweaks.tricks.len(), 1);

let system_tweaks = system_tweaks.unwrap();

assert_eq!(system_tweaks.env.len(), app.tweaks.env.len());
assert_eq!(system_tweaks.tricks.len(), app.tweaks.tricks.len());
}
}
7 changes: 7 additions & 0 deletions src/utils/gamemode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::ffi::OsString;

pub async fn is_installed() -> bool {
super::command::exec::<Vec<OsString>, OsString>("gamemoderun", vec![])
.await
.is_ok()
}
5 changes: 5 additions & 0 deletions src/utils/mangohud.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub async fn is_installed() -> bool {
super::command::exec("mangohud", ["--version"])
.await
.is_ok()
}
2 changes: 2 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod command;
pub mod env;
pub mod gamemode;
pub mod mangohud;
pub mod nix_shell;
pub mod protontricks;
pub mod service;
Expand Down

0 comments on commit 2657144

Please sign in to comment.