diff --git a/src/cli.rs b/src/cli.rs index 9543b8e..70fe72a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -67,6 +67,18 @@ pub enum ListSubcommand { }, } +#[derive(Subcommand, Debug)] +pub enum ExternSubcommand { + /// Get the path of a game with the specified label. + GameData { + /// The identifier of the game to resolve. + /// + /// Use the `list` command to query the list of imported and supported games. + #[clap(long)] + game_id: String, + } +} + #[derive(Subcommand, Debug)] pub enum Commands { /// Initialize a new project configuration. @@ -263,4 +275,10 @@ pub enum Commands { #[clap(long, default_value = "./")] project_path: PathBuf, }, + + /// Commands for use by external tooling. + Extern { + #[clap(subcommand)] + command: ExternSubcommand, + }, } diff --git a/src/game/ecosystem.rs b/src/game/ecosystem.rs index 8c8c61f..086de2c 100644 --- a/src/game/ecosystem.rs +++ b/src/game/ecosystem.rs @@ -9,23 +9,19 @@ use crate::TCLI_HOME; pub async fn get_schema() -> Result { let local_schema = TCLI_HOME.join("ecosystem_schema.json"); - match local_schema.is_file() { - true => { - let schema_file = File::open(&local_schema)?; - let reader = BufReader::new(&schema_file); + if local_schema.is_file() { + let schema_file = File::open(&local_schema)?; + let reader = BufReader::new(&schema_file); - Ok(serde_json::from_reader(reader).unwrap()) - } + Ok(serde_json::from_reader(reader).unwrap()) + } else { + let schema_file = File::create(&local_schema)?; + let schema = ecosystem::get_schema().await?; - false => { - let schema_file = File::create(&local_schema)?; - let schema = ecosystem::get_schema().await?; + let schema_writer = BufWriter::new(&schema_file); + serde_json::to_writer_pretty(schema_writer, &schema).unwrap(); - let schema_writer = BufWriter::new(&schema_file); - serde_json::to_writer_pretty(schema_writer, &schema).unwrap(); - - Ok(schema) - } + Ok(schema) } } diff --git a/src/game/import/mod.rs b/src/game/import/mod.rs index 571129b..f8c97f4 100644 --- a/src/game/import/mod.rs +++ b/src/game/import/mod.rs @@ -6,6 +6,7 @@ pub mod steam; use std::path::{Path, PathBuf}; +use super::ecosystem; use super::error::GameError; use super::registry::{ActiveDistribution, GameData}; use crate::error::Error; @@ -13,8 +14,7 @@ use crate::game::import::ea::EaImporter; use crate::game::import::egs::EgsImporter; use crate::game::import::gamepass::GamepassImporter; use crate::game::import::steam::SteamImporter; -use crate::ts::v1::models::ecosystem::GameDef; -use crate::ts::v1::{ecosystem, models::ecosystem::GameDefPlatform}; +use crate::ts::v1::models::ecosystem::{ GameDef, GameDefPlatform }; pub trait GameImporter { fn construct(self: Box, base: ImportBase) -> Result; @@ -39,7 +39,7 @@ impl ImportBase { pub async fn new(game_id: &str) -> Result { let game_def = ecosystem::get_schema() .await - .map_err(|_| GameError::EcosystemSchema)? + .unwrap() .games .get(game_id) .ok_or_else(|| GameError::BadGameId(game_id.into()))? diff --git a/src/main.rs b/src/main.rs index 581960d..a0e20c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,11 +4,11 @@ use std::io::{self, Stdin}; use std::path::PathBuf; use clap::Parser; -use cli::InitSubcommand; +use cli::{ExternSubcommand, InitSubcommand}; use colored::Colorize; use directories::BaseDirs; use error::{IoError, Error}; -use game::import::GameImporter; +use game::import::{select_importer, GameImporter}; use once_cell::sync::Lazy; use project::error::ProjectError; use project::ProjectKind; @@ -359,7 +359,21 @@ async fn main() -> Result<(), Error> { server::spawn(read, write, &project_path).await?; Ok(()) - }, + } + + Commands::Extern { command } => { + match command { + ExternSubcommand::GameData { game_id } => { + let base = ImportBase::new(&game_id).await?; + let game_data = import::select_importer(&base)? + .construct(base)?; + + println!("{}", serde_json::to_string_pretty(&game_data.active_distribution)?); + } + } + + Ok(()) + } }; test diff --git a/src/package/install/legacy_compat.rs b/src/package/install/legacy_compat.rs index c8a921d..8de3400 100644 --- a/src/package/install/legacy_compat.rs +++ b/src/package/install/legacy_compat.rs @@ -52,16 +52,17 @@ async fn init_installer_map() -> Result, Error> { ("northstar", "metherul-Northstar_Installer"), ]); - let installer_map = schema - .games - .into_iter() - .filter_map(|(_, def)| def.r2modman) - .flat_map(|def| def.mod_loader_packages) - .filter_map(|loader| match map.get(loader.loader.as_str()) { - Some(installer) => Some((loader.package_id, installer.to_string())), - None => None, - }) - .collect::>(); + // let installer_map = schema + // .games + // .into_iter() + // .filter_map(|(_, def)| def.r2modman) + // .flat_map(|def| schema.modloader_packages) + // .filter_map(|loader| match map.get(loader.loader.as_str()) { + // Some(installer) => Some((loader.package_id, installer.to_string())), + // None => None, + // }) + // .collect::>(); - Ok(installer_map) + // Shim out until we re-integrate the moved modloader_packages ecosystem field. + Ok(HashMap::new()) } diff --git a/src/ts/v1/models/ecosystem.rs b/src/ts/v1/models/ecosystem.rs index 6ee1a67..7a62112 100644 --- a/src/ts/v1/models/ecosystem.rs +++ b/src/ts/v1/models/ecosystem.rs @@ -10,6 +10,7 @@ pub struct EcosystemSchema { pub schema_version: Version, pub games: HashMap, pub communities: HashMap, + pub modloader_packages: Vec, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -34,7 +35,7 @@ pub struct GameDefMeta { #[serde(tag = "platform")] #[serde(rename_all = "kebab-case")] pub enum GameDefPlatform { - #[serde(rename = "egs")] + #[serde(rename = "epic-games-store")] EpicGames { identifier: String, }, @@ -51,6 +52,7 @@ pub enum GameDefPlatform { SteamDirect { identifier: String, }, + #[serde(rename = "oculus-store")] Oculus, Other, } @@ -60,7 +62,7 @@ impl GameDefPlatform { /// the ecosystem schema, preferably as a compile time check. pub fn ident_from_name<'a>(&'a self, name: &str) -> Option<&'a str> { match self { - GameDefPlatform::EpicGames { identifier } if name == "egs" => Some(identifier), + GameDefPlatform::EpicGames { identifier } if name == "epic-games-store" => Some(identifier), GameDefPlatform::GamePass { identifier } if name == "gamepass" => Some(identifier), GameDefPlatform::Origin { identifier } if name == "origin" || name == "ea" => { Some(identifier) @@ -76,11 +78,11 @@ impl GameDefPlatform { pub fn get_platform_names(&self) -> Vec<&'static str> { vec![ "origin", - "egs", + "epic-games-store", "gamepass", "steam", "steam-direct", - "oculus", + "oculus-store", "other", ] } @@ -93,14 +95,12 @@ pub struct GameDefR2MM { pub data_folder_name: String, pub settings_identifier: String, pub package_index: String, - pub exclusions_url: String, pub steam_folder_name: String, pub exe_names: Vec, - pub game_instancetype: String, + pub game_instance_type: String, pub game_selection_display_mode: String, - pub mod_loader_packages: Vec, pub install_rules: Vec, - pub relative_file_exclusions: Vec, + pub relative_file_exclusions: Option>, } #[derive(Serialize, Deserialize, Debug, Clone)]