Add support for lutris

This commit is contained in:
Philip Kristoffersen
2022-03-08 21:24:24 +01:00
parent 4d71aca0a6
commit 36dca25297
9 changed files with 187 additions and 3 deletions
+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>,
}
+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) {