You've already forked AstralRinth
forked from didirus/AstralRinth
add download authlib injector support
This commit is contained in:
@@ -6,9 +6,9 @@ use crate::launcher::download::download_log_config;
|
|||||||
use crate::launcher::io::IOError;
|
use crate::launcher::io::IOError;
|
||||||
use crate::profile::QuickPlayType;
|
use crate::profile::QuickPlayType;
|
||||||
use crate::state::{
|
use crate::state::{
|
||||||
Credentials, JavaVersion, ProcessMetadata, ProfileInstallStage,
|
AccountType, Credentials, JavaVersion, ProcessMetadata, ProfileInstallStage
|
||||||
};
|
};
|
||||||
use crate::util::io;
|
use crate::util::{io, utils};
|
||||||
use crate::{State, get_resource_file, process, state as st};
|
use crate::{State, get_resource_file, process, state as st};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use daedalus as d;
|
use daedalus as d;
|
||||||
@@ -633,18 +633,23 @@ pub async fn launch_minecraft(
|
|||||||
command.arg("--add-opens=jdk.internal/jdk.internal.misc=ALL-UNNAMED");
|
command.arg("--add-opens=jdk.internal/jdk.internal.misc=ALL-UNNAMED");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Fix ElyBy integration with this patch.
|
|
||||||
// [AR] Patch
|
// [AR] Patch
|
||||||
if credentials.access_token == "null" && credentials.refresh_token == "null" {
|
if credentials.account_type == AccountType::Pirate.as_lowercase_str() {
|
||||||
if version_jar == "1.16.4" || version_jar == "1.16.5" {
|
if version_jar == "1.16.4" || version_jar == "1.16.5" {
|
||||||
let invalid_url = "https://invalid.invalid";
|
let invalid_url = "https://invalid.invalid";
|
||||||
tracing::info!("✅ JVM args is patched by AstralRinth for MC {}", version_jar);
|
tracing::info!("[AR] • The launcher detected the launch of {} on the offline account. Applying multiplayer fixes.", version_jar);
|
||||||
command.arg("-Dminecraft.api.env=custom");
|
command.arg("-Dminecraft.api.env=custom");
|
||||||
command.arg(format!("-Dminecraft.api.auth.host={}", invalid_url));
|
command.arg(format!("-Dminecraft.api.auth.host={}", invalid_url));
|
||||||
command.arg(format!("-Dminecraft.api.account.host={}", invalid_url));
|
command.arg(format!("-Dminecraft.api.account.host={}", invalid_url));
|
||||||
command.arg(format!("-Dminecraft.api.session.host={}", invalid_url));
|
command.arg(format!("-Dminecraft.api.session.host={}", invalid_url));
|
||||||
command.arg(format!("-Dminecraft.api.services.host={}", invalid_url));
|
command.arg(format!("-Dminecraft.api.services.host={}", invalid_url));
|
||||||
}
|
}
|
||||||
|
} else if credentials.account_type == AccountType::ElyBy.as_lowercase_str() {
|
||||||
|
tracing::info!("[AR] • The launcher detected the launch of {} on the ElyBy account. Applying ElyBy Java Injector.", version_jar);
|
||||||
|
let path_buf = utils::get_or_download_ely_by_injector().await?;
|
||||||
|
let path = path_buf.to_str().unwrap();
|
||||||
|
tracing::info!("[AR] • ElyBy Java Injector path: {}", path);
|
||||||
|
command.arg(format!("-javaagent:{}=ely.by", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
command
|
command
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ impl AccountType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_lowercase_str(&self) -> String {
|
pub(crate) fn as_lowercase_str(&self) -> String {
|
||||||
self.as_str().to_lowercase()
|
self.as_str().to_lowercase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::state::db;
|
|||||||
///
|
///
|
||||||
use crate::{Result, State};
|
use crate::{Result, State};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
use tokio::{fs, io};
|
use tokio::{fs, io};
|
||||||
|
|
||||||
@@ -46,6 +47,119 @@ pub fn read_package_json() -> io::Result<Launcher> {
|
|||||||
Ok(launcher)
|
Ok(launcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ### AR • Ely By Injector
|
||||||
|
/// Returns the path to the ely by injector
|
||||||
|
/// If resource doesn't exist, it will be downloaded.
|
||||||
|
pub async fn get_or_download_ely_by_injector() -> Result<PathBuf> {
|
||||||
|
tracing::info!("[AR] • Attempting to get or download AuthLib Injector");
|
||||||
|
let state= State::get().await?;
|
||||||
|
let libraries_dir = state.directories.libraries_dir();
|
||||||
|
|
||||||
|
ensure_astralrinth_library_dir_exists(&libraries_dir).await?;
|
||||||
|
|
||||||
|
let (asset_name, download_url) = extract_ely_authlib_metadata("authlib-injector").await?;
|
||||||
|
let ely_by_injector = state.directories.libraries_dir().join(format!("astralrinth/{}", asset_name));
|
||||||
|
let path_in_libs = format!("astralrinth/{}", asset_name);
|
||||||
|
tracing::info!("[AR] • Path in libs: {}", path_in_libs);
|
||||||
|
|
||||||
|
if !ely_by_injector.exists() {
|
||||||
|
tracing::info!("[AR] • Doesn't exist, attempting to download AuthLib Injector from URL: {}", download_url);
|
||||||
|
let bytes = fetch_bytes_from_url(download_url.as_str()).await?;
|
||||||
|
write_file_to_libraries(&path_in_libs, &bytes).await?;
|
||||||
|
}
|
||||||
|
Ok(ely_by_injector)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### AR • Migration
|
||||||
|
/// Applying migration fix for SQLite database.
|
||||||
|
pub async fn apply_migration_fix(eol: &str) -> Result<bool> {
|
||||||
|
tracing::info!("[AR] • Attempting to apply migration fix");
|
||||||
|
let patched = db::apply_migration_fix(eol).await?;
|
||||||
|
if patched {
|
||||||
|
tracing::info!("[AR] • Successfully applied migration fix");
|
||||||
|
} else {
|
||||||
|
tracing::error!("[AR] • Failed to apply migration fix");
|
||||||
|
}
|
||||||
|
Ok(patched)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### AR • Updater
|
||||||
|
/// Initialize the update launcher.
|
||||||
|
pub async fn init_update_launcher(
|
||||||
|
download_url: &str,
|
||||||
|
local_filename: &str,
|
||||||
|
os_type: &str,
|
||||||
|
auto_update_supported: bool,
|
||||||
|
) -> Result<()> {
|
||||||
|
tracing::info!("[AR] • Initialize downloading from • {:?}", download_url);
|
||||||
|
tracing::info!("[AR] • Save local file name • {:?}", local_filename);
|
||||||
|
tracing::info!("[AR] • OS type • {}", os_type);
|
||||||
|
tracing::info!("[AR] • Auto update supported • {}", auto_update_supported);
|
||||||
|
|
||||||
|
if let Err(e) = update::get_resource(
|
||||||
|
download_url,
|
||||||
|
local_filename,
|
||||||
|
os_type,
|
||||||
|
auto_update_supported,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
eprintln!(
|
||||||
|
"[AR] • An error occurred! Failed to download the file: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!("[AR] • Code finishes without errors.");
|
||||||
|
process::exit(0)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ### AR • AuthLib (Ely By)
|
||||||
|
/// Initializes the AuthLib patching process.
|
||||||
|
///
|
||||||
|
/// Returns `true` if the authlib patched successfully.
|
||||||
|
pub async fn init_authlib_patching(
|
||||||
|
minecraft_version: &str,
|
||||||
|
is_mojang: bool,
|
||||||
|
) -> Result<bool> {
|
||||||
|
let minecraft_library_metadata = get_minecraft_library_metadata(minecraft_version).await?;
|
||||||
|
// Parses the AuthLib version from string
|
||||||
|
// Example output: "com.mojang:authlib:6.0.58" -> "6.0.58"
|
||||||
|
let authlib_version = minecraft_library_metadata.name.split(':').nth(2).unwrap_or("unknown");
|
||||||
|
let authlib_fullname_string = format!("authlib-{}.jar", authlib_version);
|
||||||
|
let authlib_fullname_str = authlib_fullname_string.as_str();
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
"[AR] • Attempting to download AuthLib -> {}.",
|
||||||
|
authlib_fullname_string
|
||||||
|
);
|
||||||
|
|
||||||
|
download_authlib(
|
||||||
|
&minecraft_library_metadata,
|
||||||
|
authlib_fullname_str,
|
||||||
|
minecraft_version,
|
||||||
|
is_mojang,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensures the `astralrinth/` directory exists inside the libraries directory.
|
||||||
|
async fn ensure_astralrinth_library_dir_exists(libraries_dir: &PathBuf) -> Result<()> {
|
||||||
|
let astralrinth_path = libraries_dir.join("astralrinth");
|
||||||
|
if !astralrinth_path.exists() {
|
||||||
|
tokio::fs::create_dir_all(&astralrinth_path).await.map_err(|e| {
|
||||||
|
tracing::error!("[AR] • Failed to create {} directory: {:?}", astralrinth_path.display(), e);
|
||||||
|
crate::ErrorKind::IOErrorOccurred {
|
||||||
|
error: format!("Failed to create {} directory: {}", astralrinth_path.display(), e),
|
||||||
|
}
|
||||||
|
.as_error()
|
||||||
|
})?;
|
||||||
|
tracing::info!("[AR] • Created missing {} directory", astralrinth_path.display());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// ### AR • Universal Write (IO) Function
|
/// ### AR • Universal Write (IO) Function
|
||||||
/// Saves the downloaded bytes to the `libraries` directory using the given relative path.
|
/// Saves the downloaded bytes to the `libraries` directory using the given relative path.
|
||||||
async fn write_file_to_libraries(
|
async fn write_file_to_libraries(
|
||||||
@@ -64,54 +178,26 @@ async fn write_file_to_libraries(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### AR • AuthLib (Ely By)
|
|
||||||
/// Initializes the AuthLib patching process.
|
|
||||||
///
|
|
||||||
/// Returns `true` if the authlib patched successfully.
|
|
||||||
pub async fn init_authlib_patching(
|
|
||||||
minecraft_version: &str,
|
|
||||||
is_mojang: bool,
|
|
||||||
) -> Result<bool> {
|
|
||||||
let minecraft_library_metadata = get_minecraft_library_metadata(minecraft_version).await?;
|
|
||||||
// Parses the AuthLib version from string
|
|
||||||
// Example output: "com.mojang:authlib:6.0.58" -> "6.0.58"
|
|
||||||
let authlib_version = minecraft_library_metadata.name.split(':').nth(2).unwrap_or("unknown");
|
|
||||||
|
|
||||||
tracing::info!(
|
|
||||||
"[AR] • Attempting to download AuthLib {}.",
|
|
||||||
authlib_version
|
|
||||||
);
|
|
||||||
|
|
||||||
download_authlib(
|
|
||||||
&minecraft_library_metadata,
|
|
||||||
authlib_version,
|
|
||||||
minecraft_version,
|
|
||||||
is_mojang,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ### AR • AuthLib (Ely By)
|
/// ### AR • AuthLib (Ely By)
|
||||||
/// Downloads the AuthLib file from Mojang libraries or Git Astralium services.
|
/// Downloads the AuthLib file from Mojang libraries or Git Astralium services.
|
||||||
async fn download_authlib(
|
async fn download_authlib(
|
||||||
minecraft_library_metadata: &Library,
|
minecraft_library_metadata: &Library,
|
||||||
authlib_version: &str,
|
authlib_fullname: &str,
|
||||||
minecraft_version: &str,
|
minecraft_version: &str,
|
||||||
is_mojang: bool,
|
is_mojang: bool,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let (url, path) = extract_download_info(minecraft_library_metadata, minecraft_version)?;
|
let (mut url, path) = extract_minecraft_local_download_info(minecraft_library_metadata, minecraft_version)?;
|
||||||
let mut download_url = url.to_string();
|
|
||||||
let full_path = state.directories.libraries_dir().join(path);
|
let full_path = state.directories.libraries_dir().join(path);
|
||||||
|
|
||||||
if !is_mojang {
|
if !is_mojang {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"[AR] • Attempting to download AuthLib from Git Astralium"
|
"[AR] • Attempting to download AuthLib from Git Astralium"
|
||||||
);
|
);
|
||||||
download_url = extract_ely_authlib_url(authlib_version).await?;
|
(_, url) = extract_ely_authlib_metadata(authlib_fullname).await?;
|
||||||
}
|
}
|
||||||
tracing::info!("[AR] • Downloading AuthLib from URL: {}", download_url);
|
tracing::info!("[AR] • Downloading AuthLib from URL: {}", url);
|
||||||
let bytes = fetch_bytes_from_url(&download_url).await?;
|
let bytes = fetch_bytes_from_url(&url).await?;
|
||||||
tracing::info!("[AR] • Will save to path: {}", full_path.to_str().unwrap());
|
tracing::info!("[AR] • Will save to path: {}", full_path.to_str().unwrap());
|
||||||
write_file_to_libraries(full_path.to_str().unwrap(), &bytes).await?;
|
write_file_to_libraries(full_path.to_str().unwrap(), &bytes).await?;
|
||||||
tracing::info!("[AR] • Successfully saved AuthLib to {:?}", full_path);
|
tracing::info!("[AR] • Successfully saved AuthLib to {:?}", full_path);
|
||||||
@@ -120,10 +206,10 @@ async fn download_authlib(
|
|||||||
|
|
||||||
/// ### AR • AuthLib (Ely By)
|
/// ### AR • AuthLib (Ely By)
|
||||||
/// Parses the ElyIntegration release JSON and returns the download URL for the given AuthLib version.
|
/// Parses the ElyIntegration release JSON and returns the download URL for the given AuthLib version.
|
||||||
async fn extract_ely_authlib_url(authlib_version: &str) -> Result<String> {
|
async fn extract_ely_authlib_metadata(authlib_fullname: &str) -> Result<(String, String)> {
|
||||||
let url = "https://git.astralium.su/api/v1/repos/didirus/ElyIntegration/releases/latest";
|
const URL: &str = "https://git.astralium.su/api/v1/repos/didirus/ElyIntegration/releases/latest";
|
||||||
|
|
||||||
let response = reqwest::get(url).await.map_err(|e| {
|
let response = reqwest::get(URL).await.map_err(|e| {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
"[AR] • Failed to fetch ElyIntegration release JSON: {:?}",
|
"[AR] • Failed to fetch ElyIntegration release JSON: {:?}",
|
||||||
e
|
e
|
||||||
@@ -142,29 +228,29 @@ async fn extract_ely_authlib_url(authlib_version: &str) -> Result<String> {
|
|||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let assets =
|
let assets = json
|
||||||
json.get("assets")
|
.get("assets")
|
||||||
.and_then(|v| v.as_array())
|
.and_then(|v| v.as_array())
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
crate::ErrorKind::ParseError {
|
crate::ErrorKind::ParseError {
|
||||||
reason: "Missing 'assets' array".into(),
|
reason: "Missing 'assets' array".into(),
|
||||||
}
|
}
|
||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let asset = assets
|
let asset = assets
|
||||||
.iter()
|
.iter()
|
||||||
.find(|a| {
|
.find(|a| {
|
||||||
a.get("name")
|
a.get("name")
|
||||||
.and_then(|n| n.as_str())
|
.and_then(|n| n.as_str())
|
||||||
.map(|n| n.contains(authlib_version))
|
.map(|n| n.contains(authlib_fullname))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
crate::ErrorKind::ParseError {
|
crate::ErrorKind::ParseError {
|
||||||
reason: format!(
|
reason: format!(
|
||||||
"No matching asset for authlib-{}.jar",
|
"No matching asset for {} in ElyIntegration JSON response.",
|
||||||
authlib_version
|
authlib_fullname
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
.as_error()
|
.as_error()
|
||||||
@@ -178,9 +264,21 @@ async fn extract_ely_authlib_url(authlib_version: &str) -> Result<String> {
|
|||||||
reason: "Missing 'browser_download_url'".into(),
|
reason: "Missing 'browser_download_url'".into(),
|
||||||
}
|
}
|
||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
Ok(download_url.to_string())
|
let asset_name = asset
|
||||||
|
.get("name")
|
||||||
|
.and_then(|n| n.as_str())
|
||||||
|
.ok_or_else(|| {
|
||||||
|
crate::ErrorKind::ParseError {
|
||||||
|
reason: "Missing 'name'".into(),
|
||||||
|
}
|
||||||
|
.as_error()
|
||||||
|
})?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
Ok((asset_name, download_url))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### AR • AuthLib (Ely By)
|
/// ### AR • AuthLib (Ely By)
|
||||||
@@ -188,10 +286,10 @@ async fn extract_ely_authlib_url(authlib_version: &str) -> Result<String> {
|
|||||||
///
|
///
|
||||||
/// Returns a tuple of references to the URL and path strings,
|
/// Returns a tuple of references to the URL and path strings,
|
||||||
/// or an error if the required metadata is missing.
|
/// or an error if the required metadata is missing.
|
||||||
fn extract_download_info<'a>(
|
fn extract_minecraft_local_download_info(
|
||||||
minecraft_library_metadata: &'a Library,
|
minecraft_library_metadata: &Library,
|
||||||
minecraft_version: &str,
|
minecraft_version: &str,
|
||||||
) -> Result<(&'a str, &'a str)> {
|
) -> Result<(String, String)> {
|
||||||
let artifact = minecraft_library_metadata
|
let artifact = minecraft_library_metadata
|
||||||
.downloads
|
.downloads
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -203,14 +301,14 @@ fn extract_download_info<'a>(
|
|||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let url = artifact.url.as_deref().ok_or_else(|| {
|
let url = artifact.url.clone().ok_or_else(|| {
|
||||||
crate::ErrorKind::MinecraftMetadataNotFound {
|
crate::ErrorKind::MinecraftMetadataNotFound {
|
||||||
minecraft_version: minecraft_version.to_string(),
|
minecraft_version: minecraft_version.to_string(),
|
||||||
}
|
}
|
||||||
.as_error()
|
.as_error()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let path = artifact.path.as_deref().ok_or_else(|| {
|
let path = artifact.path.clone().ok_or_else(|| {
|
||||||
crate::ErrorKind::MinecraftMetadataNotFound {
|
crate::ErrorKind::MinecraftMetadataNotFound {
|
||||||
minecraft_version: minecraft_version.to_string(),
|
minecraft_version: minecraft_version.to_string(),
|
||||||
}
|
}
|
||||||
@@ -220,7 +318,7 @@ fn extract_download_info<'a>(
|
|||||||
Ok((url, path))
|
Ok((url, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### AR • AuthLib (Ely By)
|
/// ### AR • Universal Fetch Bytes (IO)
|
||||||
/// Downloads bytes from the provided URL with a 15 second timeout.
|
/// Downloads bytes from the provided URL with a 15 second timeout.
|
||||||
async fn fetch_bytes_from_url(url: &str) -> Result<bytes::Bytes> {
|
async fn fetch_bytes_from_url(url: &str) -> Result<bytes::Bytes> {
|
||||||
// Create client instance with request timeout.
|
// Create client instance with request timeout.
|
||||||
@@ -249,9 +347,9 @@ async fn fetch_bytes_from_url(url: &str) -> Result<bytes::Bytes> {
|
|||||||
|
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
let status = response.status().to_string();
|
let status = response.status().to_string();
|
||||||
tracing::error!("[AR] • Failed to download authlib: HTTP {}", status);
|
tracing::error!("[AR] • Failed to download file: HTTP {}", status);
|
||||||
return Err(crate::ErrorKind::NetworkErrorOccurred {
|
return Err(crate::ErrorKind::NetworkErrorOccurred {
|
||||||
error: format!("Failed to download authlib: HTTP {status}"),
|
error: format!("Failed to download file: HTTP {status}"),
|
||||||
}
|
}
|
||||||
.as_error());
|
.as_error());
|
||||||
}
|
}
|
||||||
@@ -319,48 +417,3 @@ async fn get_minecraft_library_metadata(minecraft_version: &str) -> Result<Libra
|
|||||||
}
|
}
|
||||||
.as_error())
|
.as_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### AR • Migration
|
|
||||||
/// Applying migration fix for SQLite database.
|
|
||||||
pub async fn apply_migration_fix(eol: &str) -> Result<bool> {
|
|
||||||
tracing::info!("[AR] • Attempting to apply migration fix");
|
|
||||||
let patched = db::apply_migration_fix(eol).await?;
|
|
||||||
if patched {
|
|
||||||
tracing::info!("[AR] • Successfully applied migration fix");
|
|
||||||
} else {
|
|
||||||
tracing::error!("[AR] • Failed to apply migration fix");
|
|
||||||
}
|
|
||||||
Ok(patched)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ### AR • Updater
|
|
||||||
/// Initialize the update launcher.
|
|
||||||
pub async fn init_update_launcher(
|
|
||||||
download_url: &str,
|
|
||||||
local_filename: &str,
|
|
||||||
os_type: &str,
|
|
||||||
auto_update_supported: bool,
|
|
||||||
) -> Result<()> {
|
|
||||||
tracing::info!("[AR] • Initialize downloading from • {:?}", download_url);
|
|
||||||
tracing::info!("[AR] • Save local file name • {:?}", local_filename);
|
|
||||||
tracing::info!("[AR] • OS type • {}", os_type);
|
|
||||||
tracing::info!("[AR] • Auto update supported • {}", auto_update_supported);
|
|
||||||
|
|
||||||
if let Err(e) = update::get_resource(
|
|
||||||
download_url,
|
|
||||||
local_filename,
|
|
||||||
os_type,
|
|
||||||
auto_update_supported,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
eprintln!(
|
|
||||||
"[AR] • An error occurred! Failed to download the file: {}",
|
|
||||||
e
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!("[AR] • Code finishes without errors.");
|
|
||||||
process::exit(0)
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user