add hash check
This commit is contained in:
parent
f60555a442
commit
872bad1b25
102
Cargo.lock
generated
102
Cargo.lock
generated
@ -4,9 +4,13 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alterware-launcher"
|
name = "alterware-launcher"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"http_req",
|
"http_req",
|
||||||
|
"rand",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha1_smol",
|
||||||
"winres",
|
"winres",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -34,6 +38,17 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http_req"
|
name = "http_req"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@ -46,6 +61,12 @@ dependencies = [
|
|||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.63"
|
version = "0.3.63"
|
||||||
@ -73,6 +94,12 @@ version = "1.17.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b"
|
checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.59"
|
version = "1.0.59"
|
||||||
@ -91,6 +118,36 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.20"
|
version = "0.16.20"
|
||||||
@ -119,6 +176,12 @@ dependencies = [
|
|||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@ -134,6 +197,37 @@ name = "serde"
|
|||||||
version = "1.0.164"
|
version = "1.0.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.164"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.96"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1_smol"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
@ -188,6 +282,12 @@ version = "0.9.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.86"
|
version = "0.2.86"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "alterware-launcher"
|
name = "alterware-launcher"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
build = "res/build.rs"
|
build = "res/build.rs"
|
||||||
|
|
||||||
@ -14,6 +14,10 @@ panic = "abort"
|
|||||||
http_req = { version = "0.9.0", default-features = false, features = [
|
http_req = { version = "0.9.0", default-features = false, features = [
|
||||||
"rust-tls",
|
"rust-tls",
|
||||||
] }
|
] }
|
||||||
|
sha1_smol = "1.0.0"
|
||||||
|
serde = { version = "1.0.164", features = ["derive"] }
|
||||||
|
serde_json = "1.0.96"
|
||||||
|
rand = "0.8.5"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
winres = "0.1.12"
|
winres = "0.1.12"
|
||||||
|
@ -9,7 +9,7 @@ pub fn get_body(url: &str) -> Vec<u8> {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _get_body_string(url: &str) -> String {
|
pub fn get_body_string(url: &str) -> String {
|
||||||
String::from_utf8(get_body(url)).unwrap()
|
String::from_utf8(get_body(url)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
120
src/main.rs
120
src/main.rs
@ -1,10 +1,61 @@
|
|||||||
mod http;
|
mod http;
|
||||||
use std::path::PathBuf;
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize)]
|
||||||
|
struct CdnFile {
|
||||||
|
name: String,
|
||||||
|
size: u32,
|
||||||
|
hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Game<'a> {
|
||||||
|
engine: &'a str,
|
||||||
|
client: &'a str,
|
||||||
|
references: &'a [&'a str],
|
||||||
|
}
|
||||||
|
|
||||||
const MASTER: &str = "https://master.alterware.dev";
|
const MASTER: &str = "https://master.alterware.dev";
|
||||||
|
const GAMES: [Game; 2] = [
|
||||||
|
Game {
|
||||||
|
engine: "iw4",
|
||||||
|
client: "iw4-sp",
|
||||||
|
references: &["iw4sp.exe", "iw4mp.exe"],
|
||||||
|
},
|
||||||
|
Game {
|
||||||
|
engine: "iw5",
|
||||||
|
client: "iw5-mod",
|
||||||
|
references: &["iw5sp.exe", "iw5mp.exe", "iw5mp_server.exe"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
fn download_and_launch(url: &str, file_path: &PathBuf) {
|
fn file_get_sha1(path: &PathBuf) -> String {
|
||||||
|
let mut sha1 = sha1_smol::Sha1::new();
|
||||||
|
sha1.update(&fs::read(path).unwrap());
|
||||||
|
sha1.digest().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn download_and_launch(url: &str, file_path: &PathBuf, hash: Option<String>) {
|
||||||
|
if let Some(parent) = file_path.parent() {
|
||||||
|
if !parent.exists() {
|
||||||
|
fs::create_dir_all(parent).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if file_path.exists() && hash.is_some() {
|
||||||
|
let sha1_local = file_get_sha1(file_path).to_lowercase();
|
||||||
|
let sha1_remote = hash.unwrap().to_lowercase();
|
||||||
|
if sha1_local != sha1_remote {
|
||||||
|
println!("Local hash: {}", sha1_local);
|
||||||
|
println!("Remote hash: {}", sha1_remote);
|
||||||
|
println!("Updating {}...", file_path.display());
|
||||||
http::download_file(url, file_path);
|
http::download_file(url, file_path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Downloading {}...", file_path.display());
|
||||||
|
http::download_file(url, file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Launching {}...", file_path.display());
|
||||||
std::process::Command::new(file_path)
|
std::process::Command::new(file_path)
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -12,38 +63,45 @@ fn download_and_launch(url: &str, file_path: &PathBuf) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn get_hash(game: &Game) -> Option<String> {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let cdn_info: Vec<CdnFile> = serde_json::from_str(&http::get_body_string(
|
||||||
let game: String;
|
format!("{}/files.json?{}", MASTER, rand::Rng::gen_range(&mut rand::thread_rng(), 0..1000)).as_str(),
|
||||||
if args.len() > 1 {
|
))
|
||||||
game = String::from(&args[1]);
|
.unwrap();
|
||||||
} else {
|
|
||||||
// check if iw4sp.exe or iw4mp.exe exists
|
for file in cdn_info {
|
||||||
if std::path::Path::new("iw4sp.exe").exists() || std::path::Path::new("iw4mp.exe").exists()
|
if file.name == format!("{}/{}.exe", game.engine, game.client) {
|
||||||
{
|
return Some(file.hash);
|
||||||
game = String::from("iw4-sp");
|
|
||||||
} else if std::path::Path::new("iw5sp.exe").exists()
|
|
||||||
|| std::path::Path::new("iw5mp.exe").exists()
|
|
||||||
|| std::path::Path::new("iw5mp_server.exe").exists()
|
|
||||||
{
|
|
||||||
game = String::from("iw5-mod");
|
|
||||||
} else {
|
|
||||||
println!("No game specified and no game found in current directory");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if game == "iw4-sp" {
|
None
|
||||||
download_and_launch(
|
}
|
||||||
&format!("{}/iw4/iw4-sp.exe", MASTER),
|
|
||||||
&PathBuf::from("iw4-sp.exe"),
|
fn main() {
|
||||||
);
|
let args: Vec<String> = std::env::args().collect();
|
||||||
} else if game == "iw5-mod" {
|
let mut game: String = String::new();
|
||||||
download_and_launch(
|
if args.len() > 1 {
|
||||||
&format!("{}/iw5/iw5-mod.exe", MASTER),
|
game = String::from(&args[1]);
|
||||||
&PathBuf::from("iw5-mod.exe"),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
println!("Invalid game");
|
'main: for g in GAMES.iter() {
|
||||||
|
for r in g.references.iter() {
|
||||||
|
if std::path::Path::new(r).exists() {
|
||||||
|
game = String::from(g.client);
|
||||||
|
break 'main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for g in GAMES.iter() {
|
||||||
|
if g.client == game {
|
||||||
|
download_and_launch(
|
||||||
|
&format!("{}/{}/{}.exe?{}", MASTER, g.engine, g.client, rand::Rng::gen_range(&mut rand::thread_rng(), 0..1000)),
|
||||||
|
&PathBuf::from(format!("{}.exe", g.client)),
|
||||||
|
get_hash(g)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user