Added build config
This commit is contained in:
parent
d8407adf4c
commit
fbf1b9241b
|
|
@ -313,6 +313,12 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.2"
|
||||
|
|
@ -508,7 +514,7 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
|
@ -521,6 +527,12 @@ version = "0.12.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
|
|
@ -647,7 +659,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -980,18 +1002,18 @@ checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.32"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
|
@ -1135,18 +1157,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.186"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.186"
|
||||
version = "1.0.195"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1176,6 +1198,19 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38"
|
||||
dependencies = [
|
||||
"indexmap 2.1.0",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
|
|
@ -1250,9 +1285,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1271,9 +1306,11 @@ dependencies = [
|
|||
"indicatif",
|
||||
"md5",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"term_size",
|
||||
"tokio",
|
||||
"winreg 0.51.0",
|
||||
"winreg 0.52.0",
|
||||
"winres",
|
||||
"zip-extract",
|
||||
]
|
||||
|
|
@ -1492,6 +1529,12 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.0"
|
||||
|
|
@ -1800,9 +1843,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.51.0"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "937f3df7948156640f46aacef17a70db0de5917bda9c92b0f751f3a955b588fc"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
|
|
|
|||
|
|
@ -11,19 +11,21 @@ colored = "2.0.4"
|
|||
chrono = "0.4.26"
|
||||
dirs = "5.0.1"
|
||||
indicatif = "0.17.6"
|
||||
reqwest = { version = "0.11.20", features = ["stream"]}
|
||||
reqwest = { version = "0.11.20", features = ["stream"] }
|
||||
futures = "0.3.28"
|
||||
tokio = { version = "1.32.0", features=["full"]}
|
||||
tokio = { version = "1.32.0", features = ["full"] }
|
||||
futures-util = "0.3.28"
|
||||
md5 = "0.7.0"
|
||||
zip-extract = "0.1.2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winreg = "0.51.0"
|
||||
winreg = "0.52.0"
|
||||
|
||||
[build-dependencies]
|
||||
chrono = "0.4.26"
|
||||
winres = "0.1.12"
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
serde_yaml = "0.9.30"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
.d8888b. Y88b d88P 888b 888 88888888888 d8888 Y88b d88P
|
||||
d88P Y88b Y88b d88P 8888b 888 888 d88888 Y88b d88P
|
||||
Y88b. Y88o88P 88888b 888 888 d88P888 Y88o88P
|
||||
\"Y888b. Y888P 888Y88b 888 888 d88P 888 Y888P
|
||||
\"Y88b. 888 888 Y88b888 888 d88P 888 d888b
|
||||
\"888 888 888 Y88888 888 d88P 888 d88888b
|
||||
Y88b d88P 888 888 Y8888 888 d8888888888 d88P Y88b
|
||||
\"Y8888P\" 888 888 Y888 888 d88P 888 d88P Y88b
|
||||
|
||||
175
build.rs
175
build.rs
|
|
@ -1,30 +1,161 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use winres::WindowsResource;
|
||||
fn main() {
|
||||
// Get the current build date and time
|
||||
let build_date = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string();
|
||||
use serde::Deserialize;
|
||||
|
||||
// Write the build date to a file
|
||||
/// CHANGES
|
||||
/// [+] Use rust CFG for build (not sure)
|
||||
/// [+] A build config
|
||||
/// [+] Ascii is now premade due to the result always being static anyways
|
||||
/// [+] Cut down into functions
|
||||
|
||||
const ENGLISH_LANGUAGE: u16 = 0x0409;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct BuildConfig {
|
||||
#[serde(rename = "Ascii")]
|
||||
pub ascii: AsciiConfig,
|
||||
#[serde(rename = "Runtime")]
|
||||
pub runtime: RuntimeConfig,
|
||||
#[serde(rename = "Windows")]
|
||||
pub windows: WindowsConfig,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AsciiConfig {
|
||||
#[serde(rename = "Location")]
|
||||
pub location: String,
|
||||
#[serde(rename = "Padding")]
|
||||
pub padding: usize,
|
||||
#[serde(rename = "FallbackText")]
|
||||
pub fallback_text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RuntimeConfig {
|
||||
#[serde(rename = "SetupUrl")]
|
||||
pub setup_url: String,
|
||||
#[serde(rename = "BaseUrl")]
|
||||
pub base_url: String,
|
||||
#[serde(rename = "ThreadCount")]
|
||||
pub thread_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct WindowsConfig {
|
||||
#[serde(rename = "Icon")]
|
||||
pub icon: String,
|
||||
#[serde(rename = "Resources")]
|
||||
pub resources: HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn get_padding(size: usize) -> String {
|
||||
" ".repeat(size)
|
||||
}
|
||||
|
||||
fn out_dir() -> PathBuf {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = format!("{}/build_date.txt", out_dir);
|
||||
fs::write(&dest_path, &build_date).unwrap();
|
||||
return PathBuf::from(out_dir);
|
||||
}
|
||||
|
||||
if env::var_os("CARGO_CFG_WINDOWS").is_some() {
|
||||
// Add a version resource to the executable
|
||||
let mut res = WindowsResource::new();
|
||||
res.set_icon("assets/Bootstrapper.ico");
|
||||
res.set_language(0x0409); // US English
|
||||
res.set("FileVersion", env!("CARGO_PKG_VERSION"));
|
||||
res.set("FileDescription", "SYNTAX Windows Bootstrapper");
|
||||
res.set("ProductName", "SYNTAX Bootstrapper");
|
||||
res.set("ProductVersion", env!("CARGO_PKG_VERSION"));
|
||||
res.set("InternalName", "SYNTAX Bootstrapper");
|
||||
res.set("OriginalFilename", "SyntaxPlayerLauncher.exe");
|
||||
res.set("CompanyName", "SYNTAX Corporation");
|
||||
res.set("LegalCopyright", "Copyright (c) 2023");
|
||||
res.compile().unwrap();
|
||||
/* Builds ascii that is displayed at startup */
|
||||
fn build_large_ascii(config: &BuildConfig) {
|
||||
println!("cargo:rerun-if-changed={}", config.ascii.location);
|
||||
|
||||
let build_date = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string();
|
||||
let ascii_b = fs::read(&config.ascii.location).unwrap();
|
||||
let padding = get_padding(config.ascii.padding);
|
||||
let mut ascii = String::from_utf8(ascii_b).unwrap();
|
||||
|
||||
ascii += "\n";
|
||||
ascii += &format!(
|
||||
"{} | Build Date: {} | Version: {}",
|
||||
config.runtime.base_url,
|
||||
build_date,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
|
||||
let mut new_asci = String::new();
|
||||
for line in ascii.lines() {
|
||||
new_asci += &format!("{}{}\n", padding.clone(), line);
|
||||
}
|
||||
fs::write(out_dir().join("./ascii.txt"), new_asci).unwrap();
|
||||
}
|
||||
|
||||
fn build_small_ascii(config: &BuildConfig) {
|
||||
let build_date = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string();
|
||||
fs::write(
|
||||
out_dir().join("./ascii_small.txt"),
|
||||
format!(
|
||||
"{} | {} | Build Date: {} | Version: {}",
|
||||
config.ascii.fallback_text,
|
||||
config.runtime.base_url,
|
||||
build_date,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
)
|
||||
).unwrap()
|
||||
}
|
||||
|
||||
fn build_ascii(config: &BuildConfig) {
|
||||
build_large_ascii(config);
|
||||
build_small_ascii(config);
|
||||
}
|
||||
|
||||
fn build_windows(cfg: &WindowsConfig) {
|
||||
println!("cargo:rerun-if-changed={}", cfg.icon);
|
||||
|
||||
let mut res = WindowsResource::new();
|
||||
res.set_language(ENGLISH_LANGUAGE); // US English
|
||||
res.set_icon(&cfg.icon);
|
||||
|
||||
for (key, value) in &cfg.resources {
|
||||
if value.starts_with("env:") {
|
||||
let (_, env) = value.split_at(4);
|
||||
let value = env::var(env).unwrap();
|
||||
res.set(key, &value);
|
||||
println!("cargo:rerun-if-env-changed={}", env);
|
||||
} else {
|
||||
res.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
res.compile().unwrap()
|
||||
}
|
||||
|
||||
fn generate_const<T: AsRef<str>>(name: &str, c_type: &str, value: T) -> String {
|
||||
let value = match c_type {
|
||||
"&str" => format!(r#""{}""#, value.as_ref()),
|
||||
_ => value.as_ref().into(),
|
||||
};
|
||||
|
||||
format!("const {name}: {c_type} = {value};\n")
|
||||
}
|
||||
|
||||
/* Passes values */
|
||||
fn build_runtime(config: &RuntimeConfig) {
|
||||
let mut output = String::new();
|
||||
output += &generate_const("SETUP_URL", "&str", &config.setup_url);
|
||||
output += &generate_const("BASE_URL", "&str", &config.base_url);
|
||||
output += &generate_const("THREAD_COUNT", "usize", format!("{}", config.thread_count));
|
||||
|
||||
fs::write(out_dir().join("./codegen.rs"), output).unwrap();
|
||||
}
|
||||
|
||||
fn load_config() -> BuildConfig {
|
||||
println!("cargo:rerun-if-changed=build.yaml");
|
||||
let bytes = fs::read("./build.yaml").unwrap();
|
||||
serde_yaml::from_slice(&bytes).unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = load_config();
|
||||
|
||||
build_ascii(&config);
|
||||
build_runtime(&config.runtime);
|
||||
|
||||
if let Some(_) = env::var_os("CARGO_CFG_WINDOWS") {
|
||||
build_windows(&config.windows)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# Information about the startup ascii
|
||||
Ascii:
|
||||
Location: assets/ascii.txt
|
||||
Padding: 4
|
||||
FallbackText: SYNTAX Bootstrapper
|
||||
|
||||
# Information to be used at runtime
|
||||
Runtime:
|
||||
SetupUrl: setup.syntax.eco
|
||||
BaseUrl: syntax.eco
|
||||
ThreadCount: 2
|
||||
|
||||
# Information about the exe
|
||||
Windows:
|
||||
Icon: assets/Bootstrapper.ico
|
||||
Resources:
|
||||
FileVersion: env:CARGO_PKG_VERSION
|
||||
FileDescription: SYNTAX Windows Bootstrapper
|
||||
ProductName: SYNTAX Bootstrapper
|
||||
ProductVersion: env:CARGO_PKG_VERSION
|
||||
InternalName: SYNTAX Bootstrapper
|
||||
OriginalFilename: SyntaxPlayerLauncher.exe
|
||||
CompanyName: SYNTAX Corporation
|
||||
LegalCopyright: Copyright (c) 2024
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
use std::{ result, error::Error };
|
||||
|
||||
use colored::*;
|
||||
|
||||
type Result<T> = result::Result<T, Box<dyn Error>>;
|
||||
|
||||
pub fn get_time() -> String {
|
||||
chrono::Local::now().format("%H:%M:%S").to_string()
|
||||
}
|
||||
|
||||
fn get_progress_style<T: AsRef<str>>(target: T) -> Result<ProgressStyle> {
|
||||
let progress_style = indicatif::ProgressStyle
|
||||
::default_bar()
|
||||
.template(
|
||||
format!(
|
||||
"{}\n{}",
|
||||
format!(
|
||||
"[{}] [{}] {}",
|
||||
get_time().bold().blue(),
|
||||
"INFO".bold().green(),
|
||||
format!("Downloading {}", target.as_ref())
|
||||
),
|
||||
" ".repeat(16) +
|
||||
"{spinner:.green} [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})"
|
||||
).as_str()
|
||||
)?
|
||||
.progress_chars("#>-");
|
||||
|
||||
Ok(progress_style)
|
||||
}
|
||||
|
||||
pub fn create_progress() {}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
use ::colored::*;
|
||||
use crate::log::get_time;
|
||||
println!( "[{}] [{}] {}",get_time().bold().blue(),"INFO".bold().green(),format!($($t)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
use ::colored::*;
|
||||
use crate::log::get_time;
|
||||
println!( "[{}] [{}] {}",get_time().bold().blue(),"ERROR".bold().red(),format!($($t)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
use ::colored::*;
|
||||
use crate::log::get_time;
|
||||
println!( "[{}] [{}] {}",get_time().bold().blue(),"DEBUG".bold().yellow(),format!($($t)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! fatal {
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
use ::colored::*;
|
||||
use crate::log::get_time;
|
||||
panic!( "[{}] [{}] {}",get_time().bold().blue(),"FATAL".bold().red().underline(),format!($($t)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
use indicatif::ProgressStyle;
|
||||
pub(crate) use info;
|
||||
pub(crate) use error;
|
||||
pub(crate) use debug;
|
||||
pub(crate) use fatal;
|
||||
494
src/main.rs
494
src/main.rs
|
|
@ -1,5 +1,6 @@
|
|||
use chrono::format;
|
||||
use colored::*;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use reqwest::Client;
|
||||
use dirs::data_local_dir;
|
||||
|
|
@ -18,96 +19,66 @@ use std::io::prelude::*;
|
|||
#[cfg(not(target_os = "windows"))]
|
||||
use std::os::unix::fs::FileExt;
|
||||
|
||||
fn info( message : &str ) {
|
||||
let time = chrono::Local::now().format("%H:%M:%S").to_string();
|
||||
println!("[{}] [{}] {}", time.bold().blue(), "INFO".bold().green(), message);
|
||||
}
|
||||
pub mod log;
|
||||
|
||||
fn error( message : &str ) {
|
||||
let time = chrono::Local::now().format("%H:%M:%S").to_string();
|
||||
println!("[{}] [{}] {}", time.bold().blue(), "ERROR".bold().red(), message);
|
||||
}
|
||||
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
fn debug( message : &str ) {
|
||||
let time = chrono::Local::now().format("%H:%M:%S").to_string();
|
||||
println!("[{}] [{}] {}", time.bold().blue(), "DEBUG".bold().yellow(), message);
|
||||
}
|
||||
const ASCII_ART: &str = include_str!(concat!(env!("OUT_DIR"), "./ascii.txt"));
|
||||
const SMALL_ACII: &str = include_str!(concat!(env!("OUT_DIR"), "./ascii_small.txt"));
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn debug( message : &str ) {}
|
||||
|
||||
pub async fn http_get( client: &Client ,url: &str ) -> Result<String, reqwest::Error> {
|
||||
debug(&format!("{} {}", "GET".green(), url.bright_blue()));
|
||||
pub async fn http_get(client: &Client, url: &str) -> Result<String, reqwest::Error> {
|
||||
debug!("{} {}", "GET".green(), url.bright_blue());
|
||||
let response = client.get(url).send().await;
|
||||
if (response.is_err()) {
|
||||
debug(&format!("Failed to fetch {}", url.bright_blue()));
|
||||
if response.is_err() {
|
||||
debug!("Failed to fetch {}", url.bright_blue());
|
||||
return Err(response.err().unwrap());
|
||||
}
|
||||
let response_body = response.unwrap().text().await.unwrap();
|
||||
Ok(response_body)
|
||||
}
|
||||
|
||||
pub async fn download_file( client: &Client, url: &str, path: &PathBuf ) {
|
||||
debug(&format!("{} {}", "GET".green(), url.bright_blue()));
|
||||
pub async fn download_file(client: &Client, url: &str, path: &PathBuf) {
|
||||
debug!("{} {}", "GET".green(), url.bright_blue());
|
||||
let response = client.get(url).send().await.unwrap();
|
||||
let content_length = response.content_length().unwrap();
|
||||
debug(&format!("Content Length: {}", content_length));
|
||||
debug!("Content Length: {}", content_length);
|
||||
|
||||
let time = chrono::Local::now().format("%H:%M:%S").to_string();
|
||||
let pg_bar_str = " {spinner:.green} [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})";
|
||||
let pg_bar_str = " ";
|
||||
let progress_bar = indicatif::ProgressBar::new(content_length);
|
||||
let progress_style = indicatif::ProgressStyle::default_bar()
|
||||
.template(
|
||||
format!("{}\n{}",
|
||||
format!(
|
||||
"[{}] [{}] {}",
|
||||
time.bold().blue(),
|
||||
"INFO".bold().green(),
|
||||
&format!("Downloading {}", &url.bright_blue())
|
||||
),
|
||||
pg_bar_str).as_str()
|
||||
)
|
||||
.unwrap().progress_chars("#>-");
|
||||
progress_bar.set_style(progress_style);
|
||||
|
||||
// progress_bar.set_style(progress_style);
|
||||
progress_bar.set_message("Downloading File");
|
||||
|
||||
let file = std::fs::File::create(path).unwrap();
|
||||
let mut file = std::fs::File::create(path).unwrap();
|
||||
let mut downloaded: u64 = 0;
|
||||
let mut stream = response.bytes_stream();
|
||||
|
||||
while let Some(item) = stream.next().await {
|
||||
let chunk = item.or(Err(format!("Error while downloading file"))).unwrap();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
file.seek_write(chunk.as_ref(), downloaded).unwrap();
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
file.write_at(chunk.as_ref(), downloaded).unwrap();
|
||||
}
|
||||
file.write_all(&chunk);
|
||||
let new = std::cmp::min(downloaded + (chunk.len() as u64), content_length);
|
||||
downloaded = new;
|
||||
progress_bar.set_position(new);
|
||||
}
|
||||
progress_bar.finish();
|
||||
info(format!("Finished downloading {}", url.green()).as_str());
|
||||
info!("Finished downloading {}", url.green());
|
||||
}
|
||||
|
||||
pub async fn download_file_prefix( client: &Client, url: &str, path_prefix : &PathBuf ) -> PathBuf {
|
||||
pub async fn download_file_prefix(client: &Client, url: &str, path_prefix: &PathBuf) -> PathBuf {
|
||||
let path = path_prefix.join(generate_md5(url).await);
|
||||
download_file(client, url, &path).await;
|
||||
return path;
|
||||
}
|
||||
|
||||
pub async fn generate_md5( input : &str ) -> String {
|
||||
pub async fn generate_md5(input: &str) -> String {
|
||||
let hashed_input = md5::compute(input.as_bytes());
|
||||
return format!("{:x}", hashed_input);
|
||||
}
|
||||
|
||||
pub async fn create_folder_if_not_exists( path: &PathBuf ) {
|
||||
pub async fn create_folder_if_not_exists(path: &PathBuf) {
|
||||
if !path.exists() {
|
||||
info(&format!("Creating folder {}", path.to_str().unwrap().bright_blue()));
|
||||
info!("Creating folder {}", path.to_str().unwrap().bright_blue());
|
||||
std::fs::create_dir_all(path).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
@ -116,403 +87,46 @@ fn get_installation_directory() -> PathBuf {
|
|||
return PathBuf::from(data_local_dir().unwrap().to_str().unwrap()).join("Syntax");
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
fn format_info_line<T: AsRef<str>>(data: T) -> ColoredString {
|
||||
let data = data.as_ref();
|
||||
|
||||
// Clear the terminal before printing the startup text
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
std::process::Command::new("cmd")
|
||||
.args(&["/c", "cls"])
|
||||
.spawn()
|
||||
.expect("cls command failed to start")
|
||||
.wait()
|
||||
.expect("failed to wait");
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
std::process::Command::new("clear").spawn().unwrap();
|
||||
}
|
||||
data.magenta().cyan().italic().on_black()
|
||||
}
|
||||
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let base_url : &str = "www.syntax.eco";
|
||||
let mut setup_url : &str = "setup.syntax.eco";
|
||||
let fallback_setup_url : &str = "d2f3pa9j0u8v6f.cloudfront.net";
|
||||
let mut bootstrapper_filename :&str = "SyntaxPlayerLauncher.exe";
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
bootstrapper_filename = "SyntaxPlayerLinuxLauncher";
|
||||
}
|
||||
let build_date = include_str!(concat!(env!("OUT_DIR"), "/build_date.txt"));
|
||||
let startup_text = format!("
|
||||
.d8888b. Y88b d88P 888b 888 88888888888 d8888 Y88b d88P
|
||||
d88P Y88b Y88b d88P 8888b 888 888 d88888 Y88b d88P
|
||||
Y88b. Y88o88P 88888b 888 888 d88P888 Y88o88P
|
||||
\"Y888b. Y888P 888Y88b 888 888 d88P 888 Y888P
|
||||
\"Y88b. 888 888 Y88b888 888 d88P 888 d888b
|
||||
\"888 888 888 Y88888 888 d88P 888 d88888b
|
||||
Y88b d88P 888 888 Y8888 888 d8888888888 d88P Y88b
|
||||
\"Y8888P\" 888 888 Y888 888 d88P 888 d88P Y88b
|
||||
|
||||
{} | Build Date: {} | Version: {}", base_url ,build_date, env!("CARGO_PKG_VERSION"));
|
||||
|
||||
// Format the startup text to be centered
|
||||
let mut terminal_width = 80;
|
||||
if let Some((w, _h)) = term_size::dimensions() {
|
||||
terminal_width = w;
|
||||
}
|
||||
if terminal_width < 80 {
|
||||
print!("{}\n", format!("SYNTAX Bootstrapper | {} | Build Date: {} | Version: {}", base_url, build_date, env!("CARGO_PKG_VERSION")).to_string().magenta().cyan().italic().on_black()); // Fallback message
|
||||
fn is_large() -> bool {
|
||||
if let Some((terminal_width, _)) = term_size::dimensions() {
|
||||
return terminal_width > 80;
|
||||
} else {
|
||||
let startup_text_lines = startup_text.lines().collect::<Vec<&str>>();
|
||||
//println!("{}", startup_text.bold().blue().on_black());
|
||||
|
||||
// print all lines except the last one
|
||||
for line in &startup_text_lines[0..startup_text_lines.len() - 1] {
|
||||
let spaces = (terminal_width - line.len()) / 2;
|
||||
let formatted_line = format!("{}{}", " ".repeat(spaces), line);
|
||||
println!("{}", formatted_line.bright_magenta().italic().on_black());
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
// print last line as a different color
|
||||
let last_line = startup_text_lines[startup_text_lines.len() - 1];
|
||||
let spaces = (terminal_width - last_line.len()) / 2;
|
||||
let last_line = format!("{}{}", " ".repeat(spaces), last_line);
|
||||
println!("{}\n", last_line.magenta().cyan().italic().on_black());
|
||||
fn startup_info() {
|
||||
/* Clear screen */
|
||||
print!("\x1b[2J\x1b[H");
|
||||
|
||||
if !is_large() {
|
||||
return println!("{}", format_info_line(SMALL_ACII));
|
||||
}
|
||||
|
||||
let http_client: Client = reqwest::Client::builder()
|
||||
.no_gzip()
|
||||
.build()
|
||||
.unwrap();
|
||||
debug(format!("Setup Server: {} | Base Server: {}", setup_url.bright_blue(), base_url.bright_blue()).as_str());
|
||||
debug("Fetching latest client version from setup server");
|
||||
|
||||
let latest_client_version : String;
|
||||
let latest_client_version_response = http_get(&http_client ,&format!("https://{}/version", setup_url)).await;
|
||||
match latest_client_version_response {
|
||||
Ok(latest_client_version_result) => {
|
||||
debug(&format!("Latest Client Version: {}", latest_client_version_result.bright_blue()));
|
||||
latest_client_version = latest_client_version_result;
|
||||
},
|
||||
Err(e) => {
|
||||
error(&format!("Failed to fetch latest client version from setup server: [{}], attempting to fallback to {}", e.to_string().bright_red(), fallback_setup_url.bright_blue()));
|
||||
let fallback_client_version_response = http_get(&http_client ,&format!("https://{}/version", fallback_setup_url)).await;
|
||||
match fallback_client_version_response {
|
||||
Ok(fallback_client_version_result) => {
|
||||
info(&format!("Successfully fetched latest client version from fallback setup server: {}", fallback_setup_url.bright_blue()));
|
||||
debug(&format!("Latest Client Version: {}", fallback_client_version_result.bright_blue()));
|
||||
latest_client_version = fallback_client_version_result;
|
||||
setup_url = fallback_setup_url;
|
||||
},
|
||||
Err(e) => {
|
||||
error(&format!("Failed to fetch latest client version from fallback setup server: {}, are you connected to the internet?", e));
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut lines: Vec<&str> = ASCII_ART.lines().collect();
|
||||
let last = lines.pop();
|
||||
|
||||
for value in lines {
|
||||
println!("{}", value.bright_magenta().italic().on_black());
|
||||
}
|
||||
|
||||
// Wait for the latest client version to be fetched
|
||||
info(&format!("Latest Client Version: {}", latest_client_version.cyan().underline()));
|
||||
debug(&format!("Setup Server: {}", setup_url.cyan().underline()));
|
||||
|
||||
let installation_directory = get_installation_directory();
|
||||
debug(&format!("Installation Directory: {}", installation_directory.to_str().unwrap().bright_blue()));
|
||||
create_folder_if_not_exists(&installation_directory).await;
|
||||
|
||||
let versions_directory = installation_directory.join("Versions");
|
||||
debug(&format!("Versions Directory: {}", versions_directory.to_str().unwrap().bright_blue()));
|
||||
create_folder_if_not_exists(&versions_directory).await;
|
||||
|
||||
let temp_downloads_directory = installation_directory.join("Downloads");
|
||||
debug(&format!("Temp Downloads Directory: {}", temp_downloads_directory.to_str().unwrap().bright_blue()));
|
||||
create_folder_if_not_exists(&temp_downloads_directory).await;
|
||||
|
||||
let current_version_directory = versions_directory.join(format!("{}", latest_client_version));
|
||||
debug(&format!("Current Version Directory: {}", current_version_directory.to_str().unwrap().bright_blue()));
|
||||
create_folder_if_not_exists(¤t_version_directory).await;
|
||||
|
||||
let latest_bootstrapper_path = current_version_directory.join(bootstrapper_filename);
|
||||
// Is the program currently running from the latest version directory?
|
||||
let current_exe_path = std::env::current_exe().unwrap();
|
||||
// If the current exe path is not in the current version directory, then we need to run the latest bootstrapper ( download if needed )
|
||||
if !current_exe_path.starts_with(¤t_version_directory) {
|
||||
// Check if the latest bootstrapper is downloaded
|
||||
if !latest_bootstrapper_path.exists() {
|
||||
info("Downloading the latest bootstrapper and restarting");
|
||||
// Download the latest bootstrapper
|
||||
download_file(&http_client, &format!("https://{}/{}-{}", setup_url, latest_client_version, bootstrapper_filename), &latest_bootstrapper_path).await;
|
||||
}
|
||||
// Run the latest bootstrapper ( with the same arguments passed to us ) and exit
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let mut command = std::process::Command::new(latest_bootstrapper_path.clone());
|
||||
command.args(&args[1..]);
|
||||
match command.spawn() {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
debug(&format!("Bootstrapper errored with error {}", e));
|
||||
info("Found bootstrapper was corrupted! Downloading...");
|
||||
std::fs::remove_file(latest_bootstrapper_path.clone()).unwrap();
|
||||
download_file(&http_client, &format!("https://{}/{}-{}", setup_url, latest_client_version, bootstrapper_filename), &latest_bootstrapper_path).await;
|
||||
command.spawn().expect("Bootstrapper is still corrupted.");
|
||||
std::thread::sleep(std::time::Duration::from_secs(20));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
// Make sure the latest bootstrapper is executable
|
||||
std::process::Command::new("chmod").arg("+x").arg(latest_bootstrapper_path.to_str().unwrap()).spawn().unwrap();
|
||||
|
||||
info("We need permission to run the latest bootstrapper");
|
||||
let mut command = std::process::Command::new(latest_bootstrapper_path);
|
||||
command.args(&args[1..]);
|
||||
command.spawn().unwrap();
|
||||
}
|
||||
std::process::exit(0);
|
||||
if let Some(last_val) = last {
|
||||
println!("{}", format_info_line(last_val));
|
||||
}
|
||||
}
|
||||
|
||||
// Looks like we are running from the latest version directory, so we can continue with the update process
|
||||
// Check for "AppSettings.xml" in the current version directory
|
||||
// If it doesent exist, then we got either a fresh directory or a corrupted installation
|
||||
// So delete the every file in the current version directory except for the Bootstrapper itself
|
||||
let app_settings_path = current_version_directory.join("AppSettings.xml");
|
||||
let client_executable_path = current_version_directory.join("SyntaxPlayerBeta.exe");
|
||||
if !app_settings_path.exists() { //|| !client_executable_path.exists() {
|
||||
info("Downloading the latest client files, this may take a while.");
|
||||
for entry in std::fs::read_dir(¤t_version_directory).unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
if path.is_file() {
|
||||
if path != current_exe_path {
|
||||
std::fs::remove_file(path).unwrap();
|
||||
}
|
||||
} else {
|
||||
std::fs::remove_dir_all(path).unwrap();
|
||||
}
|
||||
}
|
||||
fn main() {
|
||||
/* Ansi character to clear line */
|
||||
|
||||
let VersionURLPrefix = format!("https://{}/{}-", setup_url, latest_client_version);
|
||||
startup_info();
|
||||
|
||||
let Client2018Zip : PathBuf = download_file_prefix(&http_client, format!("{}2018client.zip", VersionURLPrefix).as_str(), &temp_downloads_directory).await;
|
||||
let Client2020Zip : PathBuf = download_file_prefix(&http_client, format!("{}2020client.zip", VersionURLPrefix).as_str(), &temp_downloads_directory).await;
|
||||
let Client2014Zip : PathBuf = download_file_prefix(&http_client, format!("{}2014client.zip", VersionURLPrefix).as_str(), &temp_downloads_directory).await;
|
||||
let Client2016Zip : PathBuf = download_file_prefix(&http_client, format!("{}2016client.zip", VersionURLPrefix).as_str(), &temp_downloads_directory).await;
|
||||
info("Download finished, extracting files.");
|
||||
|
||||
fn extract_to_dir( zip_file : &PathBuf, target_dir : &PathBuf ) {
|
||||
info(format!("Extracting {} to {}", zip_file.to_str().unwrap().bright_blue(), target_dir.to_str().unwrap().bright_blue()).as_str());
|
||||
let zip_file_cursor = std::fs::File::open(zip_file).unwrap();
|
||||
zip_extract::extract(zip_file_cursor, target_dir, false).unwrap();
|
||||
}
|
||||
|
||||
let client_2018_directory = current_version_directory.join("Client2018");
|
||||
create_folder_if_not_exists(&client_2018_directory).await;
|
||||
extract_to_dir(&Client2018Zip, &client_2018_directory);
|
||||
|
||||
let client_2020_directory = current_version_directory.join("Client2020");
|
||||
create_folder_if_not_exists(&client_2020_directory).await;
|
||||
extract_to_dir(&Client2020Zip, &client_2020_directory);
|
||||
|
||||
let client_2014_directory = current_version_directory.join("Client2014");
|
||||
create_folder_if_not_exists(&client_2014_directory).await;
|
||||
extract_to_dir(&Client2014Zip, &client_2014_directory);
|
||||
|
||||
let client_2016_directory = current_version_directory.join("Client2016");
|
||||
create_folder_if_not_exists(&client_2016_directory).await;
|
||||
extract_to_dir(&Client2016Zip, &client_2016_directory);
|
||||
|
||||
info("Finished extracting files, cleaning up.");
|
||||
std::fs::remove_dir_all(&temp_downloads_directory).unwrap();
|
||||
|
||||
// Install the syntax-player scheme in the registry
|
||||
info("Installing syntax-player scheme");
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let hkey_current_user = RegKey::predef(HKEY_CURRENT_USER);
|
||||
let hkey_classes_root : RegKey = hkey_current_user.open_subkey("Software\\Classes").unwrap();
|
||||
let hkey_syntax_player = hkey_classes_root.create_subkey("syntax-player").unwrap().0;
|
||||
let hkey_syntax_player_shell = hkey_syntax_player.create_subkey("shell").unwrap().0;
|
||||
let hkey_syntax_player_shell_open = hkey_syntax_player_shell.create_subkey("open").unwrap().0;
|
||||
let hkey_syntax_player_shell_open_command = hkey_syntax_player_shell_open.create_subkey("command").unwrap().0;
|
||||
let defaulticon = hkey_syntax_player.create_subkey("DefaultIcon").unwrap().0;
|
||||
hkey_syntax_player_shell_open_command.set_value("", &format!("\"{}\" \"%1\"", current_exe_path.to_str().unwrap())).unwrap();
|
||||
defaulticon.set_value("", &format!("\"{}\",0", current_exe_path.to_str().unwrap())).unwrap();
|
||||
hkey_syntax_player.set_value("", &format!("URL: Syntax Protocol")).unwrap();
|
||||
hkey_syntax_player.set_value("URL Protocol", &"").unwrap();
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
// Linux support
|
||||
// We have to write a .desktop file to ~/.local/share/applications
|
||||
let desktop_file_path = dirs::data_local_dir().unwrap().join("applications").join("syntax-player.desktop");
|
||||
let desktop_file = format!(
|
||||
"[Desktop Entry]
|
||||
Name=Syntax Launcher
|
||||
Exec={} %u
|
||||
Terminal=true
|
||||
Type=Application
|
||||
MimeType=x-scheme-handler/syntax-player;
|
||||
Icon={}
|
||||
StartupWMClass=SyntaxLauncher
|
||||
Categories=Game;
|
||||
Comment=Syntax Launcher
|
||||
", current_exe_path.to_str().unwrap(), current_exe_path.to_str().unwrap());
|
||||
std::fs::write(desktop_file_path, desktop_file).unwrap();
|
||||
// We also have to write a mimeapps.list file to ~/.config
|
||||
let mimeapps_list_path = dirs::config_dir().unwrap().join("mimeapps.list");
|
||||
let mimeapps_list = format!(
|
||||
"[Default Applications]
|
||||
x-scheme-handler/syntax-player=syntax-player.desktop
|
||||
");
|
||||
std::fs::write(mimeapps_list_path, mimeapps_list).unwrap();
|
||||
// We also have to write a mimeapps.list file to ~/.local/share
|
||||
let mimeapps_list_path = dirs::data_local_dir().unwrap().join("mimeapps.list");
|
||||
let mimeapps_list = format!(
|
||||
"[Default Applications]
|
||||
x-scheme-handler/syntax-player=syntax-player.desktop
|
||||
");
|
||||
std::fs::write(mimeapps_list_path, mimeapps_list).unwrap();
|
||||
}
|
||||
|
||||
// Write the AppSettings.xml file
|
||||
let app_settings_xml = format!(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<Settings>
|
||||
<ContentFolder>content</ContentFolder>
|
||||
<BaseUrl>http://{}</BaseUrl>
|
||||
</Settings>", base_url
|
||||
);
|
||||
std::fs::write(app_settings_path, app_settings_xml).unwrap();
|
||||
|
||||
// Check for any other version directories and deletes them
|
||||
for entry in std::fs::read_dir(&versions_directory).unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
if path != current_version_directory {
|
||||
std::fs::remove_dir_all(path).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the arguments passed to the bootstrapper
|
||||
// Looks something like "syntax-player://1+launchmode:play+gameinfo:TICKET+placelauncherurl:https://www.syntax.eco/Game/placelauncher.ashx?placeId=660&t=TICKET+k:l"
|
||||
debug(&format!("Arguments Passed: {}", args.join(" ").bright_blue()));
|
||||
if args.len() == 1 {
|
||||
// Just open the website
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
std::process::Command::new("cmd").arg("/c").arg("start").arg("https://www.syntax.eco/games").spawn().unwrap();
|
||||
std::process::exit(0);
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
std::process::Command::new("xdg-open").arg("https://www.syntax.eco/games").spawn().unwrap();
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
let main_args = &args[1];
|
||||
let main_args = main_args.replace("syntax-player://", "");
|
||||
let main_args = main_args.split("+").collect::<Vec<&str>>();
|
||||
|
||||
let mut launch_mode = String::new();
|
||||
let mut authentication_ticket = String::new();
|
||||
let mut join_script = String::new();
|
||||
let mut client_year = String::new();
|
||||
|
||||
for arg in main_args {
|
||||
let mut arg_split = arg.split(":");
|
||||
let key = arg_split.next().unwrap();
|
||||
let value =
|
||||
if arg_split.clone().count() > 0 {
|
||||
arg_split.collect::<Vec<&str>>().join(":")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
debug(&format!("{}: {}", key.bright_blue(), value.bright_blue()));
|
||||
match key {
|
||||
"launchmode" => {
|
||||
launch_mode = value.to_string();
|
||||
},
|
||||
"gameinfo" => {
|
||||
authentication_ticket = value.to_string();
|
||||
},
|
||||
"placelauncherurl" => {
|
||||
join_script = value.to_string();
|
||||
},
|
||||
"clientyear" => {
|
||||
client_year = value.to_string();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let custom_wine = "wine";
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
// We allow user to specify the wine binary path in installation_directory/winepath.txt
|
||||
let wine_path_file = installation_directory.join("winepath.txt");
|
||||
if wine_path_file.exists() {
|
||||
let custom_wine = std::fs::read_to_string(wine_path_file).unwrap();
|
||||
info(&format!("Using custom wine binary: {}", custom_wine.bright_blue()));
|
||||
} else {
|
||||
info("No custom wine binary specified, using default wine command");
|
||||
info(format!("If you want to use a custom wine binary, please create a file at {} with the path to the wine binary", wine_path_file.to_str().unwrap()).as_str());
|
||||
}
|
||||
}
|
||||
let client_executable_path : PathBuf;
|
||||
debug(&client_year.to_string());
|
||||
if client_year == "2018" {
|
||||
client_executable_path = current_version_directory.join("Client2018").join("SyntaxPlayerBeta.exe");
|
||||
} else if client_year == "2020" {
|
||||
client_executable_path = current_version_directory.join("Client2020").join("SyntaxPlayerBeta.exe");
|
||||
} else if client_year == "2014" {
|
||||
client_executable_path = current_version_directory.join("Client2014").join("SyntaxPlayerBeta.exe");
|
||||
} else {
|
||||
client_executable_path = current_version_directory.join("Client2016").join("SyntaxPlayerBeta.exe");
|
||||
}
|
||||
if !client_executable_path.exists() {
|
||||
// Delete AppSettings.xml so the bootstrapper will download the client again
|
||||
let app_settings_path = current_version_directory.join("AppSettings.xml");
|
||||
std::fs::remove_file(app_settings_path).unwrap();
|
||||
|
||||
error("Failed to run SyntaxPlayerBeta.exe, is your antivirus removing it? The bootstrapper will attempt to redownload the client on next launch.");
|
||||
std::thread::sleep(std::time::Duration::from_secs(20));
|
||||
std::process::exit(0);
|
||||
}
|
||||
match launch_mode.as_str() {
|
||||
"play" => {
|
||||
info("Launching SYNTAX");
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let mut command = std::process::Command::new(client_executable_path);
|
||||
command.args(&["--play","--authenticationUrl", format!("https://{}/Login/Negotiate.ashx", base_url).as_str(), "--authenticationTicket", authentication_ticket.as_str(), "--joinScriptUrl", format!("{}",join_script.as_str()).as_str()]);
|
||||
command.spawn().unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
std::process::exit(0);
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
// We have to launch the game through wine
|
||||
let mut command = std::process::Command::new(custom_wine);
|
||||
command.args(&[client_executable_path.to_str().unwrap(), "--play","--authenticationUrl", format!("https://{}/Login/Negotiate.ashx", base_url).as_str(), "--authenticationTicket", authentication_ticket.as_str(), "--joinScriptUrl", format!("{}",join_script.as_str()).as_str()]);
|
||||
// We must wait for the game to exit before exiting the bootstrapper
|
||||
let mut child = command.spawn().unwrap();
|
||||
child.wait().unwrap();
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
std::process::exit(0);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
error("Unknown launch mode, exiting.");
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
log::info!("{}", SETUP_URL);
|
||||
log::debug!("Hello {}", "World");
|
||||
log::error!("Oh no there was an issue");
|
||||
log::fatal!("Oh shit")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue