Change vanilla JAR download timeout and add warnings
use anyhow::Context;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::Arc;
+use std::time::SystemTime;
use std::{
fs::{self, File},
io,
@@ -11,6 +14,8 @@ use zip::ZipArchive;
const JAR_URL: &str =
"https://launcher.mojang.com/v1/objects/c5f6fb23c3876461d46ec380421e42b289789530/server.jar";
const JAR_NAME: &str = "server-1.16.2.jar";
+const DOWNLOAD_WARNING_MINUTES: f64 = 2.0;
+const DOWNLOAD_TIMEOUT_MINUTES: u64 = 30;
/// Downloads vanilla server/client JARs and assets, used
/// for loot tables, recipes, etc.
@@ -19,7 +24,10 @@ const JAR_NAME: &str = "server-1.16.2.jar";
/// The vanilla datapack will be extracted to `$base/datapacks`.
pub fn download_vanilla_assets(base: &Path) -> anyhow::Result<()> {
let jar = download_jar(base)
- .context("failed to download vanilla server JAR")
+ .context(format!(
+ "failed to download vanilla server JAR in {} minutes",
+ DOWNLOAD_TIMEOUT_MINUTES
+ ))
.context("please make sure you have an Internet connection.")?;
// NB: JAR files are just glorified ZIP files, so we can use the zip crate
// to process the data.
@@ -32,10 +40,37 @@ pub fn download_vanilla_assets(base: &Path) -> anyhow::Result<()> {
fn download_jar(base: &Path) -> anyhow::Result<File> {
log::info!("Downloading vanilla server JAR from {}", JAR_URL);
+
+ let downloaded = Arc::new(AtomicBool::new(false));
+ let download_start_time = SystemTime::now();
+ let mut download_time = 1.0;
+ let mut warning = 1;
+ let downloaded1 = downloaded.clone();
+ std::thread::spawn(move || {
+ while !downloaded1.load(Ordering::Relaxed) {
+ let elapsed = download_start_time.elapsed().unwrap().as_secs_f64();
+ if elapsed / 60.0 >= warning as f64 * DOWNLOAD_WARNING_MINUTES
+ && download_time / 60.0 < warning as f64 * DOWNLOAD_WARNING_MINUTES
+ {
+ log::warn!("Looks like you have a slow internet connection! Downloading vanilla server JAR for {} minutes", warning as f64 * DOWNLOAD_WARNING_MINUTES);
+ warning += 1;
+ }
+ download_time = elapsed;
+ std::thread::sleep(Duration::from_secs(1));
+ }
+ });
+
let mut data = ureq::get(JAR_URL)
- .timeout(Duration::from_secs(10))
- .call()?
+ .timeout(Duration::from_secs(60 * DOWNLOAD_TIMEOUT_MINUTES))
+ .call()
+ .map_err(|err| {
+ // stop download time counter
+ downloaded.store(true, Ordering::Relaxed);
+ err
+ })?
.into_reader();
+ downloaded.store(true, Ordering::Relaxed);
+ log::info!("Downloaded vanilla server JAR successfully");
let downloaded_dir = base.join("downloaded");
fs::create_dir_all(&downloaded_dir)?;
