fully replace http_req with reqwest
close #43 Should also help to either resolve or at least investigate seemingly random TLS & IO errors #64 #77
This commit is contained in:
parent
9de8543590
commit
02c3004231
@ -1,19 +1,21 @@
|
||||
use semver::Version;
|
||||
|
||||
pub fn latest_tag(owner: &str, repo: &str) -> String {
|
||||
let github_body = crate::http::get_body_string(
|
||||
pub async fn latest_tag(owner: &str, repo: &str) -> String {
|
||||
let github_body = crate::http_async::get_body_string(
|
||||
format!(
|
||||
"https://api.github.com/repos/{}/{}/releases/latest",
|
||||
owner, repo
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let github_json: serde_json::Value = serde_json::from_str(&github_body).unwrap();
|
||||
github_json["tag_name"].to_string().replace('"', "")
|
||||
}
|
||||
|
||||
pub fn latest_version(owner: &str, repo: &str) -> Version {
|
||||
let tag = latest_tag(owner, repo).replace('v', "");
|
||||
pub async fn latest_version(owner: &str, repo: &str) -> Version {
|
||||
let tag = latest_tag(owner, repo).await.replace('v', "");
|
||||
Version::parse(&tag).unwrap()
|
||||
}
|
||||
|
||||
|
84
src/http.rs
84
src/http.rs
@ -1,84 +0,0 @@
|
||||
use crate::global;
|
||||
use crate::misc;
|
||||
use std::{fs, io::Write, path::Path, str};
|
||||
|
||||
pub fn get_body(url: &str) -> Vec<u8> {
|
||||
let mut res: Vec<u8> = Vec::new();
|
||||
|
||||
match http_req::request::Request::new(&url.try_into().unwrap())
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
global::GH_OWNER,
|
||||
global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send(&mut res)
|
||||
{
|
||||
Ok(req) => {
|
||||
if req.status_code() == http_req::response::StatusCode::new(302)
|
||||
|| req.status_code() == http_req::response::StatusCode::new(301)
|
||||
{
|
||||
let location = req.headers().get("Location").unwrap().as_str();
|
||||
return get_body(location);
|
||||
}
|
||||
|
||||
if req.status_code() != http_req::response::StatusCode::new(200) {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not get body from {}, got {}",
|
||||
url,
|
||||
req.status_code()
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!("Could not get body from {}, got:\n{}", url, e));
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get_body_string(url: &str) -> String {
|
||||
String::from_utf8(get_body(url)).unwrap()
|
||||
}
|
||||
|
||||
pub fn download_file(url: &str, file_path: &Path) {
|
||||
let body = get_body(url);
|
||||
|
||||
match fs::File::create(file_path) {
|
||||
Ok(mut file) => match file.write_all(&body) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not write to file {}, got:\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
match e.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
fs::create_dir_all(file_path.parent().unwrap()).unwrap();
|
||||
return download_file(url, file_path);
|
||||
}
|
||||
std::io::ErrorKind::PermissionDenied => {
|
||||
misc::fatal_error(&format!(
|
||||
"Permission to {} denied.\n Please try:\n 1. Running the launcher as administrator.\n 2. Manually deleting the last downloaded file.\n 3. If your game is in the program files directory try moving it to another location.\n 4. Create an exception/exclusion in your Anti-Virus Software for either the last downloaded file or the entire game directory.\n\n\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
misc::fatal_error(&format!(
|
||||
"Could not create file {}, got:\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ use reqwest::Client;
|
||||
|
||||
use crate::misc;
|
||||
|
||||
pub async fn download_file(
|
||||
pub async fn download_file_progress(
|
||||
client: &Client,
|
||||
pb: &ProgressBar,
|
||||
url: &str,
|
||||
@ -58,3 +58,65 @@ pub async fn download_file(
|
||||
pb.set_message(String::default());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn download_file(url: &str, path: &PathBuf) -> Result<(), String> {
|
||||
let client = Client::new();
|
||||
match client
|
||||
.get(url)
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
crate::global::GH_OWNER,
|
||||
crate::global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(res) => {
|
||||
let body = res.bytes().await.or(Err("Failed to download file"))?;
|
||||
let mut file = File::create(path).or(Err("Failed to create file"))?;
|
||||
file.write_all(&body).or(Err("Failed to write to file"))?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not download file from {}, got:\n{}",
|
||||
url, e
|
||||
));
|
||||
Err("Could not download file".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_body(url: &str) -> Result<Vec<u8>, String> {
|
||||
let client = Client::new();
|
||||
match client
|
||||
.get(url)
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
crate::global::GH_OWNER,
|
||||
crate::global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(res) => {
|
||||
let body = res.bytes().await.or(Err("Failed to get body"))?;
|
||||
Ok(body.to_vec())
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!("Could not get body from {}, got:\n{}", url, e));
|
||||
Err("Could not get body".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_body_string(url: &str) -> Result<String, String> {
|
||||
let body = get_body(url).await?;
|
||||
Ok(String::from_utf8(body).unwrap())
|
||||
}
|
||||
|
16
src/iw4x.rs
16
src/iw4x.rs
@ -1,6 +1,6 @@
|
||||
use crate::github;
|
||||
use crate::global::*;
|
||||
use crate::http;
|
||||
use crate::http_async;
|
||||
use crate::misc;
|
||||
|
||||
use colored::*;
|
||||
@ -14,12 +14,12 @@ pub fn local_revision(dir: &Path) -> u16 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remote_revision() -> u16 {
|
||||
misc::rev_to_int(&github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO))
|
||||
pub async fn remote_revision() -> u16 {
|
||||
misc::rev_to_int(&github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO).await)
|
||||
}
|
||||
|
||||
pub fn update(dir: &Path) {
|
||||
let remote = remote_revision();
|
||||
pub async fn update(dir: &Path) {
|
||||
let remote = remote_revision().await;
|
||||
let local = local_revision(dir);
|
||||
|
||||
if remote <= local && dir.join("iw4x.dll").exists() {
|
||||
@ -39,12 +39,14 @@ pub fn update(dir: &Path) {
|
||||
"Downloading".bright_yellow(),
|
||||
misc::cute_path(&dir.join("iw4x.dll"))
|
||||
);
|
||||
http::download_file(
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/iw4x.dll",
|
||||
github::latest_release_url(GH_IW4X_OWNER, GH_IW4X_REPO)
|
||||
),
|
||||
&dir.join("iw4x.dll"),
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
fs::write(dir.join(".iw4xrevision"), format!("r{}", remote)).unwrap();
|
||||
}
|
||||
|
20
src/main.rs
20
src/main.rs
@ -1,7 +1,6 @@
|
||||
mod config;
|
||||
mod github;
|
||||
mod global;
|
||||
mod http;
|
||||
mod http_async;
|
||||
mod iw4x;
|
||||
mod misc;
|
||||
@ -271,7 +270,7 @@ async fn update_dir(
|
||||
fs::create_dir_all(parent).unwrap();
|
||||
}
|
||||
}
|
||||
http_async::download_file(
|
||||
http_async::download_file_progress(
|
||||
&client,
|
||||
pb,
|
||||
&format!("{}/{}", master_url, file.name),
|
||||
@ -292,15 +291,16 @@ async fn update(
|
||||
force: bool,
|
||||
skip_iw4x_sp: Option<bool>,
|
||||
master_url: &String,
|
||||
ignore_required_files: Option<bool>
|
||||
ignore_required_files: Option<bool>,
|
||||
) {
|
||||
let skip_iw4x_sp = skip_iw4x_sp.unwrap_or(false);
|
||||
let ignore_required_files = ignore_required_files.unwrap_or(false);
|
||||
|
||||
let cdn_info: Vec<CdnFile> = serde_json::from_str(&http::get_body_string(
|
||||
format!("{}/files.json", master_url).as_str(),
|
||||
))
|
||||
let res = http_async::get_body_string(format!("{}/files.json", master_url).as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
println!("{}", res);
|
||||
let cdn_info: Vec<CdnFile> = serde_json::from_str(&res).unwrap();
|
||||
|
||||
if !ignore_required_files && !game.required_files_exist(dir) {
|
||||
println!(
|
||||
@ -324,7 +324,7 @@ async fn update(
|
||||
}
|
||||
|
||||
if game.engine == "iw4" {
|
||||
iw4x::update(dir);
|
||||
iw4x::update(dir).await;
|
||||
|
||||
let iw4x_dirs = vec!["iw4x", "zone/patch"];
|
||||
for d in &iw4x_dirs {
|
||||
@ -558,7 +558,7 @@ async fn main() {
|
||||
};
|
||||
|
||||
if !arg_bool(&args, "--skip-launcher-update") && !cfg.skip_self_update {
|
||||
self_update::run(cfg.update_only);
|
||||
self_update::run(cfg.update_only).await;
|
||||
} else {
|
||||
arg_remove(&mut args, "--skip-launcher-update");
|
||||
}
|
||||
@ -593,7 +593,9 @@ async fn main() {
|
||||
cfg.args = String::default();
|
||||
}
|
||||
|
||||
let games_json = http::get_body_string(format!("{}/games.json", master_url).as_str());
|
||||
let games_json = http_async::get_body_string(format!("{}/games.json", master_url).as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
let games: Vec<Game> = serde_json::from_str(&games_json).unwrap();
|
||||
|
||||
let mut game: String = String::new();
|
||||
|
@ -5,9 +5,9 @@ use semver::Version;
|
||||
#[cfg(not(windows))]
|
||||
use std::{thread, time};
|
||||
|
||||
pub fn self_update_available() -> bool {
|
||||
pub async fn self_update_available() -> bool {
|
||||
let current_version: Version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
||||
let latest_version = github::latest_version(GH_OWNER, GH_REPO);
|
||||
let latest_version = github::latest_version(GH_OWNER, GH_REPO).await;
|
||||
|
||||
current_version < latest_version
|
||||
}
|
||||
@ -39,10 +39,10 @@ pub fn restart() -> std::io::Error {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn run(update_only: bool) {
|
||||
pub async fn run(update_only: bool) {
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::http;
|
||||
use crate::http_async;
|
||||
use crate::misc;
|
||||
|
||||
let working_dir = std::env::current_dir().unwrap();
|
||||
@ -62,7 +62,7 @@ pub fn run(update_only: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if self_update_available() {
|
||||
if self_update_available().await {
|
||||
println!("Performing launcher self-update.");
|
||||
println!(
|
||||
"If you run into any issues, please download the latest version at {}",
|
||||
@ -82,14 +82,16 @@ pub fn run(update_only: bool) {
|
||||
"alterware-launcher.exe"
|
||||
};
|
||||
|
||||
http::download_file(
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/{}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO),
|
||||
launcher_name
|
||||
),
|
||||
&file_path,
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
if !file_path.exists() {
|
||||
println!("Failed to download launcher update.");
|
||||
|
Loading…
Reference in New Issue
Block a user