Compare commits
5 Commits
Release-1-
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
2e2bc87682 | |
|
|
2c895eb5f5 | |
|
|
f606023568 | |
|
|
2397108f63 | |
|
|
541e99b1b2 |
|
|
@ -0,0 +1,52 @@
|
||||||
|
name: Build Release Executables
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-release-windows:
|
||||||
|
name: Build on Windows ${{ github.event.release.tag_name }}
|
||||||
|
runs-on: windows-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --release
|
||||||
|
- name: Rename executable
|
||||||
|
run: mv target/release/syntax_bootstrapper.exe target/release/SyntaxPlayerLauncher.exe
|
||||||
|
- name: Upload Release Asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ github.event.release.upload_url }}
|
||||||
|
asset_path: target/release/SyntaxPlayerLauncher.exe
|
||||||
|
asset_name: SyntaxPlayerLauncher.exe
|
||||||
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
|
build-release-linux:
|
||||||
|
name: Build on Linux ${{ github.event.release.tag_name }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --release
|
||||||
|
- name: Rename executable
|
||||||
|
run: mv target/release/syntax_bootstrapper target/release/SyntaxPlayerLinuxLauncher
|
||||||
|
- name: Upload Release Asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ github.event.release.upload_url }}
|
||||||
|
asset_path: target/release/SyntaxPlayerLinuxLauncher
|
||||||
|
asset_name: SyntaxPlayerLinuxLauncher
|
||||||
|
asset_content_type: application/octet-stream
|
||||||
|
|
@ -1178,9 +1178,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.5"
|
version = "0.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
|
|
@ -1261,7 +1261,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syntax_bootstrapper"
|
name = "syntax_bootstrapper"
|
||||||
version = "1.3.2"
|
version = "1.3.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"colored",
|
"colored",
|
||||||
|
|
@ -1271,6 +1271,7 @@ dependencies = [
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"md5",
|
"md5",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"sha1",
|
||||||
"term_size",
|
"term_size",
|
||||||
"tokio",
|
"tokio",
|
||||||
"winreg 0.51.0",
|
"winreg 0.51.0",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "syntax_bootstrapper"
|
name = "syntax_bootstrapper"
|
||||||
version = "1.3.2"
|
version = "1.3.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# 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
|
||||||
|
|
@ -17,6 +17,7 @@ tokio = { version = "1.32.0", features=["full"]}
|
||||||
futures-util = "0.3.28"
|
futures-util = "0.3.28"
|
||||||
md5 = "0.7.0"
|
md5 = "0.7.0"
|
||||||
zip-extract = "0.1.2"
|
zip-extract = "0.1.2"
|
||||||
|
sha1 = "0.10.6"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winreg = "0.51.0"
|
winreg = "0.51.0"
|
||||||
|
|
|
||||||
85
src/main.rs
85
src/main.rs
|
|
@ -6,6 +6,7 @@ use dirs::data_local_dir;
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use md5;
|
use md5;
|
||||||
use zip_extract;
|
use zip_extract;
|
||||||
|
use sha1::{Sha1, Digest};
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use std::os::windows::prelude::FileExt;
|
use std::os::windows::prelude::FileExt;
|
||||||
|
|
@ -112,6 +113,14 @@ pub async fn create_folder_if_not_exists( path: &PathBuf ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_sha1_hash_of_file( path: &PathBuf ) -> String {
|
||||||
|
let mut file = std::fs::File::open(path).unwrap();
|
||||||
|
let mut hasher = Sha1::new();
|
||||||
|
std::io::copy(&mut file, &mut hasher).unwrap();
|
||||||
|
let hash = hasher.finalize();
|
||||||
|
return format!("{:x}", hash);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_installation_directory() -> PathBuf {
|
fn get_installation_directory() -> PathBuf {
|
||||||
return PathBuf::from(data_local_dir().unwrap().to_str().unwrap()).join("Syntax");
|
return PathBuf::from(data_local_dir().unwrap().to_str().unwrap()).join("Syntax");
|
||||||
}
|
}
|
||||||
|
|
@ -241,10 +250,23 @@ async fn main() {
|
||||||
if !current_exe_path.starts_with(¤t_version_directory) {
|
if !current_exe_path.starts_with(¤t_version_directory) {
|
||||||
// Check if the latest bootstrapper is downloaded
|
// Check if the latest bootstrapper is downloaded
|
||||||
if !latest_bootstrapper_path.exists() {
|
if !latest_bootstrapper_path.exists() {
|
||||||
info("Downloading the latest bootstrapper and restarting");
|
info("Downloading the latest bootstrapper");
|
||||||
// Download the latest bootstrapper
|
// Download the latest bootstrapper
|
||||||
download_file(&http_client, &format!("https://{}/{}-{}", setup_url, latest_client_version, bootstrapper_filename), &latest_bootstrapper_path).await;
|
download_file(&http_client, &format!("https://{}/{}-{}", setup_url, latest_client_version, bootstrapper_filename), &latest_bootstrapper_path).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lets compare the SHA1 hash of the latest bootstrapper to the one we are currently running
|
||||||
|
// If they are the same, then we can continue with the update process
|
||||||
|
// We do this because antivirus software does not like this type of behavior
|
||||||
|
|
||||||
|
let latest_bootstrapper_hash = get_sha1_hash_of_file(&latest_bootstrapper_path).await;
|
||||||
|
let current_exe_hash = get_sha1_hash_of_file(¤t_exe_path).await;
|
||||||
|
|
||||||
|
debug(&format!("Latest Bootstrapper Hash: {}", latest_bootstrapper_hash.bright_blue()));
|
||||||
|
debug(&format!("Current Bootstrapper Hash: {}", current_exe_hash.bright_blue()));
|
||||||
|
|
||||||
|
if latest_bootstrapper_hash != current_exe_hash {
|
||||||
|
info("Starting latest bootstrapper");
|
||||||
// Run the latest bootstrapper ( with the same arguments passed to us ) and exit
|
// Run the latest bootstrapper ( with the same arguments passed to us ) and exit
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
|
|
@ -267,12 +289,24 @@ async fn main() {
|
||||||
// Make sure the latest bootstrapper is executable
|
// Make sure the latest bootstrapper is executable
|
||||||
std::process::Command::new("chmod").arg("+x").arg(latest_bootstrapper_path.to_str().unwrap()).spawn().unwrap();
|
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 desktop_file_content = &format!("[Desktop Entry]
|
||||||
let mut command = std::process::Command::new(latest_bootstrapper_path);
|
Name=Syntax Launcher
|
||||||
command.args(&args[1..]);
|
Exec={} %u
|
||||||
command.spawn().unwrap();
|
Icon={}
|
||||||
|
Type=Application
|
||||||
|
Terminal=true
|
||||||
|
Version={}
|
||||||
|
MimeType=x-scheme-handler/syntax-player;", latest_bootstrapper_path.to_str().unwrap(), latest_bootstrapper_path.to_str().unwrap(), env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
|
let desktop_file_path = dirs::data_local_dir().unwrap().join("applications").join("syntax-player.desktop");
|
||||||
|
std::fs::write(desktop_file_path, desktop_file_content).unwrap();
|
||||||
|
|
||||||
|
info("Please launch SYNTAX from the website, to continue with the update process.");
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(20));
|
||||||
}
|
}
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looks like we are running from the latest version directory, so we can continue with the update process
|
// Looks like we are running from the latest version directory, so we can continue with the update process
|
||||||
|
|
@ -280,14 +314,13 @@ async fn main() {
|
||||||
// If it doesent exist, then we got either a fresh directory or a corrupted installation
|
// 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
|
// 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 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() {
|
if !app_settings_path.exists() { //|| !client_executable_path.exists() {
|
||||||
info("Downloading the latest client files, this may take a while.");
|
info("Downloading the latest client files, this may take a while.");
|
||||||
for entry in std::fs::read_dir(¤t_version_directory).unwrap() {
|
for entry in std::fs::read_dir(¤t_version_directory).unwrap() {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
if path != current_exe_path {
|
if path != latest_bootstrapper_path {
|
||||||
std::fs::remove_file(path).unwrap();
|
std::fs::remove_file(path).unwrap();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -339,43 +372,25 @@ async fn main() {
|
||||||
let hkey_syntax_player_shell_open = hkey_syntax_player_shell.create_subkey("open").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 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;
|
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();
|
hkey_syntax_player_shell_open_command.set_value("", &format!("\"{}\" \"%1\"", latest_bootstrapper_path.to_str().unwrap())).unwrap();
|
||||||
defaulticon.set_value("", &format!("\"{}\",0", current_exe_path.to_str().unwrap())).unwrap();
|
defaulticon.set_value("", &format!("\"{}\",0", latest_bootstrapper_path.to_str().unwrap())).unwrap();
|
||||||
hkey_syntax_player.set_value("", &format!("URL: Syntax Protocol")).unwrap();
|
hkey_syntax_player.set_value("", &format!("URL: Syntax Protocol")).unwrap();
|
||||||
hkey_syntax_player.set_value("URL Protocol", &"").unwrap();
|
hkey_syntax_player.set_value("URL Protocol", &"").unwrap();
|
||||||
}
|
}
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
{
|
{
|
||||||
// Linux support
|
// Linux support
|
||||||
// We have to write a .desktop file to ~/.local/share/applications
|
let desktop_file_content = &format!("[Desktop Entry]
|
||||||
let desktop_file_path = dirs::data_local_dir().unwrap().join("applications").join("syntax-player.desktop");
|
|
||||||
let desktop_file = format!(
|
|
||||||
"[Desktop Entry]
|
|
||||||
Name=Syntax Launcher
|
Name=Syntax Launcher
|
||||||
Exec={} %u
|
Exec={} %u
|
||||||
Terminal=true
|
|
||||||
Type=Application
|
|
||||||
MimeType=x-scheme-handler/syntax-player;
|
|
||||||
Icon={}
|
Icon={}
|
||||||
StartupWMClass=SyntaxLauncher
|
Type=Application
|
||||||
Categories=Game;
|
Terminal=true
|
||||||
Comment=Syntax Launcher
|
Version={}
|
||||||
", current_exe_path.to_str().unwrap(), current_exe_path.to_str().unwrap());
|
MimeType=x-scheme-handler/syntax-player;", latest_bootstrapper_path.to_str().unwrap(), latest_bootstrapper_path.to_str().unwrap(), env!("CARGO_PKG_VERSION"));
|
||||||
std::fs::write(desktop_file_path, desktop_file).unwrap();
|
|
||||||
// We also have to write a mimeapps.list file to ~/.config
|
let desktop_file_path = dirs::data_local_dir().unwrap().join("applications").join("syntax-player.desktop");
|
||||||
let mimeapps_list_path = dirs::config_dir().unwrap().join("mimeapps.list");
|
std::fs::write(desktop_file_path, desktop_file_content).unwrap();
|
||||||
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
|
// Write the AppSettings.xml file
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue