From 27a7dad62d25c6f7b8ee55882a8c9e92122d540b Mon Sep 17 00:00:00 2001 From: TOwInOK <60252419+TOwInOK@users.noreply.github.com> Date: Mon, 4 Mar 2024 00:11:05 +0700 Subject: [PATCH] minor changes start work at modrinth plugin system --- src/config/datapack.rs | 21 +---------- src/config/downloader.rs | 63 +++++++++++++++++++++---------- src/config/errors.rs | 10 ++--- src/config/mod.rs | 42 +++++++++------------ src/config/models/item.rs | 67 --------------------------------- src/config/models/mod.rs | 2 +- src/config/models/modrinth.rs | 71 +++++++++++++++++++++++++++++++++++ src/config/models/vanilla.rs | 5 ++- src/config/plugin.rs | 8 ++-- src/main.rs | 2 +- 10 files changed, 147 insertions(+), 144 deletions(-) delete mode 100644 src/config/models/item.rs create mode 100644 src/config/models/modrinth.rs diff --git a/src/config/datapack.rs b/src/config/datapack.rs index c20a50f..55febf6 100644 --- a/src/config/datapack.rs +++ b/src/config/datapack.rs @@ -11,23 +11,4 @@ pub struct Datapack { paper: Option>, //List of plugins to stop updating frozen: Option>, -} - -impl Datapack { - // fn new( - // modrinth: Option>, - // spigot: Option>, - // paper: Option>, - // frozen: Option>, - // ) -> Self { - // Self { - // modrinth, - // spigot, - // paper, - // frozen, - // } - // } - // pub fn default() -> Self { - // Datapack::new(None, None, None, None) - // } -} +} \ No newline at end of file diff --git a/src/config/downloader.rs b/src/config/downloader.rs index 670d4a0..0ea25c9 100644 --- a/src/config/downloader.rs +++ b/src/config/downloader.rs @@ -1,25 +1,30 @@ -use std::{env, path::PathBuf}; +use crate::config::DownloadErrors; +use log::warn; use log::{info, trace}; -use sha1::Sha1; +use md5::Md5; use sha1::Digest as Digest1; -use sha2::Sha256; +use sha1::Sha1; use sha2::Digest as Digest256; -use md5::Md5; +use sha2::Sha256; +use std::collections::HashMap; +use std::{env, path::PathBuf}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use crate::config::DownloadErrors; use super::{CompareHashError, ConfigErrors}; - pub struct Downloader(); impl Downloader { - ///Get all info about for download core //We need to get sha* or md5 for checking it - pub async fn download_core(freeze: bool, link:String, hash: ChooseHash) -> Result<(), DownloadErrors> { + pub async fn download_core( + freeze: bool, + link: String, + hash: ChooseHash, + ) -> Result<(), DownloadErrors> { if freeze { - info!("Мы не нуждаемся в загрузке"); + warn!("Загрузка ядра была отключена!\n + Если это ваша первая загрузка, то отключите параметр freeze"); return Ok(()); } let (content, result_str) = Self::get_file(&link, hash.clone()).await?; @@ -31,10 +36,19 @@ impl Downloader { Ok(()) } else { trace!("Hash файла: {}\nHash ожидалось: {:#?}", result_str, &hash); - Err(DownloadErrors::DownloadCorrupt("Файл получен с ошибками!".to_string())) + Err(DownloadErrors::DownloadCorrupt( + "Файл получен с ошибками!".to_string(), + )) } } - + ///### This func needs to download plugins, not to choose list of plugin to download. + /// + ///## `[lh]` is map contains values: `[Mode to download, Hash of mod]` + pub async fn download_plugins(lh: HashMap, version: String) -> Result<(), DownloadErrors> { + //use version to download file only for this version + //safe file like `[name-version.jar]` + todo!() + } async fn get_file(link: &str, hash: ChooseHash) -> Result<(Vec, ChooseHash), ConfigErrors> { let response = reqwest::get(link).await?; @@ -42,12 +56,18 @@ impl Downloader { let hash = hash.calculate_hash(&*content).await?; Ok((content.to_vec(), hash)) } - - - async fn save_file(content: Vec, current_dir: PathBuf, link: &str) -> tokio::io::Result<()> { + async fn save_file( + content: Vec, + current_dir: PathBuf, + link: &str, + ) -> tokio::io::Result<()> { let path_buf = PathBuf::from(link); - let fname = current_dir.join(path_buf.file_name().unwrap_or_else(|| std::ffi::OsStr::new("tmp.bin"))); + let fname = current_dir.join( + path_buf + .file_name() + .unwrap_or_else(|| std::ffi::OsStr::new("tmp.bin")), + ); let mut file = tokio::fs::File::create(fname).await?; file.write_all(&content).await?; Ok(()) @@ -62,7 +82,10 @@ pub enum ChooseHash { } impl ChooseHash { - async fn calculate_hash(self, mut reader: impl tokio::io::AsyncRead + Unpin) -> Result { + async fn calculate_hash( + self, + mut reader: impl tokio::io::AsyncRead + Unpin, + ) -> Result { match self { ChooseHash::SHA1(_) => { let mut hashed = ::new(); @@ -75,7 +98,7 @@ impl ChooseHash { } let result = hashed.finalize(); Ok(ChooseHash::SHA1(format!("{:x}", result))) - }, + } ChooseHash::SHA256(_) => { let mut hashed = ::new(); let mut buffer = [0; 4096]; @@ -87,7 +110,7 @@ impl ChooseHash { } let result = hashed.finalize(); Ok(ChooseHash::SHA256(format!("{:x}", result))) - }, + } ChooseHash::MD5(_) => { let mut hashed = ::new(); let mut buffer = [0; 4096]; @@ -99,7 +122,7 @@ impl ChooseHash { } let result = hashed.finalize(); Ok(ChooseHash::MD5(format!("{:x}", result))) - }, + } } } } @@ -112,4 +135,4 @@ impl std::fmt::Display for ChooseHash { ChooseHash::MD5(hash) => write!(f, "MD5: {}", hash), } } -} \ No newline at end of file +} diff --git a/src/config/errors.rs b/src/config/errors.rs index 0e13bd5..356802a 100644 --- a/src/config/errors.rs +++ b/src/config/errors.rs @@ -54,8 +54,6 @@ impl From for DownloadErrors { } } - - #[derive(Error, Debug)] pub enum CompareHashError { #[error("Конвертация Sha1 проведена не успешно : {0}")] @@ -70,9 +68,9 @@ pub enum CompareHashError { impl From for ConfigErrors { fn from(value: CompareHashError) -> Self { match value { - CompareHashError::SHA1(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), - CompareHashError::SHA256(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), - CompareHashError::MD5(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), + CompareHashError::SHA1(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), + CompareHashError::SHA256(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), + CompareHashError::MD5(msg) => ConfigErrors::LoadCorrupt(msg.to_string()), } } -} \ No newline at end of file +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 896797e..d1172a1 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,13 +1,12 @@ mod datapack; +mod downloader; mod errors; mod models; mod plugin; mod version; -mod downloader; - -use downloader::Downloader; use datapack::*; +use downloader::Downloader; use errors::*; use log::info; use models::vanilla::Vanilla; @@ -51,36 +50,31 @@ impl Config { pub async fn download_all(self) -> Result<(), DownloadErrors> { //download core - self.choose_core().await + self.choose_core().await?; + self.choose_plugin().await } ///Function download core by info in [`Config`] - async fn choose_core(self) -> Result<(), DownloadErrors> { - match self.version { + async fn choose_core(&self) -> Result<(), DownloadErrors> { + match &self.version { //Download vanilla Versions::Vanilla(ver, freeze) => { - let (link, hash) = Vanilla::find(&*ver).await?; - Downloader::download_core(freeze, link, hash).await + let (link, hash) = Vanilla::find(&**ver).await?; + Downloader::download_core(*freeze, link, hash).await } - Versions::Purpur(_, _) => todo!(), Versions::Paper(_, _) => todo!(), Versions::Spigot(_, _) => todo!(), Versions::Bucket(_, _) => todo!(), } } -} - - - - -async fn download_plugins() -> Result<(), DownloadErrors> { - todo!() -} -async fn download_mods() -> Result<(), DownloadErrors> { - todo!() -} -async fn download_datapacks() -> Result<(), DownloadErrors> { - todo!() -} - + async fn choose_plugin(&self) -> Result<(), DownloadErrors> { + if let Some(plugins) = &self.plugins { + + todo!() + } else { + info!("Нет плагинов для скачивания"); + Ok(()) + } + } +} \ No newline at end of file diff --git a/src/config/models/item.rs b/src/config/models/item.rs deleted file mode 100644 index 9af768a..0000000 --- a/src/config/models/item.rs +++ /dev/null @@ -1,67 +0,0 @@ -use serde::Deserialize; -use serde::Serialize; -use serde_json::Value; - -pub type ItemRoot = Vec; - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ItemData { - #[serde(rename = "game_versions")] - pub game_versions: Vec, - pub loaders: Vec, - pub id: String, - #[serde(rename = "project_id")] - pub project_id: String, - #[serde(rename = "author_id")] - pub author_id: String, - pub featured: bool, - pub name: String, - #[serde(rename = "version_number")] - pub version_number: String, - pub changelog: String, - #[serde(rename = "changelog_url")] - pub changelog_url: Value, - #[serde(rename = "date_published")] - pub date_published: String, - pub downloads: i64, - #[serde(rename = "version_type")] - pub version_type: String, - pub status: String, - #[serde(rename = "requested_status")] - pub requested_status: Value, - pub files: Vec, - pub dependencies: Vec, -} - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct File { - pub hashes: Hashes, - pub url: String, - pub filename: String, - pub primary: bool, - pub size: i64, - #[serde(rename = "file_type")] - pub file_type: Value, -} - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Hashes { - pub sha512: String, - pub sha1: String, -} - -#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Dependency { - #[serde(rename = "version_id")] - pub version_id: Value, - #[serde(rename = "project_id")] - pub project_id: String, - #[serde(rename = "file_name")] - pub file_name: Value, - #[serde(rename = "dependency_type")] - pub dependency_type: String, -} diff --git a/src/config/models/mod.rs b/src/config/models/mod.rs index d7a20cf..3209e0b 100644 --- a/src/config/models/mod.rs +++ b/src/config/models/mod.rs @@ -1,2 +1,2 @@ -pub mod item; +pub mod modrinth; pub mod vanilla; diff --git a/src/config/models/modrinth.rs b/src/config/models/modrinth.rs new file mode 100644 index 0000000..662587e --- /dev/null +++ b/src/config/models/modrinth.rs @@ -0,0 +1,71 @@ +use std::collections::HashMap; + +use md5::digest::typenum::Mod; +use serde::Deserialize; +use serde::Serialize; +use serde_json::Value; + +use crate::config::downloader::ChooseHash; + +pub type Name = String; +pub type Hash = ChooseHash; +pub type ProjectID = String; +pub type PluginID = String; +pub type About = (Hash, ProjectID, PluginID); + +pub struct Modrinth { + plugin: HashMap +} +///# Example +///we have cdn like this: `https://cdn.modrinth.com/data/PROJECT_ID/versions/ID/NAME-LOADER-VERSION.jar` +///we can take `[project_id]` -> `AANobbMI` +///we can take `[id]` -> `4GyXKCLd` +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ModrinthData { + //Always change ich version + pub id: PluginID, + //Stable token. + pub project_id: ProjectID, + pub files: Vec, + pub dependencies: Vec, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct File { + pub hashes: Hashes, + pub url: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Hashes { + pub sha1: String, + // pub sha512: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Dependency { + #[serde(rename = "version_id")] + pub version_id: Value, + #[serde(rename = "file_name")] + pub file_name: Value, + #[serde(rename = "dependency_type")] + pub dependency_type: String, +} + + +impl Modrinth { + ///Convert Vector of data to hashmap + ///for download files + pub async fn convert(data: Vec) -> Self { + let hashmap: HashMap = HashMap::new(); + data.iter().map(|x| + { + + }); + todo!() + } +} \ No newline at end of file diff --git a/src/config/models/vanilla.rs b/src/config/models/vanilla.rs index e98e9ec..0c776c8 100644 --- a/src/config/models/vanilla.rs +++ b/src/config/models/vanilla.rs @@ -86,7 +86,10 @@ impl Vanilla { info!("Find jar to download!"); debug!("Check body: {:#?}", &download_section.downloads.server); - Ok((download_section.downloads.server.url, ChooseHash::SHA1(download_section.downloads.server.sha1))) + Ok(( + download_section.downloads.server.url, + ChooseHash::SHA1(download_section.downloads.server.sha1), + )) } ///Return `url` for get a json which contain link to download diff --git a/src/config/plugin.rs b/src/config/plugin.rs index 9fd86cd..2f7b453 100644 --- a/src/config/plugin.rs +++ b/src/config/plugin.rs @@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, Debug)] pub struct Plugin { //list to download from https://modrinth.com/ - modrinth: Option>, + pub modrinth: Option>, //list to download from https://www.spigotmc.org/ - spigot: Option>, + pub spigot: Option>, //list to download from https://hangar.papermc.io/ - paper: Option>, + pub paper: Option>, //List of plugins to stop updating - frozen: Option>, + pub frozen: Option>, } impl Plugin { diff --git a/src/main.rs b/src/main.rs index b517073..fda5ba8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ async fn main() { Config::default() }); log::debug!("{:#?}", config); - match Config::download_all(config).await { + match config.download_all().await { Ok(_) => todo!(), Err(_) => todo!(), }