#![allow(dead_code)]
use std::env::var_os;
use std::ffi::OsString;
use std::fs;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use regex::Regex;
use shellexpand;
fn default_base() -> PathBuf {
if let Some(base_dir) = var_os("SC2_PROXY_BASE") {
Path::new(&base_dir).to_path_buf()
} else if cfg!(windows) {
Path::new("C:/Program Files (x86)/StarCraft II").to_path_buf()
} else if cfg!(target_os = "macos") {
Path::new("/Applications/StarCraft II").to_path_buf()
} else if cfg!(linux) {
Path::new(&shellexpand::tilde("~/StarCraft II").into_owned()).to_path_buf()
} else {
panic!("Unknown system, use SC2_PROXY_BASE env var");
}
}
fn bin_path() -> PathBuf {
if let Some(base_dir) = var_os("SC2_PROXY_BIN") {
Path::new(&base_dir).to_path_buf()
} else if cfg!(windows) {
Path::new("SC2_x64.exe").to_path_buf()
} else if cfg!(target_os = "macos") {
Path::new("SC2.app/Contents/MacOS/SC2").to_path_buf()
} else if cfg!(linux) {
Path::new(&shellexpand::tilde("SC2_x64").into_owned()).to_path_buf()
} else {
panic!("Unknown system, use SC2_PROXY_BIN env var");
}
}
fn cwd() -> Option<PathBuf> {
if let Some(base_dir) = var_os("SC2_PROXY_CWD") {
Some(Path::new(&base_dir).to_path_buf())
} else if cfg!(windows) {
Some(Path::new("Support64").to_path_buf())
} else {
None
}
}
fn latest_executeble_path(versions_dir: PathBuf) -> PathBuf {
let (max_version, path) = fs::read_dir(versions_dir)
.unwrap()
.filter_map(|entry| -> Option<(u64, PathBuf)> {
let path = entry.unwrap().path();
let name = path
.file_name()
.unwrap()
.to_str()
.expect("Invalid unicode in folder name");
if path.metadata().unwrap().is_dir() && name.starts_with("Base") {
let version: &str = name.split_at(4).1;
version.parse::<u64>().ok().map(|v| (v, path.to_path_buf()))
} else {
None
}
})
.max_by_key(|(v, _)| v.clone())
.expect("No downloaded SC2 binaries found");
if max_version < 55958 {
panic!("Your SC2 binary is too old. Upgrade to 3.16.1 or newer.");
}
path.join(bin_path())
}
fn execute_info_path() -> Option<PathBuf> {
let env_skip_os_str = var_os("SC2_PROXY_SKIP_EXECUTE_INFO").unwrap_or(OsString::new());
let env_skip_str = env_skip_os_str
.to_str()
.expect("SC2_PROXY_SKIP_EXECUTE_INFO was invalid unicode");
if env_skip_str == "" || env_skip_str == "0" {
None
} else if cfg!(windows) {
Some(
Path::new(&shellexpand::tilde("~\\Documents\\StarCraft II\\ExecuteInfo.txt").into_owned())
.to_path_buf(),
)
} else if cfg!(target_os = "macos") {
Some(Path::new("/Library/Application Support/Blizzard/StarCraft II/ExecuteInfo.txt").to_path_buf())
} else {
None
}
}
fn read_execute_info(path: PathBuf) -> Option<PathBuf> {
let mut f = fs::File::open(path).ok()?;
let mut contents = String::new();
f.read_to_string(&mut contents)
.expect("Could not read ExecuteInfo.txt");
let re = Regex::new(r" = (.*)Versions").unwrap();
let base = Path::new(re.captures(&contents)?.get(1).unwrap().as_str()).to_path_buf();
if base.exists() {
Some(base)
} else {
None
}
}
pub fn base_dir() -> PathBuf {
if let Some(base_dir) = var_os("SC2_PROXY_BASE") {
Path::new(&base_dir).to_path_buf()
} else if let Some(ei_path) = execute_info_path() {
read_execute_info(ei_path).unwrap_or_else(|| default_base())
} else {
default_base()
}
}
pub fn executable() -> PathBuf {
latest_executeble_path(base_dir().join(Path::new("Versions")))
}
pub fn cwd_dir() -> PathBuf {
let base = base_dir();
if let Some(c) = cwd() {
base.join(c)
} else {
base
}
}
pub fn replay_dir() -> PathBuf {
base_dir().join(Path::new("Replays").to_path_buf())
}
pub fn map_dir() -> PathBuf {
base_dir().join(Path::new("Maps").to_path_buf())
}