diff --git a/belmont/main.gd b/belmont/main.gd index 33e757f..2bf3528 100644 --- a/belmont/main.gd +++ b/belmont/main.gd @@ -18,6 +18,27 @@ signal update_game(game) signal verify_game(game) var oops_s = preload("res://oops.tscn") var panic_s = preload("res://panic.tscn") +enum status_code{ + Ok = 0, + OOTemp = 1, + Already = 2, + NoVer = 3, + ESymlink, + PatchFail, + ExtFail, + DlFail +} + +var code_dict_map = { + status_code.OOTemp : "Out of temporary space! Free up some space on your computer.", + status_code.Already : "You're already on the latest version... this shouldn't happen.", + status_code.NoVer : "The version you're trying to update to doesn't exist in the file.", + status_code.ESymlink : "Error creating symlink. Try installing somewhere else.", + status_code.PatchFail : "Error patching game.", + status_code.ExtFail : "Error extracting game ZIP", + status_code.DlFail : "Error downloading game." +} + func panic(err_string): var z = panic_s.instantiate() @@ -55,11 +76,11 @@ func _on_HomeButton_pressed(): apply_theme("adastral") func _on_game_verified(status,game): - print("[Belmont/GameVerified] %s verified" % [game]) - call_deferred("t_game_verified",game) + call_deferred("t_game_verified",game,status + ) func _on_game_updated(status,game): - call_deferred("t_game_updated",game) + call_deferred("t_game_updated",game,status) func _on_error(error_detail): print(error_detail) @@ -150,27 +171,33 @@ func add_side_icons(): func t_progress_update(game,progress): games[game]["progress"] = progress*100 -func t_game_verified(game): +func t_game_verified(game,status): change_game(game) - games[game]["progress"] = 0 - if current_game == game: - var tween = get_tree().create_tween() - tween.tween_property($ProgressBar,"modulate",Color.TRANSPARENT,0.2) - await get_tree().create_timer(0.2).timeout - $ProgressBar.hide() - set_buttons(current_game) + if status == status_code.Ok: + games[game]["progress"] = 0 + if current_game == game: + var tween = get_tree().create_tween() + tween.tween_property($ProgressBar,"modulate",Color.TRANSPARENT,0.2) + await get_tree().create_timer(0.2).timeout + $ProgressBar.hide() + set_buttons(current_game) + else: + panic(code_dict_map) -func t_game_updated(game): +func t_game_updated(game,status): change_game(game) - $InstalledVersion.text = "[left]Installed Version: [b]%s[/b]" % s.get_installed_version(game) - games[game]["status"] = "" - games[game]["progress"] = 0 - if current_game == game: - var tween = get_tree().create_tween() - tween.tween_property($ProgressBar,"modulate",Color.TRANSPARENT,0.2) - await get_tree().create_timer(0.2).timeout - $ProgressBar.hide() - set_buttons(current_game) + if status == status_code.Ok: + $InstalledVersion.text = "[left]Installed Version: [b]%s[/b]" % s.get_installed_version(game) + games[game]["status"] = "" + games[game]["progress"] = 0 + if current_game == game: + var tween = get_tree().create_tween() + tween.tween_property($ProgressBar,"modulate",Color.TRANSPARENT,0.2) + await get_tree().create_timer(0.2).timeout + $ProgressBar.hide() + set_buttons(current_game) + else: + panic(code_dict_map[status]) func disabled(color): diff --git a/winter/Code/binding/binding.cpp b/winter/Code/binding/binding.cpp index c8b9721..1f6eaa9 100644 --- a/winter/Code/binding/binding.cpp +++ b/winter/Code/binding/binding.cpp @@ -4,8 +4,8 @@ using namespace godot; void binding::_bind_methods() { - ADD_SIGNAL(MethodInfo("game_verified", PropertyInfo(Variant::STRING, "status"), PropertyInfo(Variant::STRING, "game"))); - ADD_SIGNAL(MethodInfo("game_updated", PropertyInfo(Variant::STRING, "status"), PropertyInfo(Variant::STRING, "game"))); + ADD_SIGNAL(MethodInfo("game_verified", PropertyInfo(Variant::INT, "status"), PropertyInfo(Variant::STRING, "game"))); + ADD_SIGNAL(MethodInfo("game_updated", PropertyInfo(Variant::INT, "status"), PropertyInfo(Variant::STRING, "game"))); ADD_SIGNAL(MethodInfo("progress_update", PropertyInfo(Variant::FLOAT, "progress"), PropertyInfo(Variant::STRING, "game"))); ADD_SIGNAL(MethodInfo("palace_started")); ADD_SIGNAL(MethodInfo("error", PropertyInfo(Variant::STRING, "error_details"), PropertyInfo(Variant::INT, "error_level"))); @@ -84,7 +84,6 @@ void binding::init_palace() void binding::_init_palace() { - throw 1; UtilityFunctions::print("[binding] Firing up palace!"); try { @@ -114,7 +113,7 @@ int binding::update_game(godot::String game_name) void binding::_update_game(String game_name) { int z = p->update_game(game_name.utf8().get_data()); - emit_signal("game_updated", String(std::to_string(z).c_str()), game_name); + emit_signal("game_updated", z, game_name); } int binding::verify_game(godot::String game_name) @@ -128,7 +127,7 @@ int binding::verify_game(godot::String game_name) void binding::_verify_game(String game_name) { int z = p->verify_game(game_name.utf8().get_data()); - emit_signal("game_verified", String(std::to_string(z).c_str()), game_name); + emit_signal("game_verified", z, game_name); } bool binding::is_app_installed(String app_id) diff --git a/winter/Code/emley/kachemak/kachemak.cpp b/winter/Code/emley/kachemak/kachemak.cpp index 21a695b..b22f359 100644 --- a/winter/Code/emley/kachemak/kachemak.cpp +++ b/winter/Code/emley/kachemak/kachemak.cpp @@ -35,10 +35,9 @@ std::optional Kachemak::get_km_version(const std::string &versi KachemakVersion ret = { .file_name = jsonVersion["file"].get(), - // .download_url = jsonVersion["url"].get(), - .download_url = jsonVersion["file_p2p"].get(), - // .download_size = jsonVersion["presz"].get(), - // .extract_size = jsonVersion["postsz"].get(), + .download_url_p2p = jsonVersion["file_p2p"].get(), + .download_size = jsonVersion["file_size"].get(), + .extract_size = jsonVersion["ext_size"].get(), .version = version, .signature = jsonVersion["sig"].get(), }; @@ -83,15 +82,15 @@ int Kachemak::free_space_check(const uintmax_t size, const FreeSpaceCheckCategor switch (category) { case FreeSpaceCheckCategory::Temporary: - if (std::filesystem::space(temp_path).free < size) + if (std::filesystem::space(temp_path).free < size*1000) { - return 1; + return (int)StatusCode::OOTemp; } break; case FreeSpaceCheckCategory::Permanent: - if (std::filesystem::space(sourcemod_path).free < size) + if (std::filesystem::space(sourcemod_path).free < size*1000) { - return 2; + return (int)StatusCode::OOPerm; } break; } @@ -100,19 +99,20 @@ int Kachemak::free_space_check(const uintmax_t size, const FreeSpaceCheckCategor int Kachemak::free_space_check_path(const uintmax_t size, const std::filesystem::path custom_path) { - if (std::filesystem::space(custom_path).free < size) + if (std::filesystem::space(custom_path).free < size*1000) { - return 1; + return (int)StatusCode::OOPerm; } return 0; } + int Kachemak::verify() { std::optional installed_km_version = get_km_version(installed_version_code); if (!installed_km_version) { - return 4; + return (int)StatusCode::NoVer; } // full signature url std::stringstream sig_url_full; @@ -124,7 +124,7 @@ int Kachemak::verify() butler_verify(sig_url_full.str(), dataDir_path.string(), heal_url.str()); force_verify = false; write_version(); - return 0; + return (int)StatusCode::Ok; } /** @@ -135,6 +135,7 @@ int Kachemak::verify() 1: symlink fail 2: space check fail 3: already on latest / verification needed first + 4: installed versiobn doesn't exist in version file */ int Kachemak::update() @@ -142,24 +143,24 @@ int Kachemak::update() A_printf("[Kachemak/update] Updating %s... ", folder_name.c_str()); if (installed_version_code == get_latest_version_code() || force_verify) { - return 3; + return (int)StatusCode::Already; } std::optional patch = get_patch(installed_version_code); if (!patch) { - return 3; + return (int)StatusCode::Already; } - if (free_space_check(patch.value().temp_required, FreeSpaceCheckCategory::Permanent) != 0) + if (free_space_check(patch.value().temp_required, FreeSpaceCheckCategory::Temporary) != 0) { - return 2; + return (int)StatusCode::OOTemp; } std::optional km_installed_version = get_km_version(installed_version_code); if (!km_installed_version) { - return 4; + return (int)StatusCode::NoVer; } // full signature url @@ -169,38 +170,41 @@ int Kachemak::update() std::filesystem::path data_dir_path = sourcemod_path / folder_name; std::stringstream heal_url; heal_url << source_url << km_installed_version.value().file_name; - int verifyRes = butler_verify(sig_url_full.str(), data_dir_path.string(), heal_url.str()); + int verify_ret = butler_verify(sig_url_full.str(), data_dir_path.string(), heal_url.str()); std::stringstream patch_url_full; patch_url_full << source_url << patch.value().url; std::filesystem::path staging_path = sourcemod_path / ("butler-staging-" + folder_name.string()); A_printf("[Kachemak/update] Patching %s from %s to %s, with staging dir at %s. ", folder_name.c_str(), km_installed_version.value().version.c_str(), get_latest_version_code().c_str(), staging_path.c_str()); - int patchRes = butler_patch(patch_url_full.str(), staging_path.string(), patch.value().filename, data_dir_path.string(), patch.value().temp_required); - + int patch_ret = butler_patch(patch_url_full.str(), staging_path.string(), patch.value().filename, data_dir_path.string(), patch.value().temp_required); installed_version_code = get_latest_version_code(); write_version(); - return 0; + if(patch_ret != 0) + { + A_error(ErrorLevel::SERIOUS,"Failiure writing version!"); + return (int)StatusCode::PatchFail; + } + else + { + return (int)StatusCode::Ok; + } } int Kachemak::install() { std::optional latest_version = get_latest_km_version(); - if (!latest_version) - { - return 2; - } int disk_space_status = free_space_check(latest_version.value().download_size, FreeSpaceCheckCategory::Temporary); if (disk_space_status != 0) { return disk_space_status; } - std::string download_uri = source_url + latest_version.value().download_url; + std::string download_uri = source_url + latest_version.value().download_url_p2p; A_printf("[Kachemak/install] Downloading via torrent..."); int download_status = torrent::libtorrent_download(download_uri, temp_path.string(), &event_system); if (download_status != 0) { A_error(ErrorLevel::SERIOUS,"[Kachemak/install] Download failed - ret val %d \n", download_status); - return download_status; + return (int)StatusCode::DlFail; } A_printf("[Kachemak/install] Download complete: extracting..."); std::filesystem::create_directory(sourcemod_path.string() / folder_name); @@ -210,12 +214,9 @@ int Kachemak::install() A_printf("[Kachemak/install] Extraction done!"); installed_version_code = get_latest_version_code(); write_version(); - return 0; - } - else - { - return 1; + return (int)StatusCode::Ok; } + return (int)StatusCode::ExtFail; } int Kachemak::install_path(std::filesystem::path custom_path) @@ -230,7 +231,7 @@ int Kachemak::install_path(std::filesystem::path custom_path) { return disk_space_status; } - std::string download_uri = source_url + latest_version.value().download_url; + std::string download_uri = source_url + latest_version.value().download_url_p2p; A_printf("[Kachemak/InstallInPath] Downloading via torrent..."); int download_status = torrent::libtorrent_download(download_uri, temp_path.string(), &event_system); // std::filesystem::path path = net::download_to_temp(downloadUri, latestVersion.value().file_name, @@ -267,13 +268,13 @@ int Kachemak::extract(const std::string &input_file, const std::string &output_d if (free_space_check(size * 2, FreeSpaceCheckCategory::Permanent) != 0) { A_printf("[Kachemak/extract] Not enough space. Exiting."); - return 1; + return (int)StatusCode::OOPerm; } int ret = sys::extract_zip((temp_path / input_file).string(), output_directory); if (ret != 0) { A_error(ErrorLevel::SERIOUS,"[Kachemak/extract] Extraction Failed - %s\n", zip_strerror(ret)); - return -1; + return (int)StatusCode::ExtFail; } installed_version_code = get_latest_version_code(); write_version(); diff --git a/winter/Code/emley/kachemak/kachemak.hpp b/winter/Code/emley/kachemak/kachemak.hpp index f487ebd..4abd4c5 100644 --- a/winter/Code/emley/kachemak/kachemak.hpp +++ b/winter/Code/emley/kachemak/kachemak.hpp @@ -12,7 +12,7 @@ struct KachemakVersion { std::string file_name; - std::string download_url; + std::string download_url_p2p; std::size_t download_size; std::size_t extract_size; std::string version; @@ -24,6 +24,7 @@ struct KachemakPatch std::string url; std::string filename; std::size_t temp_required; + }; enum class FreeSpaceCheckCategory @@ -31,6 +32,19 @@ enum class FreeSpaceCheckCategory Temporary, Permanent }; +enum class StatusCode +{ + Ok, // all good + OOTemp, // out of temp space + OOPerm, // out of perm. space + Already, // already installed + NoVer, // version doesn't exist? + ESymlink, // error creating symlink + PatchFail, // error patching + ExtFail, // error extracting + DlFail, // error downloading +}; + class Kachemak : public Version { diff --git a/winter/Code/palace/palace.cpp b/winter/Code/palace/palace.cpp index d53e7a6..5486477 100644 --- a/winter/Code/palace/palace.cpp +++ b/winter/Code/palace/palace.cpp @@ -171,7 +171,7 @@ int palace::update_game(const std::string &game_name) A_printf("[Palace/UpdateGame] Updating %s....", game_name.c_str()); if (server_games[game_name]->l1->get_installed_version_code().empty()) { - server_games[game_name]->l1->install(); + return server_games[game_name]->l1->install(); } // else if(server_games[game_name]->l1->get_installed_version() == server_games[game_name]->l1->GetLatestVersion() || // server_games[game_name]->l1->force_verify){ @@ -179,7 +179,7 @@ int palace::update_game(const std::string &game_name) // } else { - server_games[game_name]->l1->update(); + return server_games[game_name]->l1->update(); } return 0; } @@ -195,7 +195,7 @@ int palace::update_game_with_path(const std::string &game_name, const std::strin // Then we practically do the same thing except inserting the sanitized path to the overloaded install function. if (server_games[game_name]->l1->get_installed_version_code().empty()) { - server_games[game_name]->l1->install_path(sanitized_path); + return server_games[game_name]->l1->install_path(sanitized_path); } // else if(server_games[game_name]->l1->get_installed_version() == server_games[game_name]->l1->GetLatestVersion() || // server_games[game_name]->l1->force_verify){