mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-18 00:12:09 +00:00
Fix the network plugin OTA update flow
This commit is contained in:
@@ -1241,13 +1241,14 @@ int GUI_App::download_plugin(std::string name, std::string package_name, Install
|
||||
// get_url
|
||||
std::string url = get_plugin_url(name, app_config->get_country_code());
|
||||
std::string download_url;
|
||||
std::string online_version;
|
||||
Slic3r::Http http_url = Slic3r::Http::get(url);
|
||||
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: check the plugin from " << url;
|
||||
http_url.timeout_connect(TIMEOUT_CONNECT)
|
||||
.timeout_max(TIMEOUT_RESPONSE)
|
||||
.header("X-BBL-OS-Type", os_type)
|
||||
.on_complete(
|
||||
[&download_url](std::string body, unsigned status) {
|
||||
[&download_url, &online_version](std::string body, unsigned status) {
|
||||
try {
|
||||
json j = json::parse(body);
|
||||
std::string message = j["message"].get<std::string>();
|
||||
@@ -1257,6 +1258,7 @@ int GUI_App::download_plugin(std::string name, std::string package_name, Install
|
||||
if (resource.is_array()) {
|
||||
for (auto iter = resource.begin(); iter != resource.end(); iter++) {
|
||||
Semver version;
|
||||
std::string version_str;
|
||||
std::string url;
|
||||
std::string type;
|
||||
std::string vendor;
|
||||
@@ -1267,7 +1269,8 @@ int GUI_App::download_plugin(std::string name, std::string package_name, Install
|
||||
BOOST_LOG_TRIVIAL(info) << "[download_plugin]: get version of settings's type, " << sub_iter.value();
|
||||
}
|
||||
else if (boost::iequals(sub_iter.key(), "version")) {
|
||||
version = *(Semver::parse(sub_iter.value()));
|
||||
version_str = sub_iter.value();
|
||||
version = *(Semver::parse(version_str));
|
||||
}
|
||||
else if (boost::iequals(sub_iter.key(), "description")) {
|
||||
description = sub_iter.value();
|
||||
@@ -1278,6 +1281,7 @@ int GUI_App::download_plugin(std::string name, std::string package_name, Install
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "[download_plugin 1]: get type " << type << ", version " << version.to_string() << ", url " << url;
|
||||
download_url = url;
|
||||
online_version = version_str;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1367,6 +1371,26 @@ int GUI_App::download_plugin(std::string name, std::string package_name, Install
|
||||
result = -1;
|
||||
});
|
||||
http.perform_sync();
|
||||
|
||||
// The cloud endpoint serves the newest build of the requested series, which may be
|
||||
// newer than the configured version. Adopt the actual downloaded version so that
|
||||
// install_plugin() names the library after what it really contains - otherwise the
|
||||
// post-load config sync (on_init_network) points at a file name that does not exist
|
||||
// and the plugin is "lost" on the following launch. Legacy mode is left untouched:
|
||||
// is_legacy_version() matches exactly and drives the legacy struct layout.
|
||||
if (result >= 0 && name == "plugins" && !online_version.empty() && !use_legacy_network_plugin()) {
|
||||
std::string configured = app_config->get_network_plugin_version();
|
||||
if (configured.empty())
|
||||
configured = get_latest_network_version();
|
||||
if (configured != online_version
|
||||
&& configured.size() >= 8 && online_version.size() >= 8
|
||||
&& configured.compare(0, 8, online_version, 0, 8) == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "[download_plugin] server returned " << online_version
|
||||
<< " for configured " << configured << ", adopting it";
|
||||
app_config->set_network_plugin_version(online_version);
|
||||
}
|
||||
}
|
||||
|
||||
j["result"] = result < 0 ? "failed" : "success";
|
||||
j["error_msg"] = err_msg;
|
||||
return result;
|
||||
@@ -3270,7 +3294,7 @@ void GUI_App::copy_network_if_available()
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path data_dir_path(data_dir_str);
|
||||
auto plugin_folder = data_dir_path / "plugins";
|
||||
auto cache_folder = data_dir_path / "ota";
|
||||
auto cache_folder = data_dir_path / "ota" / "plugins";
|
||||
std::string changelog_file = cache_folder.string() + "/network_plugins.json";
|
||||
|
||||
std::string cached_version;
|
||||
@@ -3364,8 +3388,13 @@ void GUI_App::copy_network_if_available()
|
||||
fs::remove(live555_library);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Copying live555 library from " << live555_library << " to " << live555_library_dst << " successfully.";
|
||||
}
|
||||
if (boost::filesystem::exists(changelog_file))
|
||||
fs::remove(changelog_file);
|
||||
// All cached files consumed - drop the whole ota/plugins cache folder.
|
||||
try {
|
||||
if (boost::filesystem::exists(cache_folder))
|
||||
fs::remove_all(cache_folder);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": failed to remove the plugin cache folder " << cache_folder.string();
|
||||
}
|
||||
app_config->set("update_network_plugin", "false");
|
||||
}
|
||||
|
||||
|
||||
@@ -202,34 +202,45 @@ void UpdatePluginDialog::update_info(std::string json_path)
|
||||
wxString version;
|
||||
wxString description;
|
||||
|
||||
// Parse defensively: a missing or malformed changelog must never leave the
|
||||
// dialog blank, so fall back to a generic prompt instead of returning early.
|
||||
try {
|
||||
boost::nowide::ifstream ifs(json_path);
|
||||
json j;
|
||||
ifs >> j;
|
||||
|
||||
version_str = j["version"];
|
||||
description_str = j["description"];
|
||||
if (j.contains("version"))
|
||||
version_str = j["version"];
|
||||
if (j.contains("description"))
|
||||
description_str = j["description"];
|
||||
}
|
||||
catch (nlohmann::detail::parse_error& err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << json_path << " got a nlohmann::detail::parse_error, reason = " << err.what();
|
||||
return;
|
||||
catch (std::exception& err) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << json_path << " failed, reason = " << err.what();
|
||||
}
|
||||
|
||||
version = from_u8(version_str);
|
||||
description = from_u8(description_str);
|
||||
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("A new Network plug-in (%s) is available. Do you want to install it?"), version));
|
||||
if (version.IsEmpty())
|
||||
m_text_up_info->SetLabel(_L("A new Network plug-in is available. Do you want to install it?"));
|
||||
else
|
||||
m_text_up_info->SetLabel(wxString::Format(_L("A new Network plug-in (%s) is available. Do you want to install it?"), version));
|
||||
m_text_up_info->SetMinSize(wxSize(FromDIP(260), -1));
|
||||
m_text_up_info->SetMaxSize(wxSize(FromDIP(260), -1));
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_text_label = new ::Label(m_vebview_release_note, Label::Body_13, description, LB_AUTO_WRAP);
|
||||
m_text_label->SetMinSize(wxSize(FromDIP(235), -1));
|
||||
m_text_label->SetMaxSize(wxSize(FromDIP(235), -1));
|
||||
|
||||
sizer_text_release_note->Add(m_text_label, 0, wxALL, 5);
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
m_vebview_release_note->Fit();
|
||||
if (description.IsEmpty()) {
|
||||
m_vebview_release_note->Hide();
|
||||
} else {
|
||||
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
|
||||
auto m_text_label = new ::Label(m_vebview_release_note, Label::Body_13, description, LB_AUTO_WRAP);
|
||||
m_text_label->SetMinSize(wxSize(FromDIP(235), -1));
|
||||
m_text_label->SetMaxSize(wxSize(FromDIP(235), -1));
|
||||
|
||||
sizer_text_release_note->Add(m_text_label, 0, wxALL, 5);
|
||||
m_vebview_release_note->SetSizer(sizer_text_release_note);
|
||||
m_vebview_release_note->Layout();
|
||||
m_vebview_release_note->Fit();
|
||||
}
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
Layout();
|
||||
Fit();
|
||||
|
||||
@@ -782,9 +782,9 @@ void PresetUpdater::priv::sync_tooltip(std::string http_url, std::string languag
|
||||
// return true means there are plugins files
|
||||
bool PresetUpdater::priv::get_cached_plugins_version(std::string& cached_version, bool &force)
|
||||
{
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path data_dir_path(data_dir_str);
|
||||
auto cache_folder = data_dir_path / "ota";
|
||||
// The OTA plugin cache lives in its own ota/plugins subfolder; the update dialog
|
||||
// (Plater::priv::update_plugin_when_launch) reads the changelog from the same place.
|
||||
auto cache_folder = cache_path / "plugins";
|
||||
std::string network_library, player_library, live555_library;
|
||||
bool has_plugins = false;
|
||||
|
||||
@@ -838,6 +838,25 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
|
||||
}
|
||||
std::string curr_version = GUI::wxGetApp().use_legacy_network_plugin() ? BAMBU_NETWORK_AGENT_VERSION_LEGACY : get_latest_network_version();
|
||||
std::string using_version = curr_version.substr(0, 9) + "00";
|
||||
auto cache_plugin_folder = cache_path / "plugins";
|
||||
|
||||
// Orca: drop leftovers from the old flat ota/ cache layout (pre ota/plugins) so the
|
||||
// stale files cannot linger forever after this layout migration.
|
||||
{
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
const char* legacy_names[] = {"bambu_networking.dll", "BambuSource.dll", "live555.dll", "network_plugins.json"};
|
||||
#elif defined(__WXMAC__)
|
||||
const char* legacy_names[] = {"libbambu_networking.dylib", "libBambuSource.dylib", "liblive555.dylib", "network_plugins.json"};
|
||||
#else
|
||||
const char* legacy_names[] = {"libbambu_networking.so", "libBambuSource.so", "liblive555.so", "network_plugins.json"};
|
||||
#endif
|
||||
for (const char* name : legacy_names) {
|
||||
boost::system::error_code ec;
|
||||
auto legacy_file = cache_path / name;
|
||||
if (boost::filesystem::exists(legacy_file, ec))
|
||||
boost::filesystem::remove(legacy_file, ec);
|
||||
}
|
||||
}
|
||||
|
||||
std::string cached_version;
|
||||
bool force_upgrade = false;
|
||||
@@ -868,64 +887,11 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
|
||||
}
|
||||
|
||||
if (need_delete_cache) {
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path data_dir_path(data_dir_str);
|
||||
auto cache_folder = data_dir_path / "ota";
|
||||
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
auto network_library = cache_folder / "bambu_networking.dll";
|
||||
auto player_library = cache_folder / "BambuSource.dll";
|
||||
auto live555_library = cache_folder / "live555.dll";
|
||||
#elif defined(__WXMAC__)
|
||||
auto network_library = cache_folder / "libbambu_networking.dylib";
|
||||
auto player_library = cache_folder / "libBambuSource.dylib";
|
||||
auto live555_library = cache_folder / "liblive555.dylib";
|
||||
#else
|
||||
auto network_library = cache_folder / "libbambu_networking.so";
|
||||
auto player_library = cache_folder / "libBambuSource.so";
|
||||
auto live555_library = cache_folder / "liblive555.so";
|
||||
#endif
|
||||
auto changelog_file = cache_folder / "network_plugins.json";
|
||||
|
||||
if (boost::filesystem::exists(network_library))
|
||||
{
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the file "<<network_library.string();
|
||||
try {
|
||||
fs::remove(network_library);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins file " << network_library.string();
|
||||
}
|
||||
}
|
||||
if (boost::filesystem::exists(player_library))
|
||||
{
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the file "<<player_library.string();
|
||||
try {
|
||||
fs::remove(player_library);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins file " << player_library.string();
|
||||
}
|
||||
}
|
||||
if (boost::filesystem::exists(live555_library))
|
||||
{
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the file " << live555_library.string();
|
||||
try {
|
||||
fs::remove(live555_library);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins file " << live555_library.string();
|
||||
}
|
||||
}
|
||||
if (boost::filesystem::exists(changelog_file))
|
||||
{
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the file "<<changelog_file.string();
|
||||
try {
|
||||
fs::remove(changelog_file);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins file " << changelog_file.string();
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the plugins directory " << cache_plugin_folder.string();
|
||||
try {
|
||||
fs::remove_all(cache_plugin_folder);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the plugins directory " << cache_plugin_folder.string();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,7 +909,7 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
|
||||
try {
|
||||
std::map<std::string, Resource> resources
|
||||
{
|
||||
{"slicer/plugins/cloud", { using_version, "", "", false, cache_path.string(), {"plugins"}}}
|
||||
{"slicer/plugins/cloud", { using_version, "", "", false, cache_plugin_folder.string()}}
|
||||
};
|
||||
sync_resources(http_url, resources, true, plugin_version, "network_plugins.json");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user