Merge pull request #19 from PhilipK/lutris-support

Lutris support
This commit is contained in:
Philip Kristoffersen
2022-03-08 21:34:56 +01:00
committed by GitHub
11 changed files with 213 additions and 6 deletions
+7 -3
View File
@@ -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/)
+3
View File
@@ -26,3 +26,6 @@ create_symlinks = true
[steamgrid_db] [steamgrid_db]
enabled = true enabled = true
prefer_animated = false prefer_animated = false
[lutris]
enabled = true
+78
View File
@@ -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");
}
}
+25
View File
@@ -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()
}
}
+51
View File
@@ -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),
},
}
}
}
+4
View File
@@ -0,0 +1,4 @@
pub mod game_list_parser;
pub mod lutris_game;
pub mod lutris_platform;
pub mod settings;
+7
View File
@@ -0,0 +1,7 @@
use serde::{Serialize,Deserialize};
#[derive(Debug, Deserialize, Serialize,Clone)]
pub struct LutrisSettings {
pub enabled: bool,
pub executable: Option<String>,
}
+19
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+8
View File
@@ -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) {