mirror of
https://github.com/alterware/alterware-launcher.git
synced 2025-12-04 07:17:50 +00:00
add --prerelease
This commit is contained in:
@@ -148,6 +148,8 @@
|
||||
- Skip installing redistributables
|
||||
- ```--redist```
|
||||
- Install or reinstall redistributables
|
||||
- ```--prerelease```
|
||||
- Update to prerelease version of clients (currently only available for IW4x) and launcher
|
||||
|
||||
##### Example:
|
||||
```shell
|
||||
@@ -168,6 +170,7 @@ alterware-launcher.exe iw4x --bonus -u --path "C:\Games\IW4x" --pass "-console"
|
||||
- `args`: Pass additional arguments to the game. Default: `""`.
|
||||
- `use_https`: Use HTTPS for downloads. Default: `true`.
|
||||
- `skip_redist`: Skip redistributable installations. Default: `false`.
|
||||
- `prerelease`: Update to prerelease version of clients and launcher. Default: `false`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ pub fn save_value(config_path: PathBuf, key: &str, value: bool) {
|
||||
"force_update" => config.force_update = value,
|
||||
"use_https" => config.use_https = value,
|
||||
"skip_redist" => config.skip_redist = value,
|
||||
"prerelease" => config.prerelease = value,
|
||||
_ => (),
|
||||
}
|
||||
save(config_path, config);
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
use semver::Version;
|
||||
|
||||
pub async fn latest_tag(owner: &str, repo: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||
pub async fn latest_tag(
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
prerelease: Option<bool>,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
if prerelease.unwrap_or(false) {
|
||||
latest_tag_prerelease(owner, repo).await
|
||||
} else {
|
||||
latest_tag_full(owner, repo).await
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn latest_tag_full(
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let github_body = crate::http_async::get_body_string(
|
||||
format!(
|
||||
"https://api.github.com/repos/{}/{}/releases/latest",
|
||||
@@ -8,34 +23,60 @@ pub async fn latest_tag(owner: &str, repo: &str) -> Result<String, Box<dyn std::
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| format!("Failed to fetch GitHub API: {}", e))?;
|
||||
|
||||
let github_json: serde_json::Value = serde_json::from_str(&github_body)?;
|
||||
let github_json: serde_json::Value = serde_json::from_str(&github_body)
|
||||
.map_err(|e| format!("Failed to parse GitHub API response: {}", e))?;
|
||||
|
||||
if let Some(tag_name) = github_json.get("tag_name") {
|
||||
if let Some(tag_name_str) = tag_name.as_str() {
|
||||
return Ok(tag_name_str.to_string().replace('"', ""));
|
||||
}
|
||||
let tag_name = github_json
|
||||
.get("tag_name")
|
||||
.ok_or("Missing tag_name field in GitHub response")?
|
||||
.as_str()
|
||||
.ok_or("tag_name is not a string")?;
|
||||
|
||||
Ok(tag_name.replace('"', ""))
|
||||
}
|
||||
|
||||
Ok("0.0.0".to_string())
|
||||
pub async fn latest_tag_prerelease(
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let github_body = crate::http_async::get_body_string(
|
||||
format!("https://api.github.com/repos/{}/{}/releases", owner, repo).as_str(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to fetch GitHub API: {}", e))?;
|
||||
|
||||
let github_json: serde_json::Value = serde_json::from_str(&github_body)
|
||||
.map_err(|e| format!("Failed to parse GitHub API response: {}", e))?;
|
||||
|
||||
let latest_release = github_json.get(0).ok_or("No releases found")?;
|
||||
|
||||
let tag_name = latest_release
|
||||
.get("tag_name")
|
||||
.ok_or("Release missing tag_name")?
|
||||
.as_str()
|
||||
.ok_or("tag_name is not a string")?;
|
||||
|
||||
Ok(tag_name.replace('"', ""))
|
||||
}
|
||||
|
||||
pub async fn latest_version(owner: &str, repo: &str) -> Version {
|
||||
match latest_tag(owner, repo).await {
|
||||
Ok(tag) => {
|
||||
pub async fn latest_version(
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
prerelease: Option<bool>,
|
||||
) -> Result<Version, Box<dyn std::error::Error>> {
|
||||
let tag = latest_tag(owner, repo, prerelease).await?;
|
||||
let cleaned_tag = tag.replace('v', "");
|
||||
Version::parse(&cleaned_tag).unwrap_or_else(|_| Version::new(0, 0, 0))
|
||||
}
|
||||
Err(_) => {
|
||||
crate::println_error!(
|
||||
"Failed to get latest version for {owner}/{repo}, assuming we are up to date."
|
||||
);
|
||||
Version::new(0, 0, 0)
|
||||
}
|
||||
}
|
||||
Version::parse(&cleaned_tag)
|
||||
.map_err(|e| format!("Failed to parse version '{}': {}", cleaned_tag, e).into())
|
||||
}
|
||||
|
||||
pub fn latest_release_url(owner: &str, repo: &str) -> String {
|
||||
pub fn download_url(owner: &str, repo: &str, tag: Option<&str>) -> String {
|
||||
if let Some(tag) = tag {
|
||||
format!("https://github.com/{owner}/{repo}/releases/download/{tag}")
|
||||
} else {
|
||||
format!("https://github.com/{owner}/{repo}/releases/latest")
|
||||
}
|
||||
}
|
||||
|
||||
12
src/iw4x.rs
12
src/iw4x.rs
@@ -7,8 +7,8 @@ use crate::structs;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
pub async fn remote_revision() -> u16 {
|
||||
match github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO).await {
|
||||
pub async fn remote_revision(prerelease: Option<bool>) -> u16 {
|
||||
match github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO, prerelease).await {
|
||||
Ok(tag) => misc::rev_to_int(&tag),
|
||||
Err(_) => {
|
||||
crate::println_error!("Failed to get latest version for {GH_IW4X_OWNER}/{GH_IW4X_REPO}, assuming we are up to date.");
|
||||
@@ -17,8 +17,8 @@ pub async fn remote_revision() -> u16 {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update(dir: &Path, cache: &mut structs::Cache) {
|
||||
let remote = remote_revision().await;
|
||||
pub async fn update(dir: &Path, cache: &mut structs::Cache, prerelease: Option<bool>) {
|
||||
let remote = remote_revision(prerelease).await;
|
||||
let local = misc::rev_to_int(&cache.iw4x_revision);
|
||||
|
||||
if remote <= local && dir.join("iw4x.dll").exists() {
|
||||
@@ -34,8 +34,8 @@ pub async fn update(dir: &Path, cache: &mut structs::Cache) {
|
||||
);
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/iw4x.dll",
|
||||
github::latest_release_url(GH_IW4X_OWNER, GH_IW4X_REPO)
|
||||
"{}/iw4x.dll",
|
||||
github::download_url(GH_IW4X_OWNER, GH_IW4X_REPO, Some(&format!("r{remote}")))
|
||||
),
|
||||
&dir.join("iw4x.dll"),
|
||||
)
|
||||
|
||||
14
src/main.rs
14
src/main.rs
@@ -115,7 +115,7 @@ fn setup_desktop_links(path: &Path, game: &Game) {
|
||||
async fn auto_install(path: &Path, game: &Game<'_>) {
|
||||
setup_client_links(game, path);
|
||||
setup_desktop_links(path, game);
|
||||
update(game, path, false, false, None, None).await;
|
||||
update(game, path, false, false, None, None, None).await;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -337,6 +337,7 @@ async fn update(
|
||||
force: bool,
|
||||
skip_iw4x_sp: Option<bool>,
|
||||
ignore_required_files: Option<bool>,
|
||||
prerelease: Option<bool>,
|
||||
) {
|
||||
info!("Starting update for game engine: {}", game.engine);
|
||||
info!("Update path: {}", dir.display());
|
||||
@@ -381,7 +382,7 @@ async fn update(
|
||||
};
|
||||
|
||||
if game.engine == "iw4" {
|
||||
iw4x::update(dir, &mut cache).await;
|
||||
iw4x::update(dir, &mut cache, prerelease).await;
|
||||
|
||||
let iw4x_dirs = vec!["iw4x", "zone/patch"];
|
||||
for d in &iw4x_dirs {
|
||||
@@ -651,6 +652,7 @@ async fn main() {
|
||||
println!(" --ignore-required-files: Skip required files check");
|
||||
println!(" --skip-redist: Skip redistributable installation");
|
||||
println!(" --redist: (Re-)Install redistributables");
|
||||
println!(" --prerelease: Update to prerelease version of clients and launcher");
|
||||
println!(
|
||||
"\nExample:\n alterware-launcher.exe iw4x --bonus --pass \"-console -nointro\""
|
||||
);
|
||||
@@ -779,8 +781,13 @@ async fn main() {
|
||||
*master_url = master_url.replace("https://", "http://");
|
||||
};
|
||||
|
||||
if arg_bool(&args, "--prerelease") {
|
||||
cfg.prerelease = true;
|
||||
arg_remove(&mut args, "--prerelease");
|
||||
}
|
||||
|
||||
if !arg_bool(&args, "--skip-launcher-update") && !cfg.skip_self_update {
|
||||
self_update::run(cfg.update_only).await;
|
||||
self_update::run(cfg.update_only, Some(cfg.prerelease)).await;
|
||||
} else {
|
||||
arg_remove(&mut args, "--skip-launcher-update");
|
||||
}
|
||||
@@ -927,6 +934,7 @@ async fn main() {
|
||||
cfg.force_update,
|
||||
Some(&game != "iw4x-sp"),
|
||||
Some(ignore_required_files),
|
||||
Some(cfg.prerelease),
|
||||
)
|
||||
.await;
|
||||
if !cfg.update_only {
|
||||
|
||||
@@ -3,20 +3,33 @@ use crate::global::*;
|
||||
|
||||
use semver::Version;
|
||||
|
||||
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).await;
|
||||
pub async fn self_update_available(prerelease: Option<bool>) -> bool {
|
||||
let current_version = match Version::parse(env!("CARGO_PKG_VERSION")) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to parse current version: {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let latest_version = match github::latest_version(GH_OWNER, GH_REPO, prerelease).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to get latest version: {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
current_version < latest_version
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub async fn run(_update_only: bool) {
|
||||
if self_update_available().await {
|
||||
pub async fn run(_update_only: bool, _prerelease: Option<bool>) {
|
||||
if self_update_available(None).await {
|
||||
crate::println_info!("A new version of the AlterWare launcher is available.");
|
||||
crate::println_info!(
|
||||
"Download it at {}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO)
|
||||
github::download_url(GH_OWNER, GH_REPO, None)
|
||||
);
|
||||
println!("Launching in 10 seconds..");
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
|
||||
@@ -37,7 +50,7 @@ pub fn restart() -> std::io::Error {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub async fn run(update_only: bool) {
|
||||
pub async fn run(update_only: bool, prerelease: Option<bool>) {
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::http_async;
|
||||
@@ -60,11 +73,11 @@ pub async fn run(update_only: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if self_update_available().await {
|
||||
if self_update_available(prerelease).await {
|
||||
crate::println_info!("Performing launcher self-update.");
|
||||
println!(
|
||||
"If you run into any issues, please download the latest version at {}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO)
|
||||
github::download_url(GH_OWNER, GH_REPO, None)
|
||||
);
|
||||
|
||||
let update_binary = PathBuf::from("alterware-launcher-update.exe");
|
||||
@@ -83,7 +96,7 @@ pub async fn run(update_only: bool) {
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/{}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO),
|
||||
github::download_url(GH_OWNER, GH_REPO, None),
|
||||
launcher_name
|
||||
),
|
||||
&file_path,
|
||||
|
||||
@@ -46,6 +46,8 @@ pub struct Config {
|
||||
pub use_https: bool,
|
||||
#[serde(default)]
|
||||
pub skip_redist: bool,
|
||||
#[serde(default)]
|
||||
pub prerelease: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@@ -60,6 +62,7 @@ impl Default for Config {
|
||||
engine: String::default(),
|
||||
use_https: true,
|
||||
skip_redist: false,
|
||||
prerelease: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user