mirror of
https://github.com/djibux/BoilR.git
synced 2026-09-01 05:53:41 +02:00
Initial Origin Support
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
debug= false
|
debug= false
|
||||||
|
|
||||||
|
[origin]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
[epic_games]
|
[epic_games]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
[legendary]
|
[legendary]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
[steam]
|
[steam]
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ mod manifest_item;
|
|||||||
mod settings;
|
mod settings;
|
||||||
mod epic_platform;
|
mod epic_platform;
|
||||||
|
|
||||||
pub use manifest_item::*;
|
pub(crate) use manifest_item::*;
|
||||||
use get_manifests::get_egs_manifests;
|
use get_manifests::get_egs_manifests;
|
||||||
pub use settings::EpicGamesLauncherSettings;
|
pub use settings::EpicGamesLauncherSettings;
|
||||||
pub use epic_platform::*;
|
pub use epic_platform::*;
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
itch::ItchPlatform,
|
itch::ItchPlatform,
|
||||||
|
origin::OriginPlatform,
|
||||||
steamgriddb::{download_images, CachedSearch},
|
steamgriddb::{download_images, CachedSearch},
|
||||||
};
|
};
|
||||||
use std::{fs::File, io::Write, path::Path};
|
use std::{fs::File, io::Write, path::Path};
|
||||||
mod egs;
|
mod egs;
|
||||||
mod itch;
|
mod itch;
|
||||||
mod legendary;
|
mod legendary;
|
||||||
|
mod origin;
|
||||||
mod platform;
|
mod platform;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod steam;
|
mod steam;
|
||||||
@@ -93,6 +95,13 @@ async fn run_sync() -> Result<(), Box<dyn Error>> {
|
|||||||
&mut new_user_shortcuts,
|
&mut new_user_shortcuts,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
update_platform_shortcuts(
|
||||||
|
&OriginPlatform {
|
||||||
|
settings: settings.origin.clone(),
|
||||||
|
},
|
||||||
|
&mut new_user_shortcuts,
|
||||||
|
);
|
||||||
|
|
||||||
let shortcuts = new_user_shortcuts.iter().map(|f| f.borrow()).collect();
|
let shortcuts = new_user_shortcuts.iter().map(|f| f.borrow()).collect();
|
||||||
|
|
||||||
save_shortcuts(&shortcuts, Path::new(&shortcut_info.path));
|
save_shortcuts(&shortcuts, Path::new(&shortcut_info.path));
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
mod settings;
|
||||||
|
mod origin_platform;
|
||||||
|
mod origin_game;
|
||||||
|
|
||||||
|
pub use origin_platform::*;
|
||||||
|
pub use settings::*;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
use steam_shortcuts_util::{shortcut::ShortcutOwned, Shortcut};
|
||||||
|
pub struct OriginGame {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OriginGame> for ShortcutOwned {
|
||||||
|
fn from(game: OriginGame) -> Self {
|
||||||
|
let launch = format!("origin2://game/launch?offerIds={}&autoDownload=1", game.id);
|
||||||
|
let shortcut = Shortcut::new(0, game.title.as_str(), launch.as_str(), "", "", "", "");
|
||||||
|
let mut owned_shortcut = shortcut.to_owned();
|
||||||
|
owned_shortcut.tags.push("Origin".to_owned());
|
||||||
|
owned_shortcut.tags.push("Ready TO Play".to_owned());
|
||||||
|
owned_shortcut.tags.push("Installed".to_owned());
|
||||||
|
|
||||||
|
owned_shortcut
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
use crate::platform::Platform;
|
||||||
|
use failure::*;
|
||||||
|
use nom::bytes::complete::take_until;
|
||||||
|
use std::{
|
||||||
|
fs::DirEntry,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{origin_game::OriginGame, OriginSettings};
|
||||||
|
|
||||||
|
pub struct OriginPlatform {
|
||||||
|
pub settings: OriginSettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Platform<OriginGame, OriginErrors> for OriginPlatform {
|
||||||
|
fn enabled(&self) -> bool {
|
||||||
|
self.settings.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"Origin"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_shortcuts(&self) -> Result<Vec<OriginGame>, OriginErrors> {
|
||||||
|
let origin_folder = Path::new(
|
||||||
|
&self
|
||||||
|
.settings
|
||||||
|
.path
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| get_default_location()),
|
||||||
|
)
|
||||||
|
.join("LocalContent");
|
||||||
|
if !origin_folder.exists() {
|
||||||
|
return Err(OriginErrors::PathNotFound {
|
||||||
|
path: origin_folder.to_str().unwrap().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let game_folders =
|
||||||
|
origin_folder
|
||||||
|
.read_dir()
|
||||||
|
.map_err(|e| OriginErrors::CouldNotReadGameDir {
|
||||||
|
path: origin_folder,
|
||||||
|
error: format!("{:?}", e),
|
||||||
|
})?;
|
||||||
|
let games = game_folders
|
||||||
|
.filter_map(|folder| folder.ok())
|
||||||
|
.filter_map(|game_folder| {
|
||||||
|
let game_title = game_folder.file_name().to_string_lossy().to_string();
|
||||||
|
let mfst_content = get_folder_mfst_file_content(&game_folder.path());
|
||||||
|
let id = match mfst_content {
|
||||||
|
Some(c) => parse_id_from_file(c.as_str())
|
||||||
|
.ok()
|
||||||
|
.map(|(_, id_str)| String::from(id_str)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
id.map(|id| OriginGame {
|
||||||
|
id: id.to_string(),
|
||||||
|
title: game_title,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
Ok(games.collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_folder_mfst_file_content(game_folder_path: &Path) -> Option<String> {
|
||||||
|
let game_folder_files = game_folder_path.read_dir();
|
||||||
|
if let Ok(game_folder_files) = game_folder_files {
|
||||||
|
let mfst_file = game_folder_files
|
||||||
|
.filter_map(|file| file.ok())
|
||||||
|
.filter(is_mfst_file)
|
||||||
|
.next()
|
||||||
|
.map(|file| std::fs::read_to_string(&file.path()));
|
||||||
|
return match mfst_file {
|
||||||
|
Some(mfst_file) => mfst_file.ok(),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_mfst_file(file: &DirEntry) -> bool {
|
||||||
|
file.path()
|
||||||
|
.extension()
|
||||||
|
.map(|ex| ex.to_str().unwrap_or("") == "mfst")
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_id_from_file(i: &str) -> nom::IResult<&str, &str> {
|
||||||
|
let (i, _) = take_until("&id=")(i)?;
|
||||||
|
let (i, _) = nom::bytes::complete::tag("&id=")(i)?;
|
||||||
|
take_until("&")(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn get_default_location() -> String {
|
||||||
|
//If we don't have a home drive we have to just die
|
||||||
|
let home = std::env::var("HOME").expect("Expected a home variable to be defined");
|
||||||
|
format!("{}/.origin/", home)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn get_default_location() -> String {
|
||||||
|
let key = "PROGRAMDATA";
|
||||||
|
let program_data = std::env::var(key).expect("Expected a APPDATA variable to be defined");
|
||||||
|
Path::new(&program_data)
|
||||||
|
.join("Origin")
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum OriginErrors {
|
||||||
|
#[fail(
|
||||||
|
display = "Origin path: {} could not be found. Try to specify a different path for Origin.",
|
||||||
|
path
|
||||||
|
)]
|
||||||
|
PathNotFound { path: String },
|
||||||
|
|
||||||
|
#[fail(
|
||||||
|
display = "Could not read Origin directory: {:?}. Error: {}",
|
||||||
|
path, error
|
||||||
|
)]
|
||||||
|
CouldNotReadGameDir { path: PathBuf, error: String },
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize,Clone)]
|
||||||
|
|
||||||
|
pub struct OriginSettings {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub path: Option<String>,
|
||||||
|
}
|
||||||
+3
-8
@@ -1,4 +1,4 @@
|
|||||||
use crate::{egs::EpicGamesLauncherSettings, itch::ItchSettings, legendary::LegendarySettings, steam::SteamSettings, steamgriddb::SteamGridDbSettings};
|
use crate::{egs::EpicGamesLauncherSettings, itch::ItchSettings, legendary::LegendarySettings, origin::OriginSettings, steam::SteamSettings, steamgriddb::SteamGridDbSettings};
|
||||||
|
|
||||||
use config::{Config, ConfigError, Environment, File};
|
use config::{Config, ConfigError, Environment, File};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@@ -11,11 +11,10 @@ pub struct Settings {
|
|||||||
pub legendary: LegendarySettings,
|
pub legendary: LegendarySettings,
|
||||||
pub itch: ItchSettings,
|
pub itch: ItchSettings,
|
||||||
pub steamgrid_db: SteamGridDbSettings,
|
pub steamgrid_db: SteamGridDbSettings,
|
||||||
pub steam: SteamSettings
|
pub steam: SteamSettings,
|
||||||
|
pub origin: OriginSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://github.com/JosefNemec/Playnite/tree/master/source/Plugins/OriginLibrary
|
|
||||||
//https://github.com/JosefNemec/Playnite/blob/master/source/Plugins/OriginLibrary/Origin.cs#L109
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn new() -> Result<Self, ConfigError> {
|
pub fn new() -> Result<Self, ConfigError> {
|
||||||
let mut s = Config::new();
|
let mut s = Config::new();
|
||||||
@@ -33,10 +32,6 @@ impl Settings {
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let enable_epic = true;
|
let enable_epic = true;
|
||||||
|
|
||||||
s.set_default("legendary.enabled", enable_legendary)?;
|
|
||||||
s.set_default("epic_games.enabled", enable_epic)?;
|
|
||||||
|
|
||||||
|
|
||||||
// Start off by merging in the "default" configuration file
|
// Start off by merging in the "default" configuration file
|
||||||
s.merge(File::with_name("config.toml").required(false))?;
|
s.merge(File::with_name("config.toml").required(false))?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user