Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
572c66cc16 | |||
cf87f7c741 | |||
dc8b01b4c8 | |||
9e8893ce75 | |||
6f92e1fb71 | |||
96c3e504f8 | |||
00c14d2a02 | |||
0378f19a75 | |||
64f4ae6429 | |||
b2cc21aed0 | |||
dc5957ea41 | |||
54abce4d30 | |||
6ae33cdcb3 | |||
c9d30fa95a | |||
dc81430f6b | |||
9c122506ce | |||
f2ba92c31d | |||
c92fb88e83 | |||
1e0e0090f5 | |||
48f6a96a01 |
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
@ -18,14 +18,21 @@ jobs:
|
|||||||
upload-assets:
|
upload-assets:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
include:
|
||||||
- ubuntu-20.04
|
- target: x86_64-unknown-linux-gnu
|
||||||
- windows-latest
|
os: ubuntu-20.04
|
||||||
|
- target: i686-unknown-linux-gnu
|
||||||
|
os: ubuntu-20.04
|
||||||
|
- target: x86_64-pc-windows-msvc
|
||||||
|
os: windows-latest
|
||||||
|
- target: i686-pc-windows-msvc
|
||||||
|
os: windows-latest
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: taiki-e/upload-rust-binary-action@v1
|
- uses: taiki-e/upload-rust-binary-action@v1
|
||||||
with:
|
with:
|
||||||
|
target: ${{ matrix.target }}
|
||||||
bin: alterware-launcher
|
bin: alterware-launcher
|
||||||
tar: unix
|
tar: unix
|
||||||
zip: windows
|
zip: windows
|
||||||
|
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -30,7 +30,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alterware-launcher"
|
name = "alterware-launcher"
|
||||||
version = "0.5.1"
|
version = "0.5.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored",
|
"colored",
|
||||||
"http_req",
|
"http_req",
|
||||||
@ -42,7 +42,6 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"sha1_smol",
|
"sha1_smol",
|
||||||
"steamlocate",
|
"steamlocate",
|
||||||
"windows-sys",
|
|
||||||
"winres",
|
"winres",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
@ -313,9 +312,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http_req"
|
name = "http_req"
|
||||||
version = "0.9.2"
|
version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f680177f2ebe4aabd573d07b322d15a5e0fbc97cd739fd627b08043c89041f8"
|
checksum = "42ce34c74ec562d68f2c23a532c62c1332ff1d1b6147fd118bd1938e090137d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls",
|
||||||
"unicase",
|
"unicase",
|
||||||
@ -707,9 +706,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "self-replace"
|
name = "self-replace"
|
||||||
version = "1.3.6"
|
version = "1.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c56335359191626938ef6fdeb478f9f6a7c6020254d7f4641c7d810369fa0ec1"
|
checksum = "525db198616b2bcd0f245daf7bfd8130222f7ee6af9ff9984c19a61bf1160c55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand 1.9.0",
|
"fastrand 1.9.0",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@ -718,9 +717,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.18"
|
version = "1.0.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
@ -744,9 +743,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.106"
|
version = "1.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
|
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
14
Cargo.toml
14
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "alterware-launcher"
|
name = "alterware-launcher"
|
||||||
version = "0.5.1"
|
version = "0.5.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
build = "res/build.rs"
|
build = "res/build.rs"
|
||||||
|
|
||||||
@ -15,25 +15,21 @@ panic = "abort"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
http_req = { version = "0.9.2", default-features = false, features = [
|
http_req = { version = "0.9.3", default-features = false, features = [
|
||||||
"rust-tls",
|
"rust-tls",
|
||||||
] }
|
] }
|
||||||
sha1_smol = "1.0.0"
|
sha1_smol = "1.0.0"
|
||||||
serde = { version = "1.0.188", features = ["derive"] }
|
serde = { version = "1.0.188", features = ["derive"] }
|
||||||
serde_json = "1.0.106"
|
serde_json = "1.0.107"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
semver = "1.0.18"
|
semver = "1.0.19"
|
||||||
zip = "0.6.6"
|
zip = "0.6.6"
|
||||||
colored = "2.0.4"
|
colored = "2.0.4"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
steamlocate = "2.0.0-alpha.0"
|
steamlocate = "2.0.0-alpha.0"
|
||||||
mslnk = "0.1.8"
|
mslnk = "0.1.8"
|
||||||
# https://github.com/mitsuhiko/self-replace/pull/16/
|
self-replace = "1.3.7"
|
||||||
windows-sys = { version = "0.48", features = [
|
|
||||||
"Win32_Security",
|
|
||||||
] }
|
|
||||||
self-replace = "1.3.6"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
winres = "0.1.12"
|
winres = "0.1.12"
|
||||||
|
@ -13,7 +13,19 @@ pub fn load(config_path: PathBuf) -> Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(config_path: PathBuf, config: Config) {
|
pub fn save(config_path: PathBuf, config: Config) {
|
||||||
fs::write(config_path, serde_json::to_string(&config).unwrap()).unwrap();
|
match fs::write(
|
||||||
|
config_path.clone(),
|
||||||
|
serde_json::to_string_pretty(&config).unwrap(),
|
||||||
|
) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => match e.kind() {
|
||||||
|
std::io::ErrorKind::NotFound => {
|
||||||
|
fs::create_dir_all(config_path.parent().unwrap()).unwrap();
|
||||||
|
save(config_path, config);
|
||||||
|
}
|
||||||
|
_ => println!("Could not save config file, got:\n{}\n", e),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_value(config_path: PathBuf, key: &str, value: bool) {
|
pub fn save_value(config_path: PathBuf, key: &str, value: bool) {
|
||||||
|
76
src/http.rs
76
src/http.rs
@ -1,20 +1,40 @@
|
|||||||
|
use crate::global;
|
||||||
|
use crate::misc;
|
||||||
use std::{fs, io::Write, path::Path, str};
|
use std::{fs, io::Write, path::Path, str};
|
||||||
|
|
||||||
pub fn get_body(url: &str) -> Vec<u8> {
|
pub fn get_body(url: &str) -> Vec<u8> {
|
||||||
let mut res: Vec<u8> = Vec::new();
|
let mut res: Vec<u8> = Vec::new();
|
||||||
let req = http_req::request::Request::new(&url.try_into().unwrap())
|
|
||||||
|
match http_req::request::Request::new(&url.try_into().unwrap())
|
||||||
.header(
|
.header(
|
||||||
"User-Agent",
|
"User-Agent",
|
||||||
"AlterWare Launcher | github.com/mxve/alterware-launcher",
|
&format!(
|
||||||
|
"AlterWare Launcher | github.com/{}/{}",
|
||||||
|
global::GH_OWNER,
|
||||||
|
global::GH_REPO
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.send(&mut res)
|
.send(&mut res)
|
||||||
.unwrap_or_else(|error| {
|
{
|
||||||
panic!("\n\n{}:\n{:?}", "Error", error);
|
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(302) {
|
if req.status_code() != http_req::response::StatusCode::new(200) {
|
||||||
let location = req.headers().get("Location").unwrap().as_str();
|
misc::fatal_error(&format!(
|
||||||
return get_body(location);
|
"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
|
res
|
||||||
@ -27,10 +47,38 @@ pub fn get_body_string(url: &str) -> String {
|
|||||||
pub fn download_file(url: &str, file_path: &Path) {
|
pub fn download_file(url: &str, file_path: &Path) {
|
||||||
let body = get_body(url);
|
let body = get_body(url);
|
||||||
|
|
||||||
let mut f = fs::File::create(file_path).unwrap_or_else(|error| {
|
match fs::File::create(file_path) {
|
||||||
panic!("\n\n{}:\n{:?}", "Error", error);
|
Ok(mut file) => match file.write_all(&body) {
|
||||||
});
|
Ok(_) => (),
|
||||||
f.write_all(&body).unwrap_or_else(|error| {
|
Err(e) => {
|
||||||
panic!("\n\n{}:\n{:?}", "Error", error);
|
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\n\n{}",
|
||||||
|
file_path.to_str().unwrap(),
|
||||||
|
e
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
misc::fatal_error(&format!(
|
||||||
|
"Could not create file {}, got:\n{}",
|
||||||
|
file_path.to_str().unwrap(),
|
||||||
|
e
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
42
src/main.rs
42
src/main.rs
@ -37,26 +37,35 @@ fn get_installed_games(games: &Vec<Game>) -> Vec<(u32, PathBuf)> {
|
|||||||
installed_games
|
installed_games
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn create_shortcut(path: &Path, target: &Path, icon: String, args: String) {
|
||||||
|
if let Ok(mut sl) = ShellLink::new(target) {
|
||||||
|
sl.set_arguments(Some(args));
|
||||||
|
sl.set_icon_location(Some(icon));
|
||||||
|
sl.create_lnk(path).unwrap_or_else(|error| {
|
||||||
|
println!("Error creating shortcut.\n{:#?}", error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
println!("Error creating shortcut.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn setup_client_links(game: &Game, game_dir: &Path) {
|
fn setup_client_links(game: &Game, game_dir: &Path) {
|
||||||
if game.client.len() > 1 {
|
if game.client.len() > 1 {
|
||||||
println!("Multiple clients installed, use the shortcuts (launch-<client>.lnk in the game directory or on the desktop) to launch a specific client.");
|
println!("Multiple clients installed, use the shortcuts (launch-<client>.lnk in the game directory or on the desktop) to launch a specific client.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = game_dir.join("alterware-launcher.exe");
|
|
||||||
|
|
||||||
for c in game.client.iter() {
|
for c in game.client.iter() {
|
||||||
let lnk = game_dir.join(format!("launch-{}.lnk", c));
|
create_shortcut(
|
||||||
|
&game_dir.join(format!("launch-{}.lnk", c)),
|
||||||
let mut sl = ShellLink::new(target.clone()).unwrap();
|
&game_dir.join("alterware-launcher.exe"),
|
||||||
sl.set_arguments(Some(c.to_string()));
|
|
||||||
sl.set_icon_location(Some(
|
|
||||||
game_dir
|
game_dir
|
||||||
.join(format!("{}.exe", c))
|
.join(format!("{}.exe", c))
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
));
|
c.to_string(),
|
||||||
sl.create_lnk(&lnk).unwrap();
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,19 +80,15 @@ fn setup_desktop_links(path: &Path, game: &Game) {
|
|||||||
std::env::var("USERPROFILE").unwrap()
|
std::env::var("USERPROFILE").unwrap()
|
||||||
));
|
));
|
||||||
|
|
||||||
let target = path.join("alterware-launcher.exe");
|
|
||||||
|
|
||||||
for c in game.client.iter() {
|
for c in game.client.iter() {
|
||||||
let lnk = desktop.join(format!("{}.lnk", c));
|
create_shortcut(
|
||||||
|
&desktop.join(format!("{}.lnk", c)),
|
||||||
let mut sl = ShellLink::new(target.clone()).unwrap();
|
&path.join("alterware-launcher.exe"),
|
||||||
sl.set_arguments(Some(c.to_string()));
|
|
||||||
sl.set_icon_location(Some(
|
|
||||||
path.join(format!("{}.exe", c))
|
path.join(format!("{}.exe", c))
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
));
|
c.to_string(),
|
||||||
sl.create_lnk(lnk).unwrap();
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,6 +378,7 @@ fn main() {
|
|||||||
|
|
||||||
if arg_bool(&args, "--bonus") {
|
if arg_bool(&args, "--bonus") {
|
||||||
cfg.download_bonus_content = true;
|
cfg.download_bonus_content = true;
|
||||||
|
cfg.ask_bonus_content = false;
|
||||||
arg_remove(&mut args, "--bonus");
|
arg_remove(&mut args, "--bonus");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
pub fn get_file_sha1(path: &PathBuf) -> String {
|
pub fn get_file_sha1(path: &PathBuf) -> String {
|
||||||
let mut sha1 = sha1_smol::Sha1::new();
|
let mut sha1 = sha1_smol::Sha1::new();
|
||||||
sha1.update(&fs::read(path).unwrap());
|
sha1.update(&fs::read(path).unwrap());
|
||||||
@ -18,3 +20,9 @@ pub fn rev_to_int(rev: &str) -> u16 {
|
|||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fatal_error(error: &str) {
|
||||||
|
println!("\n\n{}:\n{}", "Error".bright_red(), error);
|
||||||
|
stdin();
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ pub fn run(update_only: bool) {
|
|||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
use crate::http;
|
use crate::http;
|
||||||
|
use crate::misc;
|
||||||
|
|
||||||
let working_dir = std::env::current_dir().unwrap();
|
let working_dir = std::env::current_dir().unwrap();
|
||||||
let files = fs::read_dir(&working_dir).unwrap();
|
let files = fs::read_dir(&working_dir).unwrap();
|
||||||
@ -60,10 +61,17 @@ pub fn run(update_only: bool) {
|
|||||||
fs::remove_file(&update_binary).unwrap();
|
fs::remove_file(&update_binary).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let launcher_name = if cfg!(target_arch = "x86") {
|
||||||
|
"alterware-launcher-x86.exe"
|
||||||
|
} else {
|
||||||
|
"alterware-launcher.exe"
|
||||||
|
};
|
||||||
|
println!("{}", launcher_name);
|
||||||
http::download_file(
|
http::download_file(
|
||||||
&format!(
|
&format!(
|
||||||
"{}/download/alterware-launcher.exe",
|
"{}/download/{}",
|
||||||
github::latest_release_url(GH_OWNER, GH_REPO)
|
github::latest_release_url(GH_OWNER, GH_REPO),
|
||||||
|
launcher_name
|
||||||
),
|
),
|
||||||
&file_path,
|
&file_path,
|
||||||
);
|
);
|
||||||
@ -75,9 +83,13 @@ pub fn run(update_only: bool) {
|
|||||||
|
|
||||||
self_replace::self_replace("alterware-launcher-update.exe").unwrap();
|
self_replace::self_replace("alterware-launcher-update.exe").unwrap();
|
||||||
fs::remove_file(&file_path).unwrap();
|
fs::remove_file(&file_path).unwrap();
|
||||||
println!("Launcher updated. Please run it again.");
|
println!(
|
||||||
|
"Launcher updated. View the changelog at https://github.com/{}/{}/releases/latest",
|
||||||
|
GH_OWNER, GH_REPO,
|
||||||
|
);
|
||||||
|
println!("Please restart the launcher.");
|
||||||
if !update_only {
|
if !update_only {
|
||||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
misc::stdin();
|
||||||
}
|
}
|
||||||
std::process::exit(201);
|
std::process::exit(201);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user