Added a way to add mods

This commit is contained in:
xeovalyte 2024-05-28 16:23:51 +02:00
parent 20dddba0d5
commit d7c50ec8be
No known key found for this signature in database
4 changed files with 119 additions and 7 deletions

View File

@ -24,4 +24,7 @@ pub enum Commands {
/// The name of the mod to add /// The name of the mod to add
name: String, name: String,
}, },
/// Remove a mod from the modpack
Remove,
} }

View File

@ -12,6 +12,9 @@ async fn main() {
cli::Commands::Init => { cli::Commands::Init => {
pack::Pack::init().await; pack::Pack::init().await;
} }
cli::Commands::Add { name } => {
pack::Pack::add(name).await;
}
_ => (), _ => (),
}; };
} }

View File

@ -1,3 +1,5 @@
use core::fmt;
use serde::Deserialize; use serde::Deserialize;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -8,9 +10,63 @@ pub struct MinecraftVersion {
pub major: bool, pub major: bool,
} }
#[derive(Deserialize, Debug)]
pub struct Mod {
pub title: String,
pub description: String,
pub project_id: String,
}
impl fmt::Display for Mod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.title)
}
}
#[derive(Deserialize, Debug)]
pub struct Search {
hits: Vec<Mod>,
}
#[derive(Deserialize, Debug)]
pub struct ProjectVersion {
pub name: String,
pub game_versions: Vec<String>,
pub version_type: String,
pub id: String,
pub project_id: String,
}
pub async fn get_minecraft_versions() -> Result<Vec<MinecraftVersion>, reqwest::Error> { pub async fn get_minecraft_versions() -> Result<Vec<MinecraftVersion>, reqwest::Error> {
reqwest::get("https://api.modrinth.com/v2/tag/game_version") reqwest::get("https://api.modrinth.com/v2/tag/game_version")
.await? .await?
.json::<Vec<MinecraftVersion>>() .json::<Vec<MinecraftVersion>>()
.await .await
} }
pub async fn search_projects(
query: String,
version: &String,
loader: &String,
) -> Result<Vec<Mod>, reqwest::Error> {
let url = format!("https://api.modrinth.com/v2/search?query={query}&facets=[[\"project_type:mod\"],[\"versions:{version}\"],[\"categories:{loader}\"]]");
let response = reqwest::get(url).await?.json::<Search>().await?;
Ok(response.hits)
}
pub async fn get_project_versions(
id: &String,
version: &String,
loader: &String,
) -> Result<Vec<ProjectVersion>, reqwest::Error> {
let url = format!("https://api.modrinth.com/v2/project/{id}/version?loaders=[\"{loader}\"]&game_versions=[\"{version}\"]");
let response = reqwest::get(url)
.await?
.json::<Vec<ProjectVersion>>()
.await?;
Ok(response)
}

View File

@ -1,21 +1,31 @@
use crate::modrinth; use crate::modrinth;
use colored::*; use colored::*;
use inquire::Select; use inquire::Select;
use serde::Serialize; use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter}; use std::{
fmt::{Display, Formatter},
fs,
};
#[derive(Serialize)] #[derive(Serialize, Deserialize)]
pub struct Pack { pub struct Pack {
info: Info, info: Info,
mods: Vec<Mod>,
} }
#[derive(Serialize)] #[derive(Serialize, Deserialize)]
pub struct Mod {
id: String,
version_id: String,
}
#[derive(Serialize, Deserialize)]
pub struct Info { pub struct Info {
loader: Modloader, loader: Modloader,
minecraft_version: String, minecraft_version: String,
} }
#[derive(Serialize, Debug, Clone, Copy)] #[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub enum Modloader { pub enum Modloader {
Fabric, Fabric,
Quilt, Quilt,
@ -35,6 +45,12 @@ impl Display for Modloader {
} }
impl Pack { impl Pack {
pub fn get() -> Self {
let pack_string = fs::read_to_string(".packium.toml").unwrap();
toml::from_str(&pack_string).unwrap()
}
pub async fn init() { pub async fn init() {
println!("Fetching Minecraft information..."); println!("Fetching Minecraft information...");
@ -43,7 +59,7 @@ impl Pack {
let versions = versions let versions = versions
.iter() .iter()
.filter(|x| x.version_type == "release".to_string()) .filter(|x| x.version_type == "release".to_string())
.map(|x| x.version.clone()) .map(|x| &x.version)
.collect(); .collect();
let modloader = Select::new("Modloader?", Modloader::VARIANTS.to_vec()) let modloader = Select::new("Modloader?", Modloader::VARIANTS.to_vec())
@ -56,13 +72,47 @@ impl Pack {
let pack = Pack { let pack = Pack {
info: Info { info: Info {
minecraft_version: version, minecraft_version: version.to_owned(),
loader: modloader, loader: modloader,
}, },
mods: vec![],
}; };
let pack_toml = toml::to_string_pretty(&pack).unwrap(); let pack_toml = toml::to_string_pretty(&pack).unwrap();
std::fs::write(".packium.toml", pack_toml).unwrap(); std::fs::write(".packium.toml", pack_toml).unwrap();
} }
pub async fn add(name: &String) {
let mut pack = Self::get();
let mods = modrinth::search_projects(
name.to_owned(),
&pack.info.minecraft_version,
&pack.info.loader.to_string().to_lowercase(),
)
.await
.unwrap();
let project = Select::new("Choose a mod", mods).prompt().unwrap();
let versions = modrinth::get_project_versions(
&project.project_id,
&pack.info.minecraft_version,
&pack.info.loader.to_string().to_lowercase(),
)
.await
.unwrap();
let version = versions.get(0).unwrap();
pack.mods.push(Mod {
id: project.project_id.clone(),
version_id: version.id.clone(),
});
let pack_toml = toml::to_string_pretty(&pack).unwrap();
std::fs::write(".packium.toml", pack_toml).unwrap();
}
} }