diff --git a/paper.jar b/paper.jar new file mode 100644 index 0000000..821ed30 Binary files /dev/null and b/paper.jar differ diff --git a/settings.toml b/settings.toml index f0afb15..ef67e05 100644 --- a/settings.toml +++ b/settings.toml @@ -1,21 +1,9 @@ [core] Provider = "paper" -Version = "Latest" -Freeze = false -ForceUpdate = false - -[plugins.chunky] -source = "modrinth" -channel = "release" -freeze = false -force_update = false +Version = "1.20.6" +ForceUpdate = true [plugins.simple-voice-chat] -source = "modrinth" -channel = "release" -freeze = false force_update = false - -[additions] -config_plugins_from = "GitHub.link" -key = "GitHub.key" +[plugins.chunky] +force_update = false diff --git a/src/main.rs b/src/main.rs index e544811..6be11c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,26 +5,32 @@ pub mod query; pub mod settings; pub mod tr; +use std::sync::Arc; + use crate::errors::error::Result; +use indicatif::{MultiProgress, ProgressBar}; use lock::Lock; use settings::Settings; +use tokio::sync::Mutex; use tr::load::Load; #[tokio::main] async fn main() -> Result<()> { pretty_env_logger::formatted_builder() - .filter_level(log::LevelFilter::Debug) + .filter_level(log::LevelFilter::Info) .init(); - let mut lock = Lock::load().await?; + let mpb = Arc::new(Mutex::new(MultiProgress::new())); + let pb = mpb.lock().await.add(ProgressBar::new_spinner()); + pb.set_message("Init Minecraft Addon Controller"); + let lock = Arc::new(Mutex::new(Lock::load().await.unwrap_or_default())); let settings = Settings::load().await?; // let a = Additions::new(Some("GitHub.link".to_string()), Some("GitHub.key".to_string())); // settings.set_additions(Some(a)); - if let Some(plugins) = settings.plugins() { plugins - .download_all(settings.core().version(), &mut lock) + .download_all(settings.core().version(), &lock, &mpb) .await?; } - settings.core().download(&mut lock).await?; + settings.core().download(&lock, &mpb).await?; Ok(()) } diff --git a/src/models/cores/paper.rs b/src/models/cores/paper.rs index 0445f8b..001fb64 100644 --- a/src/models/cores/paper.rs +++ b/src/models/cores/paper.rs @@ -1,3 +1,4 @@ +use indicatif::{ProgressBar, ProgressState, ProgressStyle}; use serde::{Deserialize, Serialize}; use crate::{ @@ -48,15 +49,35 @@ impl ModelCore for T { //find build and push link async fn get_link(core: &Core) -> Result<(String, ChooseHash, String)> { let core_name = Self::CORE_NAME; + // make pb + let pb = ProgressBar::new_spinner(); + let name_closure = move |_: &ProgressState, f: &mut dyn std::fmt::Write| { + f.write_str(core_name).unwrap(); + }; + pb.set_style( + ProgressStyle::with_template( + "Package:: {name:.blue} >>> {spinner:.green} {msg:.blue} ", + ) + .unwrap() + .with_key("name", name_closure), + ); + // Start work + pb.set_message("Init work"); //get data from core let build = core.build(); let version = core.version(); //find link and version + + pb.set_message("Finding version"); + let version = find_version(version, core_name).await?; let verlink = format!( "https://api.papermc.io/v2/projects/{}/versions/{}", core_name, version ); + + pb.set_message("Make link"); + let build_list: BuildList = reqwest::get(verlink).await?.json().await?; let build_list = build_list.builds.as_slice(); match build { diff --git a/src/settings/core.rs b/src/settings/core.rs index f17a0f8..6fe4fb1 100644 --- a/src/settings/core.rs +++ b/src/settings/core.rs @@ -1,5 +1,9 @@ +use std::sync::Arc; + +use indicatif::MultiProgress; use log::{debug, info}; use serde::{Deserialize, Serialize}; +use tokio::sync::Mutex; use crate::errors::error::Result; use crate::lock::core::CoreMeta; @@ -14,6 +18,8 @@ use crate::tr::hash::ChooseHash; use crate::tr::model::core::ModelCore; use crate::tr::{download::Download, save::Save}; +use super::extensions::plugin::Plugin; + #[derive(Deserialize, Serialize, Debug, Default, PartialEq, Clone)] #[serde(rename_all = "PascalCase")] pub struct Core { @@ -81,8 +87,13 @@ impl Core { } /// Скачиваем `Core` и сохраняем его по стандартному пути. - pub async fn download(&self, lock: &mut Lock) -> Result<()> { + pub async fn download( + &self, + lock: &Arc>, + mpb: &Arc>, + ) -> Result<()> { let (link, hash, build) = self.get_link().await?; + let mut lock = lock.lock().await; if let Some(e) = lock.core().build() { debug!("lock build: {} / build: {}", &e, &build); if *e == build && !self.force_update || self.freeze { @@ -90,10 +101,9 @@ impl Core { return Ok(()); } } - let file = self - .get_file(self.provider.as_str().to_string(), link, hash) - .await?; - self.save_bytes(file, self.provider().as_str()).await?; + let mpb = mpb.lock().await; + let file = Core::get_file(self.provider.as_str().to_string(), link, hash, &mpb).await?; + Plugin::save_bytes(file, self.provider().as_str()).await?; *lock.core_mut() = CoreMeta::new(self.provider.clone(), self.version.clone(), Some(build)); lock.save().await } diff --git a/src/settings/extensions/plugin.rs b/src/settings/extensions/plugin.rs index 52f223f..51faba1 100644 --- a/src/settings/extensions/plugin.rs +++ b/src/settings/extensions/plugin.rs @@ -5,7 +5,7 @@ use crate::models::extensions::modrinth::ModrinthData; use crate::tr::hash::ChooseHash; use crate::tr::model::extension::ModelExtensions; -#[derive(Deserialize, Serialize, Debug, PartialEq, Default)] +#[derive(Deserialize, Serialize, Debug, PartialEq, Default, Clone)] pub struct Plugin { // Откуда качаем #[serde(default)] @@ -59,7 +59,7 @@ impl Plugin { } } -#[derive(Deserialize, Serialize, Debug, Default, PartialEq)] +#[derive(Deserialize, Serialize, Debug, Default, PartialEq, Clone)] #[serde(rename_all = "lowercase")] pub enum Sources { Spigot, // bad api @@ -69,7 +69,7 @@ pub enum Sources { CurseForge, // ? } -#[derive(Deserialize, Serialize, Debug, Default, PartialEq)] +#[derive(Deserialize, Serialize, Debug, Default, PartialEq, Clone)] #[serde(rename_all = "lowercase")] pub enum Channels { #[default] diff --git a/src/settings/extensions/plugins.rs b/src/settings/extensions/plugins.rs index c71ab4e..3a6e4a4 100644 --- a/src/settings/extensions/plugins.rs +++ b/src/settings/extensions/plugins.rs @@ -1,7 +1,10 @@ use std::collections::HashMap; +use std::sync::Arc; -use log::{debug, info}; +use futures_util::future::join_all; +use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle}; use serde::{Deserialize, Serialize}; +use tokio::sync::Mutex; use crate::errors::error::Result; use crate::lock::ext::ExtensionMeta; @@ -22,34 +25,52 @@ impl Plugins { &self.0 } - pub async fn download_all(&self, game_version: &str, lock: &mut Lock) -> Result<()> { - debug!("Plugins list: {:#?}", self.0); - for (name, plugin) in self.0.iter() { - // Получение ссылки, хэша и билда - let (link, hash, build) = plugin.get_link(name, game_version).await?; - //Проверка есть ли такой же Plugin в Lock - if let Some(e) = lock.plugins().get(name) { - match e.version() { - Some(e) => { - if *e == build && !plugin.force_update() || plugin.freeze() { - info!("Плагин {} не нуждается в обновлении", name); - return Ok(()); - } + pub async fn download_all( + &self, + game_version: &str, + lock: &Arc>, + mpb: &Arc>, + ) -> Result<()> { + //make list of links + let mut link_list = Vec::new(); + let mut handler_list = Vec::new(); + for (name, plugin) in self.0.clone() { + let (link, hash, build) = plugin.get_link(&name, game_version).await?; + if let Some(plugin_meta) = lock.lock().await.plugins().get(&name) { + if let Some(local_build) = plugin_meta.version() { + if *local_build == build && !plugin.force_update() || plugin.freeze() { + // PB style, init + let name_closure = move |_: &ProgressState, f: &mut dyn std::fmt::Write| { + f.write_str(&name).unwrap(); + }; + let pb = mpb.lock().await.add(ProgressBar::new_spinner()); + pb.set_style( + ProgressStyle::with_template("Package:: {name:.blue} >>> {msg:.blue}") + .unwrap() + .with_key("name", name_closure), + ); + pb.finish_with_message("Does't need to update"); + continue; } - None => {} } } - // Получение файла - let file = plugin.get_file(name.to_string(), link, hash).await?; - // Сохранение - plugin.save_bytes(file, name).await?; - // Добавление в Lock - lock.plugins_mut().insert(name.to_string(), { - ExtensionMeta::new(Some(build), format!("./plugins/{}.jar", name)) - }); - // Используем на каждой итерации, так как может возникнуть ошибка. - lock.save().await?; + link_list.push((link, hash, build, name.to_owned())) } + for (link, hash, build, name) in link_list { + let lock = Arc::clone(lock); + let mpb = Arc::clone(mpb); + handler_list.push(tokio::spawn(async move { + let mpb = mpb.lock().await; + let file = Plugin::get_file(name.to_owned(), link, hash, &mpb).await?; + let mut lock = lock.lock().await; + Plugin::save_bytes(file, name.as_str()).await?; + lock.plugins_mut().insert(name.to_string(), { + ExtensionMeta::new(Some(build), format!("./plugins/{}.jar", name)) + }); + lock.save().await + })); + } + join_all(handler_list).await; Ok(()) } } diff --git a/src/tr/download.rs b/src/tr/download.rs index bde06b3..c780e3c 100644 --- a/src/tr/download.rs +++ b/src/tr/download.rs @@ -1,15 +1,15 @@ use crate::errors::error::Result; use bytes::{Bytes, BytesMut}; use futures_util::StreamExt; -use indicatif::{ProgressBar, ProgressState, ProgressStyle}; +use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle}; use super::hash::ChooseHash; pub trait Download { fn get_file( - &self, name: String, link: String, hash: ChooseHash, + mpb: &MultiProgress, ) -> impl std::future::Future> + Send { async move { // make reqwest @@ -21,7 +21,7 @@ pub trait Download { f.write_str(&name).unwrap(); }; // PB style, init - let pb = ProgressBar::new(size); + let pb = mpb.add(ProgressBar::new(size)); pb.set_style( ProgressStyle::with_template( "Package:: {name:.blue} >>> {spinner:.green} {msg:.blue} | {bytes:.blue}/{total_bytes:.blue} -> eta:{eta:.blue}, {bytes_per_sec:.blue} | ", @@ -29,7 +29,6 @@ pub trait Download { .unwrap() .with_key("name", name_closure), ); - pb.set_message("Download..."); let mut size_upload = 0_u64; diff --git a/src/tr/save.rs b/src/tr/save.rs index 1b58d99..0bcdc25 100644 --- a/src/tr/save.rs +++ b/src/tr/save.rs @@ -33,7 +33,6 @@ pub trait Save { } } fn save_bytes( - &self, bytes: Bytes, name: &str, ) -> impl std::future::Future> + Send {