mirror of
https://github.com/djibux/BoilR.git
synced 2026-09-01 05:53:41 +02:00
@@ -14,13 +14,13 @@ The goal is that you do not have to leave your Steam library to launch games fro
|
|||||||
- [x] [Origin](https://www.origin.com) integration (currently only windows, linux comming soon)
|
- [x] [Origin](https://www.origin.com) integration (currently only windows, linux comming soon)
|
||||||
- [x] [GOG](https://www.gog.com/galaxy) integration
|
- [x] [GOG](https://www.gog.com/galaxy) integration
|
||||||
- [x] [UPlay](https://ubisoftconnect.com) integration (Windows only)
|
- [x] [UPlay](https://ubisoftconnect.com) integration (Windows only)
|
||||||
|
- [x] [Lutris](https://github.com/lutris/lutris) integration
|
||||||
- [x] Cross Platform (Linux & Windows)
|
- [x] Cross Platform (Linux & Windows)
|
||||||
- [x] UI For configuration
|
- [x] UI For configuration
|
||||||
- [x] Small (~1.5mb on disk)
|
- [x] Small (~1.5mb on disk)
|
||||||
- [x] Lightweight (~2mb ram)
|
- [x] Lightweight (~2mb ram)
|
||||||
- [x] Fast synchronization (~30ms)
|
- [x] Fast synchronization (~30ms)
|
||||||
- [x] Fast art download (as fast as your internet will take you)
|
- [x] Fast art download (as fast as your internet will take you)
|
||||||
- [ ] [Lutris](https://github.com/lutris/lutris) integration
|
|
||||||
- [ ] XBox/Microsoft Store integration
|
- [ ] XBox/Microsoft Store integration
|
||||||
- [ ] Scheduling of synchronization
|
- [ ] Scheduling of synchronization
|
||||||
- [ ] Steam Deck support (should work, but need to test when I get one)
|
- [ ] Steam Deck support (should work, but need to test when I get one)
|
||||||
@@ -70,6 +70,10 @@ create_symlinks = true #Only for Linux, To get around a bug in steam where paths
|
|||||||
enabled=false #On windows this is default false, on linux default true
|
enabled=false #On windows this is default false, on linux default true
|
||||||
executable="legendary" #If this value is not defined, "legendary" will be used, it is assumed to be on the path.
|
executable="legendary" #If this value is not defined, "legendary" will be used, it is assumed to be on the path.
|
||||||
|
|
||||||
|
[lutris]
|
||||||
|
enabled=true #Default true
|
||||||
|
executable="lutris" #The executable to run for lutris, default is "lutris".
|
||||||
|
|
||||||
[itch]
|
[itch]
|
||||||
enabled=false #Default false
|
enabled=false #Default false
|
||||||
location="C:\\Users\\user\\AppData\\Roaming\\itch" #If this value is not defined, "%APPDATA%itch" will be used on windows, and HOME/.config/itch on linux.
|
location="C:\\Users\\user\\AppData\\Roaming\\itch" #If this value is not defined, "%APPDATA%itch" will be used on windows, and HOME/.config/itch on linux.
|
||||||
@@ -96,7 +100,7 @@ prefer_animated = false #If true, animated images will be prefered over static i
|
|||||||
|
|
||||||
## Tips for Linux
|
## Tips for Linux
|
||||||
|
|
||||||
If you are on linux, and want to use one of the launchers that is not available natively, here are a few ways that you can make them work.
|
If you are on linux, and want to use one of the launchers that is not available natively, i suggest you use Lutris and make sure the BoilR integration for Lutris is enabled (see config section). If you don't want to use launch into Lutris here here are a few ways that you can make them work.
|
||||||
|
|
||||||
### GOG
|
### GOG
|
||||||
|
|
||||||
@@ -118,7 +122,7 @@ I recommend you just use [Legendary](https://github.com/derrod/legendary). But i
|
|||||||
|
|
||||||
### Origin
|
### Origin
|
||||||
|
|
||||||
Currently BoilR can't setup shortcuts to Origin because Origin uses a special link to open games. But I know of a workaround, it is just going to take a bit to make (basicly let Boiler take that url as input and let it call origin with proton settings and the url).
|
Currently BoilR can't setup shortcuts to Origin, on linux, because Origin uses a special link to open games. But I know of a workaround, it is just going to take a bit to make (basicly let Boiler take that url as input and let it call origin with proton settings and the url).
|
||||||
This section will be updated when it is ready.
|
This section will be updated when it is ready.
|
||||||
Untill then you can still play origin games thourgh Lutris [here](https://lutris.net/games/origin/)
|
Untill then you can still play origin games thourgh Lutris [here](https://lutris.net/games/origin/)
|
||||||
|
|
||||||
|
|||||||
@@ -26,3 +26,6 @@ create_symlinks = true
|
|||||||
[steamgrid_db]
|
[steamgrid_db]
|
||||||
enabled = true
|
enabled = true
|
||||||
prefer_animated = false
|
prefer_animated = false
|
||||||
|
|
||||||
|
[lutris]
|
||||||
|
enabled = true
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
use super::lutris_game::LutrisGame;
|
||||||
|
|
||||||
|
pub fn parse_lutris_games<'a>(input: &'a str) -> Vec<LutrisGame> {
|
||||||
|
input
|
||||||
|
.split("\n")
|
||||||
|
.into_iter()
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.filter_map(parse_line)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_line<'a>(input: &'a str) -> Option<LutrisGame> {
|
||||||
|
let mut sections = input.split("|");
|
||||||
|
if sections.clone().count() < 4 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let index = sections.next().unwrap().trim();
|
||||||
|
let name = sections.next().unwrap().trim();
|
||||||
|
let id = sections.next().unwrap().trim();
|
||||||
|
let platform = sections.next().unwrap().trim();
|
||||||
|
|
||||||
|
Some(LutrisGame {
|
||||||
|
id:id.to_string(),
|
||||||
|
index:index.to_string(),
|
||||||
|
name:name.to_string(),
|
||||||
|
platform:platform.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_output() {
|
||||||
|
let content = include_str!("test_output.txt");
|
||||||
|
|
||||||
|
let games = parse_lutris_games(content);
|
||||||
|
|
||||||
|
assert_eq!(19, games.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reads_index() {
|
||||||
|
let content = include_str!("test_output.txt");
|
||||||
|
|
||||||
|
let games = parse_lutris_games(content);
|
||||||
|
|
||||||
|
assert_eq!(games[0].index, "7");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reads_name() {
|
||||||
|
let content = include_str!("test_output.txt");
|
||||||
|
|
||||||
|
let games = parse_lutris_games(content);
|
||||||
|
|
||||||
|
assert_eq!(games[1].name, "Cave Story+");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reads_id() {
|
||||||
|
let content = include_str!("test_output.txt");
|
||||||
|
|
||||||
|
let games = parse_lutris_games(content);
|
||||||
|
|
||||||
|
assert_eq!(games[3].id, "dicey-dungeons");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reads_platform() {
|
||||||
|
let content = include_str!("test_output.txt");
|
||||||
|
|
||||||
|
let games = parse_lutris_games(content);
|
||||||
|
|
||||||
|
assert_eq!(games[18].platform, "steam");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
use steam_shortcuts_util::{shortcut::ShortcutOwned, Shortcut};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LutrisGame {
|
||||||
|
pub index: String,
|
||||||
|
pub name: String,
|
||||||
|
pub id: String,
|
||||||
|
pub platform: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LutrisGame> for ShortcutOwned {
|
||||||
|
fn from(game: LutrisGame) -> Self {
|
||||||
|
let options = format!("lutris:rungame/{}", game.id);
|
||||||
|
Shortcut::new(
|
||||||
|
0,
|
||||||
|
game.name.as_str(),
|
||||||
|
"lutris",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
&options.as_str(),
|
||||||
|
)
|
||||||
|
.to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
use super::game_list_parser::parse_lutris_games;
|
||||||
|
use super::lutris_game::LutrisGame;
|
||||||
|
use super::settings::LutrisSettings;
|
||||||
|
use crate::platform::{Platform, SettingsValidity};
|
||||||
|
use std::error::Error;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub struct LutrisPlatform {
|
||||||
|
pub settings: LutrisSettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Platform<LutrisGame, Box<dyn Error>> for LutrisPlatform {
|
||||||
|
fn enabled(&self) -> bool {
|
||||||
|
self.settings.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"Lutris"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_shortcuts(&self) -> Result<Vec<LutrisGame>, Box<dyn Error>> {
|
||||||
|
let default_lutris_exe = "lutris".to_string();
|
||||||
|
let lutris_executable = self.settings.executable.as_ref().unwrap_or(&default_lutris_exe);
|
||||||
|
let lutris_command = Command::new(lutris_executable).arg("-lo").output()?;
|
||||||
|
let output = String::from_utf8_lossy(&lutris_command.stdout).to_string();
|
||||||
|
let games = parse_lutris_games(output.as_str());
|
||||||
|
let mut res = vec![];
|
||||||
|
for game in games {
|
||||||
|
if game.platform != "steam" {
|
||||||
|
res.push(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
fn create_symlinks(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_valid(&self) -> crate::platform::SettingsValidity {
|
||||||
|
let shortcuts_res = self.get_shortcuts();
|
||||||
|
match shortcuts_res {
|
||||||
|
Ok(_) => SettingsValidity::Valid,
|
||||||
|
Err(err) => SettingsValidity::Invalid {
|
||||||
|
reason: format!("{}", err),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
pub mod game_list_parser;
|
||||||
|
pub mod lutris_game;
|
||||||
|
pub mod lutris_platform;
|
||||||
|
pub mod settings;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
use serde::{Serialize,Deserialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize,Clone)]
|
||||||
|
pub struct LutrisSettings {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub executable: Option<String>,
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
7 | 7 Billion Humans | 7-billion-humans | steam | -
|
||||||
|
1 | Cave Story+ | cave-story | steam | -
|
||||||
|
15 | Dead Cells | dead-cells | steam | -
|
||||||
|
6 | Dicey Dungeons | dicey-dungeons | steam | -
|
||||||
|
12 | Finding Paradise | finding-paradise | steam | -
|
||||||
|
17 | Griftlands | griftlands | steam | -
|
||||||
|
4 | Gunpoint | gunpoint | steam | -
|
||||||
|
5 | Impostor Factory | impostor-factory | steam | -
|
||||||
|
3 | Kentucky Route Zero | kentucky-route-zero | steam | -
|
||||||
|
13 | Monster Train | monster-train | steam | -
|
||||||
|
19 | My Test Game | my-test-game | linux | -
|
||||||
|
8 | Owlboy | owlboy | steam | -
|
||||||
|
16 | Papers, Please | papers-please | steam | -
|
||||||
|
11 | Reventure | reventure | steam | -
|
||||||
|
2 | Slay the Spire | slay-the-spire | steam | -
|
||||||
|
9 | Space Pirates and Zombies | space-pirates-and-zombies | steam | -
|
||||||
|
10 | The Detail | the-detail | steam | -
|
||||||
|
14 | The Henry Stickmin Collection | the-henry-stickmin-collection | steam | -
|
||||||
|
18 | Vampire Survivors | vampire-survivors | steam | -
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
mod egs;
|
mod egs;
|
||||||
mod gog;
|
mod gog;
|
||||||
mod itch;
|
mod itch;
|
||||||
|
mod lutris;
|
||||||
mod legendary;
|
mod legendary;
|
||||||
mod origin;
|
mod origin;
|
||||||
mod platform;
|
mod platform;
|
||||||
|
|||||||
+10
-3
@@ -1,7 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
egs::EpicGamesLauncherSettings, gog::GogSettings, itch::ItchSettings,
|
egs::EpicGamesLauncherSettings,
|
||||||
legendary::LegendarySettings, origin::OriginSettings, steam::SteamSettings,
|
gog::GogSettings,
|
||||||
steamgriddb::SteamGridDbSettings, uplay::UplaySettings,
|
itch::ItchSettings,
|
||||||
|
legendary::LegendarySettings,
|
||||||
|
origin::OriginSettings,
|
||||||
|
steam::SteamSettings,
|
||||||
|
steamgriddb::SteamGridDbSettings,
|
||||||
|
uplay::UplaySettings,
|
||||||
|
lutris::settings::LutrisSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
use config::{Config, ConfigError, Environment, File};
|
use config::{Config, ConfigError, Environment, File};
|
||||||
@@ -19,6 +25,7 @@ pub struct Settings {
|
|||||||
pub origin: OriginSettings,
|
pub origin: OriginSettings,
|
||||||
pub gog: GogSettings,
|
pub gog: GogSettings,
|
||||||
pub uplay: UplaySettings,
|
pub uplay: UplaySettings,
|
||||||
|
pub lutris: LutrisSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use steam_shortcuts_util::{shortcut::ShortcutOwned, shortcuts_to_bytes};
|
|||||||
use crate::{
|
use crate::{
|
||||||
egs::EpicPlatform,
|
egs::EpicPlatform,
|
||||||
legendary::LegendaryPlatform,
|
legendary::LegendaryPlatform,
|
||||||
|
lutris::lutris_platform::LutrisPlatform,
|
||||||
platform::Platform,
|
platform::Platform,
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
steam::{get_shortcuts_for_user, get_shortcuts_paths, ShortcutInfo, SteamUsersInfo},
|
steam::{get_shortcuts_for_user, get_shortcuts_paths, ShortcutInfo, SteamUsersInfo},
|
||||||
@@ -111,6 +112,13 @@ fn update_platforms(settings: &Settings, new_user_shortcuts: &mut Vec<ShortcutOw
|
|||||||
},
|
},
|
||||||
new_user_shortcuts,
|
new_user_shortcuts,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
update_platform_shortcuts(
|
||||||
|
&LutrisPlatform {
|
||||||
|
settings: settings.lutris.clone(),
|
||||||
|
},
|
||||||
|
new_user_shortcuts,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_shortcuts(shortcuts: &[ShortcutOwned], path: &Path) {
|
fn save_shortcuts(shortcuts: &[ShortcutOwned], path: &Path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user