1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::{fs, path::Path};
use clap::{Arg, Command};
fn get_zip_url(major: u32, minor: u32) -> reqwest::Url {
reqwest::Url::parse(&format!(
"https://secure.byond.com/download/build/{0}/{0}.{1}_byond.zip",
major, minor
))
.unwrap()
}
fn main() {
let matches = Command::new("byond_get")
.disable_version_flag(true)
.arg(
Arg::new("major")
.help("major BYOND version to fetch (e.g. 513)")
.required(true)
.takes_value(true),
)
.arg(
Arg::new("minor")
.help("minor BYOND version to fetch (e.g. 1539)")
.required(true)
.takes_value(true),
)
.arg(
Arg::new("destination")
.allow_invalid_utf8(true)
.help("directory to extract the BYOND build into")
.required(true)
.takes_value(true),
)
.get_matches();
let major = matches.value_of("major").unwrap();
let minor = matches.value_of("minor").unwrap();
let destination = matches.value_of_os("destination").unwrap();
let major = major
.parse::<u32>()
.expect("major version must be an integer");
let minor = minor
.parse::<u32>()
.expect("minor version must be an integer");
let destination = Path::new(destination);
if destination.exists() {
panic!("path {:?} already exists", destination);
}
let resp = reqwest::blocking::get(get_zip_url(major, minor))
.unwrap()
.bytes()
.unwrap();
let stream = std::io::Cursor::new(resp);
let mut archive = zip::ZipArchive::new(stream).unwrap();
for i in 0..archive.len() {
let mut file = archive.by_index(i).unwrap();
if file.is_dir() {
continue;
}
let local_path = file
.enclosed_name()
.unwrap()
.strip_prefix("byond/")
.unwrap();
let mut path = destination.to_path_buf();
path.push(local_path);
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
println!("Extracting {} bytes to {:?}", file.size(), path);
let mut out = fs::File::create(&path).unwrap();
std::io::copy(&mut file, &mut out).unwrap();
}
}