Merge branch '2.2.3' into dev_bug_fixed_2.3.0_alves

This commit is contained in:
alves
2026-01-19 16:16:55 +08:00
18 changed files with 588 additions and 733 deletions

View File

@@ -164,6 +164,8 @@ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS2)(
#include <gtk/gtk.h>
#endif
#define UPDATE_BY_USER 1
using namespace std::literals;
namespace pt = boost::property_tree;
@@ -909,44 +911,6 @@ void GUI_App::post_init()
}
//#endif
//BBS: remove GCodeViewer as seperate APP logic
/*if (this->init_params->start_as_gcodeviewer) {
if (! this->init_params->input_files.empty())
this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
}
else
{
if (! this->init_params->preset_substitutions.empty())
show_substitutions_info(this->init_params->preset_substitutions);
#if 0
// Load the cummulative config over the currently active profiles.
//FIXME if multiple configs are loaded, only the last one will have an effect.
// We need to decide what to do about loading of separate presets (just print preset, just filament preset etc).
// As of now only the full configs are supported here.
if (!m_print_config.empty())
this->gui->mainframe->load_config(m_print_config);
#endif
if (! this->init_params->load_configs.empty())
// Load the last config to give it a name at the UI. The name of the preset may be later
// changed by loading an AMF or 3MF.
//FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config.
this->mainframe->load_config_file(this->init_params->load_configs.back());
// If loading a 3MF file, the config is loaded from the last one.
if (!this->init_params->input_files.empty()) {
const std::vector<size_t> res = this->plater()->load_files(this->init_params->input_files);
if (!res.empty() && this->init_params->input_files.size() == 1) {
// Update application titlebar when opening a project file
const std::string& filename = this->init_params->input_files.front();
//BBS: remove amf logic as project
if (boost::algorithm::iends_with(filename, ".3mf"))
this->plater()->set_project_filename(filename);
}
}
if (! this->init_params->extra_config.empty())
this->mainframe->load_config(this->init_params->extra_config);
}*/
// BBS: to be checked
#if 1
// show "Did you know" notification
@@ -999,19 +963,13 @@ void GUI_App::post_init()
std::string language = GUI::into_u8(current_language_code());
std::string network_ver = Slic3r::NetworkAgent::get_version();
bool sys_preset = app_config->get("sync_system_preset") == "true";
this->preset_updater->sync(http_url, language, network_ver, sys_preset ? preset_bundle : nullptr);
this->check_new_version_sf();
if (is_user_login() && !app_config->get_stealth_mode()) {
// this->check_privacy_version(0);
request_user_handle(0);
}
//this->preset_updater->sync(http_url, language, network_ver, sys_preset ? preset_bundle : nullptr);
this->preset_updater->sync_web_async(true);
this->check_new_version_sf(false, false);
});
}
if (is_user_login())
request_user_handle(0);
if(!m_networking_need_update && m_agent) {
m_agent->set_on_ssdp_msg_fn(
[this](std::string json_str) {
@@ -1651,37 +1609,11 @@ void GUI_App::init_networking_callbacks()
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": enter, m_agent=%1%")%m_agent;
if (m_agent) {
//set callbacks
//m_agent->set_on_user_login_fn([this](int online_login, bool login) {
// GUI::wxGetApp().request_user_handle(online_login);
// });
m_agent->set_server_callback([](std::string url, int status) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": server_callback, url=%1%, status=%2%") % url % status;
//CallAfter([this]() {
// if (!m_server_error_dialog) {
// /*m_server_error_dialog->EndModal(wxCLOSE);
// m_server_error_dialog->Destroy();
// m_server_error_dialog = nullptr;*/
// m_server_error_dialog = new NetworkErrorDialog(mainframe);
// }
//
// if(plater()->get_select_machine_dialog() && plater()->get_select_machine_dialog()->IsShown()){
// return;
// }
//
// if (m_server_error_dialog->m_show_again) {
// return;
// }
//
// if (m_server_error_dialog->IsShown()) {
// return;
// }
//
// m_server_error_dialog->ShowModal();
//});
});
});
m_agent->set_on_server_connected_fn([this](int return_code, int reason_code) {
if (m_is_closing) {
@@ -2572,17 +2504,7 @@ bool GUI_App::on_init_inner()
preset_updater = new PresetUpdater();
Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) {
if (this->plater_ != nullptr) {
// this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAvailable);
//BBS show msg box to download new version
/* wxString tips = wxString::Format(_L("Click to download new version in default browser: %s"), version_info.version_str);
DownloadDialog dialog(this->mainframe,
tips,
_L("New version of Snapmaker Orca"),
false,
wxCENTER | wxICON_INFORMATION);
dialog.SetExtendedMessage(extmsg);*/
std::string skip_version_str = this->app_config->get("app", "skip_version");
bool skip_this_version = false;
if (!skip_version_str.empty()) {
@@ -2599,7 +2521,6 @@ bool GUI_App::on_init_inner()
UpdateVersionDialog dialog(this->mainframe);
wxString extmsg = wxString::FromUTF8(version_info.description);
dialog.update_version_info(extmsg, version_info.version_str);
//dialog.update_version_info(version_info.description);
if (evt.GetInt() != 0) {
dialog.m_button_skip_version->Hide();
}
@@ -2628,16 +2549,20 @@ bool GUI_App::on_init_inner()
false,
wxCENTER | wxICON_INFORMATION);
dialog.SetExtendedMessage(description_text);
int result = dialog.ShowModal();
switch (result)
{
case wxID_YES:
wxLaunchDefaultBrowser(download_url);
wxGetApp().mainframe->Close(true);
break;
case wxID_NO:
wxGetApp().mainframe->Close(true);
break;
case wxID_CANCEL:
wxGetApp().mainframe->Close(true);
break;
default:
wxGetApp().mainframe->Close(true);
}
@@ -2657,6 +2582,24 @@ bool GUI_App::on_init_inner()
});
dlg.ShowModal();
});
Bind(EVT_NO_PRESET_UPDATE, [this](const wxCommandEvent& evt) {
wxString msg = _L("The configuration is up to date.");
InfoDialog dlg(nullptr, _L("Info"), msg);
dlg.ShowModal();
});
Bind(EVT_NO_WEB_RESOURCE_UPDATE, [this](const wxCommandEvent& evt) {
wxString msg = _L("This is the newest version.");
InfoDialog dlg(nullptr, _L("Info"), msg);
dlg.ShowModal();
});
Bind(EVT_REQUEST_SERVER_FAIL, [this](const wxCommandEvent& evt) {
wxString msg = evt.GetString();
InfoDialog dlg(nullptr, _L("Error"), msg);
dlg.ShowModal();
});
}
else {
#ifdef __WXMSW__
@@ -2670,13 +2613,6 @@ bool GUI_App::on_init_inner()
preset_bundle->backup_user_folder();
Bind(EVT_SET_SELECTED_MACHINE, &GUI_App::on_set_selected_machine, this);
Bind(EVT_UPDATE_MACHINE_LIST, &GUI_App::on_update_machine_list, this);
Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);
Bind(EVT_USER_LOGIN_HANDLE, &GUI_App::on_user_login_handle, this);
Bind(EVT_CHECK_PRIVACY_VER, &GUI_App::on_check_privacy_update, this);
Bind(EVT_CHECK_PRIVACY_SHOW, &GUI_App::show_check_privacy_dlg, this);
Bind(EVT_SHOW_IP_DIALOG, &GUI_App::show_ip_address_enter_dialog_handler, this);
@@ -2770,26 +2706,6 @@ bool GUI_App::on_init_inner()
mainframe->Show(true);
BOOST_LOG_TRIVIAL(info) << "main frame firstly shown";
//#if BBL_HAS_FIRST_PAGE
//BBS: set tp3DEditor firstly
/*plater_->canvas3D()->enable_render(false);
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
scrn->SetText(_L("Loading Opengl resourses..."));
plater_->select_view_3D("3D");
//BBS init the opengl resource here
Size canvas_size = plater_->canvas3D()->get_canvas_size();
wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
wxGetApp().init_opengl();
plater_->canvas3D()->init();
wxGetApp().imgui()->new_frame();
plater_->canvas3D()->enable_render(true);
plater_->canvas3D()->render();
if (is_editor())
mainframe->select_tab(size_t(0));*/
//#else
//plater_->trigger_restore_project(1);
//#endif
obj_list()->set_min_height();
update_mode(); // update view mode after fix of the object_list size
@@ -2865,28 +2781,6 @@ bool GUI_App::on_init_inner()
"configuration file.\nPlease note, application settings will be lost, but printer profiles will not be affected."));
}
//启动定时器,轮询进行机器发现
// m_machine_find_timer = new wxTimer(this, m_machine_find_id);
// Bind(wxEVT_TIMER, [this](wxTimerEvent& event) {
// if (!m_machine_find_engine && GUI_App::m_app_alive.load()) {
// machine_find();
// }
// }, m_machine_find_timer->GetId());
// if (!m_machine_find_engine && GUI_App::m_app_alive.load()) {
// machine_find();
// }
//#ifdef __APPLE__
// m_machine_find_timer->Start(1000 * 60 * 2);
//#elif defined(__linux__)
// m_machine_find_timer->Start(1000 * 60 * 2);
//#else
// m_machine_find_timer->Start(5000);
//#endif
return true;
}
@@ -4187,20 +4081,6 @@ bool GUI_App::check_login()
return result;
}
void GUI_App::request_user_handle(int online_login)
{
auto evt = new wxCommandEvent(EVT_USER_LOGIN_HANDLE);
evt->SetInt(online_login);
wxQueueEvent(this, evt);
}
void GUI_App::request_user_login(int online_login)
{
auto evt = new wxCommandEvent(EVT_USER_LOGIN);
evt->SetInt(online_login);
wxQueueEvent(this, evt);
}
void GUI_App::request_user_logout()
{
if (m_agent && m_agent->is_user_login()) {
@@ -4434,27 +4314,6 @@ std::string GUI_App::handle_web_request(std::string cmd)
return "";
}
void GUI_App::handle_script_message(std::string msg)
{
try {
json j = json::parse(msg);
if (j.contains("command")) {
wxString cmd = j["command"];
if (cmd == "user_login") {
if (m_agent) {
m_agent->change_user(j.dump());
if (m_agent->is_user_login()) {
request_user_login(1);
}
}
}
}
}
catch (...) {
;
}
}
void GUI_App::request_model_download(wxString url)
{
if (plater_) {
@@ -4581,54 +4440,6 @@ void GUI_App::enable_user_preset_folder(bool enable)
}
}
void GUI_App::on_set_selected_machine(wxCommandEvent &evt)
{
// Orca: do not connect to default device during app startup, because some of the lan machines might not online yet
// and user will be prompted by several "Connect XXX failed" error message.
return;
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (dev) {
dev->set_selected_machine(m_agent->get_user_selected_machine());
}
}
void GUI_App::on_update_machine_list(wxCommandEvent &evt)
{
/* DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (dev) {
dev->add_user_subscribe();
}*/
}
void GUI_App::on_user_login_handle(wxCommandEvent &evt)
{
if (!m_agent) { return; }
int online_login = evt.GetInt();
m_agent->connect_server();
// get machine list
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
boost::thread update_thread = boost::thread([this, dev] {
dev->update_user_machine_list_info();
auto evt = new wxCommandEvent(EVT_SET_SELECTED_MACHINE);
wxQueueEvent(this, evt);
});
if (online_login) {
remove_user_presets();
enable_user_preset_folder(true);
preset_bundle->load_user_presets(m_agent->get_user_id(), ForwardCompatibilitySubstitutionRule::Enable);
mainframe->update_side_preset_ui();
GUI::wxGetApp().mainframe->show_sync_dialog();
}
}
void GUI_App::check_track_enable()
{
// Orca: alaways disable track event
@@ -4638,14 +4449,6 @@ void GUI_App::check_track_enable()
}
}
void GUI_App::on_user_login(wxCommandEvent &evt)
{
if (!m_agent) { return; }
int online_login = evt.GetInt();
// check privacy before handle
check_privacy_version(online_login);
check_track_enable();
}
bool GUI_App::is_studio_active()
{
@@ -4662,95 +4465,6 @@ void GUI_App::reset_to_active()
last_active_point = std::chrono::system_clock::now();
}
void GUI_App::check_update(bool show_tips, int by_user)
{
if (version_info.version_str.empty()) return;
if (version_info.url.empty()) return;
auto curr_version = Semver::parse(SLIC3R_VERSION);
auto remote_version = Semver::parse(version_info.version_str);
if (curr_version && remote_version && (*remote_version > *curr_version)) {
if (version_info.force_upgrade) {
wxGetApp().app_config->set_bool("force_upgrade", version_info.force_upgrade);
wxGetApp().app_config->set("upgrade", "force_upgrade", true);
wxGetApp().app_config->set("upgrade", "description", version_info.description);
wxGetApp().app_config->set("upgrade", "version", version_info.version_str);
wxGetApp().app_config->set("upgrade", "url", version_info.url);
GUI::wxGetApp().enter_force_upgrade();
}
else {
GUI::wxGetApp().request_new_version(by_user);
}
} else {
wxGetApp().app_config->set("upgrade", "force_upgrade", false);
if (show_tips)
this->no_new_version();
}
}
void GUI_App::check_new_version(bool show_tips, int by_user)
{
return; // orca: not used, see check_new_version_sf
std::string platform = "windows";
#ifdef __WINDOWS__
platform = "windows";
#endif
#ifdef __APPLE__
platform = "macos";
#endif
#ifdef __LINUX__
platform = "linux";
#endif
std::string query_params = (boost::format("?name=slicer&version=%1%&guide_version=%2%")
% VersionInfo::convert_full_version(SLIC3R_VERSION)
% VersionInfo::convert_full_version("0.0.0.1")
).str();
std::string url = get_http_url(app_config->get_country_code()) + query_params;
Slic3r::Http http = Slic3r::Http::get(url);
http.header("accept", "application/json")
.timeout_connect(TIMEOUT_CONNECT)
.timeout_max(TIMEOUT_RESPONSE)
.on_complete([this, show_tips, by_user](std::string body, unsigned) {
try {
json j = json::parse(body);
if (j.contains("message")) {
if (j["message"].get<std::string>() == "success") {
if (j.contains("software")) {
if (j["software"].empty() && show_tips) {
this->no_new_version();
}
else {
if (j["software"].contains("url")
&& j["software"].contains("version")
&& j["software"].contains("description")) {
version_info.url = j["software"]["url"].get<std::string>();
version_info.version_str = j["software"]["version"].get<std::string>();
version_info.description = j["software"]["description"].get<std::string>();
}
if (j["software"].contains("force_update")) {
version_info.force_upgrade = j["software"]["force_update"].get<bool>();
}
CallAfter([this, show_tips, by_user](){
this->check_update(show_tips, by_user);
});
}
}
}
}
}
catch (...) {
;
}
})
.on_error([this](std::string body, std::string error, unsigned int status) {
handle_http_error(status, body);
BOOST_LOG_TRIVIAL(error) << "check new version error" << body;
}).perform();
}
//parse the string, if it doesn't contain a valid version string, return invalid version.
Semver get_version(const std::string& str, const std::regex& regexp) {
std::smatch match;
@@ -5029,110 +4743,145 @@ void maybe_attach_updater_signature(Http& http, const std::string& canonical_que
} // namespace
void GUI_App::check_new_version_sf(bool show_tips, int by_user)
void GUI_App::check_web_version()
{
if (preset_updater != nullptr)
preset_updater->sync_web_async();
}
void GUI_App::check_preset_version()
{
if (preset_updater != nullptr)
preset_updater->sync_config_async();
}
void GUI_App::check_new_version_sf(bool show_tips, bool by_user)
{
std::string update_url = app_config->get_version_upgrade_url();
AppConfig* app_config = wxGetApp().app_config;
bool check_stable_only = app_config->get_bool("check_stable_update_only");
auto version_check_url = app_config->version_check_url(check_stable_only);
Http::get(version_check_url)
.on_error([&](std::string body, std::string error, unsigned http_status) {
Http::get(update_url)
.on_error([&, by_user](std::string body, std::string error, unsigned http_status) {
(void)body;
wxCommandEvent* evt = new wxCommandEvent(EVT_REQUEST_SERVER_FAIL);
wxString errorMsg = wxString::Format(_L("request to server update soft fail with body:%s,error:%s,status:%d"), body,
error, http_status);
evt->SetString(errorMsg);
if(by_user)
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%", "check_new_version_sf", http_status,
error);
})
.timeout_connect(1)
.on_complete([this,by_user, check_stable_only](std::string body, unsigned http_status) {
// Http response OK
if (http_status != 200)
.timeout_connect(TIMEOUT_CONNECT)
.on_complete([this,by_user](std::string body, unsigned http_status) {
// Http response OK
if (http_status != 200) {
BOOST_LOG_TRIVIAL(error) << format("status not 200 with: `%1%`: HTTP %2%", "check_new_version_sf", http_status);
return;
try {
boost::trim(body);
// Orca: parse github release, inspired by SS
boost::property_tree::ptree root;
std::stringstream json_stream(body);
boost::property_tree::read_json(json_stream, root);
}
try {
json jsonObj = json::parse(body);
auto errCode = jsonObj["code"];
if (errCode != 200)
return;
// at least two number, use '.' as separator. can be followed by -Az23 for prereleased and +Az42 for
// metadata
std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9]+)?(\\+[A-Za-z0-9]+)?");
auto dataObj = jsonObj.value("data", json::object());
auto isFullUpgrade = dataObj.value("is_full_upgrade", true);
auto isForceUpgrade = dataObj.value("is_force_upgrade", false);
version_info.force_upgrade = isForceUpgrade;
Semver current_version = get_version(Snapmaker_VERSION, matcher);
Semver best_pre(0, 0, 0);
Semver best_release(0, 0, 0);
std::string best_pre_url;
std::string best_release_url;
std::string best_release_content;
std::string best_pre_content;
const std::regex reg_num("([0-9]+)");
if (check_stable_only) {
std::string tag = root.get<std::string>("tag_name");
if (tag[0] == 'v')
tag.erase(0, 1);
for (std::regex_iterator it = std::sregex_iterator(tag.begin(), tag.end(), reg_num); it != std::sregex_iterator(); ++it) {}
Semver tag_version = get_version(tag, matcher);
if (root.get<bool>("prerelease")) {
if (best_pre < tag_version) {
best_pre = tag_version;
best_pre_url = root.get<std::string>("html_url");
best_pre_content = root.get<std::string>("body");
best_pre.set_prerelease("Preview");
}
} else {
if (best_release < tag_version) {
best_release = tag_version;
best_release_url = root.get<std::string>("html_url");
best_release_content = root.get<std::string>("body");
version_info.version_str = dataObj.value("version", "");
auto releaseType = dataObj.value("release_type", "");
auto platformType = dataObj.value("platform_type", "");
int fileSize = 0;
std::string fileMd5 = "";
std::string fileSha256 = "";
std::string reservedData = "";
std::string reservedData2 = "";
// win x86_x64, mac arm/x86_x64 universal
auto fullObj = dataObj.value("full", json::object());
auto defaultObj = fullObj.value("default", json::object());
auto armObj = fullObj.value("arm", json::object());
auto intelObj = fullObj.value("intel", json::object());
version_info.description = fullObj.value("file_describe", "");
if (platformType == "win") {
fileSize = defaultObj.value("file_size", 0);
fileMd5 = defaultObj.value("file_md5", "");
fileSha256 = defaultObj.value("file_sha256", "");
version_info.url = defaultObj.value("file_url", "");
reservedData = defaultObj.value("reserved_1", "");
reservedData2 = defaultObj.value("reserved_2", "");
}
else if (platformType == "mac")
{
bool isArm64 = false;
#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
isArm64 = true;
#else
isArm64 = false;
#endif
json platformObj = defaultObj;
if (isArm64) {
if (!armObj.empty()) {
platformObj = armObj;
}
}
} else {
for (auto json_version : root) {
std::string tag = json_version.second.get<std::string>("tag_name");
if (tag[0] == 'v')
tag.erase(0, 1);
for (std::regex_iterator it = std::sregex_iterator(tag.begin(), tag.end(), reg_num); it != std::sregex_iterator();
++it) {}
Semver tag_version = get_version(tag, matcher);
if (json_version.second.get<bool>("prerelease")) {
if (best_pre < tag_version) {
best_pre = tag_version;
best_pre_url = json_version.second.get<std::string>("html_url");
best_pre_content = json_version.second.get<std::string>("body");
best_pre.set_prerelease("Preview");
}
} else {
if (best_release < tag_version) {
best_release = tag_version;
best_release_url = json_version.second.get<std::string>("html_url");
best_release_content = json_version.second.get<std::string>("body");
}
else
{
if (!intelObj.empty()) {
platformObj = intelObj;
}
}
}
// if release is more recent than beta, use release anyway
if (best_pre < best_release) {
best_pre = best_release;
best_pre_url = best_release_url;
best_pre_content = best_release_content;
fileSize = platformObj.value("file_size", 0);
fileMd5 = platformObj.value("file_md5", "");
fileSha256 = platformObj.value("file_sha256", "");
version_info.url = platformObj.value("file_url", "");
reservedData = platformObj.value("reserved_1", "");
reservedData2 = platformObj.value("reserved_2", "");
}
// if we're the most recent, don't do anything
if ((check_stable_only ? best_release : best_pre) <= current_version) {
if (by_user != 0)
this->no_new_version();
else
{
BOOST_LOG_TRIVIAL(warning) << "don't support linux upgrade";
return;
}
version_info.url = check_stable_only ? best_release_url : best_pre_url;
version_info.version_str = check_stable_only ? best_release.to_string_sf() : best_pre.to_string_sf();
version_info.description = check_stable_only ? best_release_content : best_pre_content;
version_info.force_upgrade = false;
std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9]+)?(\\+[A-Za-z0-9]+)?");
Semver current_version = get_version(Snapmaker_VERSION, matcher);
Semver server_version = get_version(version_info.version_str, matcher);
if (current_version >= server_version && by_user) {
this->no_new_version();
return;
}
//if (true)
if (isForceUpgrade)
{
wxGetApp().app_config->set_bool("force_upgrade", version_info.force_upgrade);
wxGetApp().app_config->set("upgrade", "force_upgrade", true);
wxGetApp().app_config->set("upgrade", "description", version_info.description);
wxGetApp().app_config->set("upgrade", "version", version_info.version_str);
wxGetApp().app_config->set("upgrade", "url", version_info.url);
GUI::wxGetApp().enter_force_upgrade();
return;
}
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
evt->SetString((check_stable_only ? best_release : best_pre).to_string());
evt->SetString(version_info.url);
if (by_user)
evt->SetInt(UPDATE_BY_USER);
GUI::wxGetApp().QueueEvent(evt);
} catch (...) {}
})
.perform();
.perform_sync();
}
void GUI_App::process_network_msg(std::string dev_id, std::string msg)
{
@@ -5141,15 +4890,6 @@ void GUI_App::process_network_msg(std::string dev_id, std::string msg)
}
}
//BBS pop up a dialog and download files
void GUI_App::request_new_version(int by_user)
{
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
evt->SetString(GUI::from_u8(version_info.version_str));
evt->SetInt(by_user);
GUI::wxGetApp().QueueEvent(evt);
}
void GUI_App::enter_force_upgrade()
{
wxCommandEvent *evt = new wxCommandEvent(EVT_ENTER_FORCE_UPGRADE);
@@ -5166,33 +4906,6 @@ void GUI_App::set_skip_version(bool skip)
}
}
void GUI_App::show_check_privacy_dlg(wxCommandEvent& evt)
{
int online_login = evt.GetInt();
PrivacyUpdateDialog privacy_dlg(this->mainframe, wxID_ANY, _L("Privacy Policy Update"));
privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CONFIRM, [this, online_login](wxCommandEvent &e) {
app_config->set("privacy_version", privacy_version_info.version_str);
app_config->set_bool("privacy_update_checked", true);
request_user_handle(online_login);
});
privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CANCEL, [this](wxCommandEvent &e) {
app_config->set_bool("privacy_update_checked", false);
if (m_agent) {
m_agent->user_logout();
}
});
privacy_dlg.set_text(privacy_version_info.description);
privacy_dlg.on_show();
}
void GUI_App::on_show_check_privacy_dlg(int online_login)
{
auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_SHOW);
evt->SetInt(online_login);
wxQueueEvent(this, evt);
}
bool GUI_App::check_privacy_update()
{
if (privacy_version_info.version_str.empty() || privacy_version_info.description.empty()
@@ -5211,66 +4924,6 @@ bool GUI_App::check_privacy_update()
return false;
}
void GUI_App::on_check_privacy_update(wxCommandEvent& evt)
{
int online_login = evt.GetInt();
bool result = check_privacy_update();
if (result)
on_show_check_privacy_dlg(online_login);
else
request_user_handle(online_login);
}
void GUI_App::check_privacy_version(int online_login)
{
update_http_extra_header();
std::string query_params = "?policy/privacy=00.00.00.00";
std::string url = get_http_url(app_config->get_country_code()) + query_params;
Slic3r::Http http = Slic3r::Http::get(url);
http.header("accept", "application/json")
.timeout_connect(TIMEOUT_CONNECT)
.timeout_max(TIMEOUT_RESPONSE)
.on_complete([this, online_login](std::string body, unsigned) {
try {
json j = json::parse(body);
if (j.contains("message")) {
if (j["message"].get<std::string>() == "success") {
if (j.contains("resources")) {
for (auto it = j["resources"].begin(); it != j["resources"].end(); it++) {
if (it->contains("type")) {
if ((*it)["type"] == std::string("policy/privacy")
&& it->contains("version")
&& it->contains("description")
&& it->contains("url")
&& it->contains("force_update")) {
privacy_version_info.version_str = (*it)["version"].get<std::string>();
privacy_version_info.description = (*it)["description"].get<std::string>();
privacy_version_info.url = (*it)["url"].get<std::string>();
privacy_version_info.force_upgrade = (*it)["force_update"].get<bool>();
break;
}
}
}
CallAfter([this, online_login]() {
auto evt = new wxCommandEvent(EVT_CHECK_PRIVACY_VER);
evt->SetInt(online_login);
wxQueueEvent(this, evt);
});
}
}
}
}
catch (...) {
request_user_handle(online_login);
}
})
.on_error([this, online_login](std::string body, std::string error, unsigned int status) {
request_user_handle(online_login);
BOOST_LOG_TRIVIAL(error) << "check privacy version error" << body;
}).perform();
}
void GUI_App::no_new_version()
{
wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_NO_NEW_VERSION);
@@ -7345,8 +6998,7 @@ void GUI_App::check_updates(const bool verbose)
m_app_conf_exists = true;
}
else if (verbose && updater_result == PresetUpdater::R_NOOP) {
MsgNoUpdates dlg;
dlg.ShowModal();
}
}
catch (const std::exception & ex) {

View File

@@ -557,13 +557,10 @@ private:
void sm_request_login(bool show_user_info = false);
void sm_ShowUserLogin(bool show = true);
void sm_request_user_logout();
void request_user_login(int online_login = 0);
void request_user_handle(int online_login = 0);
void request_user_logout();
int request_user_unbind(std::string dev_id);
std::string handle_web_request(std::string cmd);
void handle_script_message(std::string msg);
void request_model_download(wxString url);
void download_project(std::string project_id);
void request_project_download(std::string project_id);
@@ -573,10 +570,6 @@ private:
void handle_http_error(unsigned int status, std::string body);
void on_http_error(wxCommandEvent &evt);
void on_set_selected_machine(wxCommandEvent& evt);
void on_update_machine_list(wxCommandEvent& evt);
void on_user_login(wxCommandEvent &evt);
void on_user_login_handle(wxCommandEvent& evt);
void enable_user_preset_folder(bool enable);
// BBS
@@ -585,11 +578,10 @@ private:
bool m_studio_active = true;
std::chrono::system_clock::time_point last_active_point;
void check_update(bool show_tips, int by_user);
void check_new_version(bool show_tips = false, int by_user = 0);
void check_new_version_sf(bool show_tips = false, int by_user = 0);
void check_web_version();
void check_preset_version();
void check_new_version_sf(bool show_tips = false, bool by_user = false);
void process_network_msg(std::string dev_id, std::string msg);
void request_new_version(int by_user);
void enter_force_upgrade();
void set_skip_version(bool skip = true);
void no_new_version();
@@ -609,12 +601,8 @@ private:
void start_page_http_server();
void stop_page_http_server();
void switch_staff_pick(bool on);
void on_show_check_privacy_dlg(int online_login = 0);
void show_check_privacy_dlg(wxCommandEvent& evt);
void on_check_privacy_update(wxCommandEvent &evt);
bool check_privacy_update();
void check_privacy_version(int online_login = 0);
void check_track_enable();
static bool catch_error(std::function<void()> cb, const std::string& err);
@@ -794,7 +782,7 @@ private:
bool check_networking_version();
void cancel_networking_install();
void restart_networking();
void check_config_updates_from_updater() { check_updates(false); }
void check_config_updates_from_updater(bool updateByuser = false) { check_updates(updateByuser); }
private:
int updating_bambu_networking();

View File

@@ -676,7 +676,7 @@ std::shared_ptr<HttpServer::Response> HttpServer::bbl_auth_handle_request(const
j["data"]["user"]["avatar"] = user_avatar;
agent->change_user(j.dump());
if (agent->is_user_login()) {
wxGetApp().request_user_login(1);
//wxGetApp().request_user_login(1);
}
GUI::wxGetApp().CallAfter([] { wxGetApp().ShowUserLogin(false); });
std::string location_str = (boost::format("%1%?result=success") % redirect_url).str();

View File

@@ -77,17 +77,15 @@
#include "sentry_wrapper/SentryWrapper.hpp"
#define UPDATE_BUSER true
#define UPDATE_BUAUTO false
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_SELECT_TAB, wxCommandEvent);
wxDEFINE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
wxDEFINE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
wxDEFINE_EVENT(EVT_USER_LOGIN_HANDLE, wxCommandEvent);
wxDEFINE_EVENT(EVT_CHECK_PRIVACY_VER, wxCommandEvent);
wxDEFINE_EVENT(EVT_CHECK_PRIVACY_SHOW, wxCommandEvent);
wxDEFINE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
wxDEFINE_EVENT(EVT_SET_SELECTED_MACHINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPDATE_MACHINE_LIST, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);
@@ -2294,11 +2292,26 @@ static wxMenu* generate_help_menu()
// Check New Version
append_menu_item(helpMenu, wxID_ANY, _L("Check for Update"), _L("Check for Update"),
[](wxCommandEvent&) {
wxGetApp().check_new_version_sf(true, 1);
wxGetApp().check_new_version_sf(true, UPDATE_BUSER);
}, "", nullptr, []() {
return true;
});
append_menu_item(
helpMenu, wxID_ANY, _L("Check for Process Preset Updates"), _L("Check for Process Preset Updates"),
[](wxCommandEvent&) {
wxGetApp().check_preset_version();
},
"", nullptr, []() { return true; });
append_menu_item(
helpMenu, wxID_ANY, _L("Check for Web ResourceUpdates"), _L("Check for Web ResourceUpdates"),
[](wxCommandEvent&) {
wxGetApp().check_web_version();
},
"", nullptr, []() { return true; });
append_menu_item(helpMenu, wxID_ANY, _L("Import Profile"), _L("Import Profile"), [](wxCommandEvent&) {
wxGetApp().import_presets();
});

View File

@@ -417,12 +417,7 @@ public:
};
wxDECLARE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
wxDECLARE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
wxDECLARE_EVENT(EVT_USER_LOGIN_HANDLE, wxCommandEvent);
wxDECLARE_EVENT(EVT_CHECK_PRIVACY_VER, wxCommandEvent);
wxDECLARE_EVENT(EVT_CHECK_PRIVACY_SHOW, wxCommandEvent);
wxDECLARE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
wxDECLARE_EVENT(EVT_SET_SELECTED_MACHINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPDATE_MACHINE_LIST, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);

View File

@@ -441,7 +441,7 @@ DownloadDialog::DownloadDialog(wxWindow *parent, const wxString &msg, const wxSt
: MsgDialog(parent, title, msg, style), msg(msg)
{
add_button(wxID_YES, true, _L("Download"));
add_button(wxID_CANCEL, true, _L("Skip"));
//add_button(wxID_CANCEL, true, _L("Skip"));
finalize();
}

View File

@@ -1198,7 +1198,7 @@ wxWindow* PreferencesDialog::create_general_page()
app_config->save();
auto item_check_stable_version_only = create_item_checkbox(_L("Check for stable updates only"), page, _L("Check for stable updates only"), 50, "check_stable_update_only");
//auto item_check_stable_version_only = create_item_checkbox(_L("Check for stable updates only"), page, _L("Check for stable updates only"), 50, "check_stable_update_only");
std::vector<wxString> Units = {_L("Metric") + " (mm, g)", _L("Imperial") + " (in, oz)"};
auto item_currency = create_item_combobox(_L("Units"), page, _L("Units"), "use_inches", Units);
@@ -1233,7 +1233,7 @@ wxWindow* PreferencesDialog::create_general_page()
auto item_multi_machine = create_item_checkbox(_L("Multi-device Management (Take effect after restarting Snapmaker Orca)."), page, _L("With this option enabled, you can send a task to multiple devices at the same time and manage multiple devices."), 50, "enable_multi_machine");
auto item_auto_arrange = create_item_checkbox(_L("Auto arrange plate after cloning"), page, _L("Auto arrange plate after object cloning"), 50, "auto_arrange");
auto title_presets = create_item_title(_L("Presets"), page, _L("Presets"));
auto title_network = create_item_title(_L("Network"), page, _L("Network"));
//auto title_network = create_item_title(_L("Network"), page, _L("Network"));
auto item_user_sync = create_item_checkbox(_L("Auto sync user presets (Printer/Filament/Process)"), page, _L("User Sync"), 50, "sync_user_preset");
auto item_system_sync = create_item_checkbox(_L("Update built-in Presets automatically."), page, _L("System Sync"), 50, "sync_system_preset");
auto item_save_presets = create_item_button(_L("Clear my choice on the unsaved presets."), _L("Clear"), page, L"", _L("Clear my choice on the unsaved presets."), []() {
@@ -1338,8 +1338,8 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_system_sync, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_remember_printer_config, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_save_presets, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_network, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(item_check_stable_version_only, 0, wxTOP, FromDIP(3));
//sizer_page->Add(title_network, 0, wxTOP | wxEXPAND, FromDIP(20));
//sizer_page->Add(item_check_stable_version_only, 0, wxTOP, FromDIP(3));
// SM Beta: temporarily open the item_stealth_mode and close the network plugin

View File

@@ -96,7 +96,6 @@ ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
ReleaseNoteDialog::~ReleaseNoteDialog() {}
void ReleaseNoteDialog::on_dpi_changed(const wxRect &suggested_rect)
{
}
@@ -129,19 +128,14 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(30));
wxBoxSizer* m_sizer_body = new wxBoxSizer(wxHORIZONTAL);
auto sm = create_scaled_bitmap("Snapmaker_Orca", nullptr, 55);
auto brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, wxSize(FromDIP(55), FromDIP(55)));
wxBoxSizer* m_sizer_right = new wxBoxSizer(wxVERTICAL);
m_text_up_info = new Label(this, Label::Head_13, wxEmptyString, LB_AUTO_WRAP);
m_text_up_info->SetMaxSize(wxSize(FromDIP(260), -1));
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
operation_tips = new ::Label(this, Label::Body_12, _L("Click OK to update the Network plug-in when Snapmaker Orca launches next time."), LB_AUTO_WRAP);
operation_tips->SetMinSize(wxSize(FromDIP(260), -1));
operation_tips->SetMaxSize(wxSize(FromDIP(260), -1));
@@ -213,7 +207,6 @@ UpdatePluginDialog::UpdatePluginDialog(wxWindow* parent /*= nullptr*/)
UpdatePluginDialog::~UpdatePluginDialog() {}
void UpdatePluginDialog::on_dpi_changed(const wxRect& suggested_rect)
{
}
@@ -269,18 +262,11 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxHORIZONTAL);
auto sm = create_scaled_bitmap("Snapmaker_Orca", nullptr, 70);
m_brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, wxSize(FromDIP(70), FromDIP(70)));
m_brand = new wxStaticBitmap(this, wxID_ANY, sm, wxDefaultPosition, wxSize(FromDIP(70), FromDIP(70)));
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
m_text_up_info = new Label(this, Label::Head_14, wxEmptyString, LB_AUTO_WRAP);
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
@@ -424,7 +410,6 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent)
UpdateVersionDialog::~UpdateVersionDialog() {}
wxWebView* UpdateVersionDialog::CreateTipView(wxWindow* parent)
{
wxWebView* tipView = WebView::CreateWebView(parent, "");

View File

@@ -1905,7 +1905,7 @@ void SSWCP_MachineFind_Instance::sw_StopMachineFind()
void SSWCP_MachineFind_Instance::add_machine_to_list(const json& machine_info)
{
try {
BOOST_LOG_TRIVIAL(info) << "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT" << machine_info.dump();
BOOST_LOG_TRIVIAL(info) << "check the machine list on json: " << machine_info.dump();
for (const auto& [key, value] : machine_info.items()) {
std::string sn = value["sn"].get<std::string>();
bool need_send = false;
@@ -1928,7 +1928,7 @@ void SSWCP_MachineFind_Instance::add_machine_to_list(const json& machine_info)
m_res_data[key]["connected"] = true;
}
std::string ip = value["ip"].get<std::string>();
if (info.ip != ip && info.link_mode != "wan") {
if (0) {
info.ip = ip;
wxGetApp().app_config->save_device_info(info);

View File

@@ -92,8 +92,6 @@ bool MsgUpdateSlic3r::disable_version_check() const
return true;
}
// MsgUpdateConfig
MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_before_wizard /* = false*/)
: DPIDialog(wxGetApp().mainframe, wxID_ANY, _L("Configuration update"), wxDefaultPosition, wxDefaultSize, wxCAPTION)
{
@@ -123,7 +121,6 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
auto m_text_up_info = new wxStaticText(this, wxID_ANY, _L("A new configuration package is available. Do you want to install it?"), wxDefaultPosition, wxDefaultSize, 0);
m_text_up_info->SetFont(::Label::Head_14);
m_text_up_info->SetForegroundColour(wxColour(0x26, 0x2E, 0x30));
@@ -179,17 +176,12 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
wxBoxSizer *content_sizer = new wxBoxSizer(wxVERTICAL);
const auto lang_code = wxGetApp().current_language_code_safe().ToStdString();
auto *versions = new wxBoxSizer(wxVERTICAL);
// BBS: use changelog string instead of url
wxStaticText *changelog_textctrl = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(560), -1));
for (const auto &update : updates) {
auto* versions = new wxBoxSizer(wxVERTICAL);
wxStaticText* changelog_textctrl = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, wxEmptyString, wxDefaultPosition,
@@ -214,12 +206,8 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
versions->Add(flex);
// BBS: use changelog string instead of url
//auto change_log = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, from_u8(update.change_log), wxDefaultPosition, wxDefaultSize);
changelog_textctrl->SetLabel(changelog_textctrl->GetLabel() + wxString::Format("%s\n", from_u8(update.change_log)));
//auto change_log = new wxStaticText(m_scrollwindw_release_note, wxID_ANY, from_u8(update.change_log), wxDefaultPosition, wxDefaultSize);
changelog_textctrl->SetLabel(changelog_textctrl->GetLabel() + wxString::Format("%s\n", from_u8(update.change_log)));
content_sizer->Add(versions);
@@ -227,16 +215,13 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
if (changelog_textctrl)
content_sizer->Add(changelog_textctrl, 1, wxEXPAND | wxTOP, FromDIP(30));
}
m_butto_ok->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { EndModal(wxID_OK); });
m_button_cancel->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { EndModal(wxID_CLOSE); });
m_scrollwindw_release_note->SetSizer(content_sizer);
m_scrollwindw_release_note->Layout();
SetSizer(m_sizer_main);
Layout();
m_sizer_main->Fit(this);

View File

@@ -61,10 +61,6 @@ public:
// force_before_wizard - indicates that check of updated is forced before ConfigWizard opening
MsgUpdateConfig(const std::vector<Update> &updates, bool force_before_wizard = false);
void on_dpi_changed(const wxRect &suggested_rect);
// MsgUpdateConfig(MsgUpdateConfig &&) = delete;
//MsgUpdateConfig(const MsgUpdateConfig &) = delete;
//MsgUpdateConfig &operator=(MsgUpdateConfig &&) = delete;
//MsgUpdateConfig &operator=(const MsgUpdateConfig &) = delete;
~MsgUpdateConfig();
};

View File

@@ -91,7 +91,7 @@ SMUserLogin::SMUserLogin(bool isLogout) : wxDialog((wxWindow *) (wxGetApp().main
Bind(wxEVT_WEBVIEW_NEWWINDOW, &SMUserLogin::OnNewWindow, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &SMUserLogin::OnTitleChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &SMUserLogin::OnFullScreenChanged, this, m_browser->GetId());
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &SMUserLogin::OnScriptMessage, this, m_browser->GetId());
//Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &SMUserLogin::OnScriptMessage, this, m_browser->GetId());
// Connect the idle events
// Bind(wxEVT_IDLE, &SMUserLogin::OnIdle, this);
@@ -305,7 +305,6 @@ void SMUserLogin::OnScriptMessage(wxWebViewEvent &evt)
}
if (strCmd == "user_login") {
j["data"]["autotest_token"] = m_AutotestToken;
wxGetApp().handle_script_message(j.dump());
Close();
}
else if (strCmd == "get_localhost_url") {

View File

@@ -279,7 +279,6 @@ void ZUserLogin::OnScriptMessage(wxWebViewEvent &evt)
}
if (strCmd == "user_login") {
j["data"]["autotest_token"] = m_AutotestToken;
wxGetApp().handle_script_message(j.dump());
Close();
}
else if (strCmd == "get_localhost_url") {

View File

@@ -181,7 +181,9 @@ struct Updates
std::vector<Update> updates;
};
wxDEFINE_EVENT(EVT_REQUEST_SERVER_FAIL, wxCommandEvent);
wxDEFINE_EVENT(EVT_NO_WEB_RESOURCE_UPDATE, wxCommandEvent);
wxDEFINE_EVENT(EVT_NO_PRESET_UPDATE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);
@@ -201,6 +203,8 @@ struct PresetUpdater::priv
bool cancel;
std::thread thread;
bool m_web_thread_cancel;
std::thread m_web_resource_thread;
bool has_waiting_updates { false };
Updates waiting_updates;
bool has_waiting_printer_updates { false };
@@ -226,7 +230,9 @@ struct PresetUpdater::priv
void sync_version() const;
void parse_version_string(const std::string& body) const;
void sync_resources(std::string http_url, std::map<std::string, Resource> &resources, bool check_patch = false, std::string current_version="", std::string changelog_file="");
void sync_config();
void sync_config(bool isAuto_check = true);
void sync_update_flutter_resource(bool isAuto_check = true);
bool download_file(const std::string& url, const std::string& target_path, int timeout_sec = 30, bool* cancel_flag = nullptr);
void sync_tooltip(std::string http_url, std::string language);
void sync_plugins(std::string http_url, std::string plugin_version);
void sync_printer_config(std::string http_url);
@@ -263,7 +269,7 @@ void PresetUpdater::priv::set_download_prefs(AppConfig *app_config)
{
version_check_url = app_config->version_check_url();
auto profile_update_url = app_config->profile_update_url();
auto profile_update_url = app_config->get_preset_upgrade_url();
if (!profile_update_url.empty())
enabled_config_update = true;
else
@@ -649,123 +655,271 @@ void PresetUpdater::priv::sync_resources(std::string http_url, std::map<std::str
}
}
}
// Orca: sync config update for currect App version
void PresetUpdater::priv::sync_config()
bool PresetUpdater::priv::download_file(const std::string& url,
const std::string& target_path,
int timeout_sec,
bool* cancel_flag )
{
auto cache_profile_path = cache_path;
auto cache_profile_update_file = cache_path / "profiles_update.json";
std::string asset_name;
if (fs::exists(cache_profile_update_file)) {
try {
boost::nowide::ifstream f(cache_profile_update_file.string());
json data = json::parse(f);
if (data.contains("name"))
asset_name = data["name"].get<std::string>();
f.close();
} catch (const std::exception& ex) {
BOOST_LOG_TRIVIAL(error) << "[Orca Updater]: failed to read profiles_update.json when sync_config: " << ex.what() << std::endl;
} catch (...) {
// catch any other errors (that we have no information about)
BOOST_LOG_TRIVIAL(error) << "[Orca Updater]: unknown failure when reading profiles_update.json in sync_config" << std::endl;
}
}
AppConfig *app_config = GUI::wxGetApp().app_config;
bool res = false;
// auto profile_update_url = app_config->profile_update_url() + "/" + Snapmaker_VERSION;
auto profile_update_url = app_config->profile_update_url();
// parse the assets section and get the latest asset by comparing the name
fs::path tmp_path = target_path + ".tmp";
Http::get(profile_update_url)
.on_error([cache_profile_path, cache_profile_update_file](std::string body, std::string error, unsigned http_status) {
// Orca: we check the response body to see if it's "Not Found", if so, it means for the current Orca version we don't have OTA
// updates, we can delete the cache file
if (!body.empty()) {
try {
json j = json::parse(body);
if (j.contains("message") && j["message"].get<std::string>() == "Not Found") {
// The current Orca version does not have any OTA updates, delete the cache file
if (fs::exists(cache_profile_path / "profiles"))
fs::remove_all(cache_profile_path / "profiles");
if (fs::exists(cache_profile_update_file))
fs::remove(cache_profile_update_file);
}
} catch (...) {}
BOOST_LOG_TRIVIAL(info) << "Downloading file from: " << url << " to: " << target_path;
Slic3r::Http::get(url)
.on_progress([cancel_flag](Slic3r::Http::Progress progress, bool& cancel_http) {
// BOOST_LOG_TRIVIAL(debug) << "Download progress: " << progress.dlnow << "/" << progress.dltotal;
if (cancel_flag && *cancel_flag) {
cancel_http = true;
}
BOOST_LOG_TRIVIAL(info) << format("Error getting: `%1%`: HTTP %2%, %3%", "sync_config_orca", http_status, error);
})
.timeout_connect(5)
.on_complete([this, asset_name, cache_profile_path, cache_profile_update_file](std::string body, unsigned http_status) {
.on_error([&url](std::string body, std::string error, unsigned http_status) {
BOOST_LOG_TRIVIAL(error) << "Download failed: " << url << ", HTTP status: " << http_status << ", error: " << error;
})
.on_complete([&](std::string body, unsigned http_status) {
if (http_status != 200) {
BOOST_LOG_TRIVIAL(error) << "Download failed with HTTP status: " << http_status;
return;
}
fs::path target(target_path);
if (!fs::exists(target.parent_path())) {
fs::create_directories(target.parent_path());
}
fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
if (!file.is_open()) {
BOOST_LOG_TRIVIAL(error) << "Failed to open file for writing: " << tmp_path;
return;
}
file.write(body.c_str(), body.size());
file.close();
boost::system::error_code ec;
fs::rename(tmp_path, target_path, ec);
if (ec) {
BOOST_LOG_TRIVIAL(error) << "Failed to rename temp file: " << ec.message();
return;
}
extract_file(target_path, "../ota/profiles/");
BOOST_LOG_TRIVIAL(info) << "Download completed: " << target_path;
res = true;
})
.timeout_max(timeout_sec)
.perform_sync();
if (fs::exists(tmp_path)) {
fs::remove(tmp_path);
}
return res;
}
void PresetUpdater::priv::sync_update_flutter_resource(bool isAuto_check)
{
auto cache_profile_path = cache_path;
AppConfig* app_config = GUI::wxGetApp().app_config;
auto preset_update_url = app_config->get_web_resource_upgrade_url();
Http::get(preset_update_url)
.on_error([cache_profile_path, isAuto_check](std::string body, std::string error, unsigned http_status) {
wxCommandEvent* evt = new wxCommandEvent(EVT_REQUEST_SERVER_FAIL);
wxString errorMsg = wxString::Format(_L("request to server update web resource fail with body:%s,error:%s,status:%d"), body, error, http_status);
evt->SetString(errorMsg);
if (!isAuto_check)
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("Error getting: `%1%`: HTTP %2%, %3%", "sync_update_flutter_resource", http_status, error);
})
.timeout_connect(TIMEOUT_CONNECT)
.on_complete([this, cache_profile_path, isAuto_check](std::string body, unsigned http_status) {
// Http response OK
if (http_status != 200)
return;
try {
json j = json::parse(body);
struct update
{
std::string url;
std::string name;
int ver = -9999;
} latest_update;
if (!(j.contains("message") && j["message"].get<std::string>() == "Not Found")) {
json assets = j.at("assets");
if (assets.is_array()) {
for (auto asset : assets) {
std::string name = asset["name"].get<std::string>();
int versionNumber = -1;
std::regex regexPattern("Snapmaker_Orca-profiles_ota_.*\\.([0-9]+)\\.zip$");
std::smatch matches;
if (std::regex_search(name, matches, regexPattern) && matches.size() > 1) {
versionNumber = std::stoi(matches[1].str());
}
if (versionNumber > 0 && versionNumber > latest_update.ver) {
latest_update.url = asset["browser_download_url"].get<std::string>();
latest_update.name = name;
latest_update.ver = versionNumber;
}
}
}
}
if (cancel)
json jsonObj = json::parse(body);
auto errCode = jsonObj["code"];
if (errCode != 200)
return;
if (latest_update.ver > 0) {
if (latest_update.name == asset_name)
return;
if (fs::exists(cache_profile_path / "profiles"))
fs::remove_all(cache_profile_path / "profiles");
fs::create_directories(cache_profile_path / "profiles");
// download the file
std::string download_url = latest_update.url;
std::string download_file = (cache_path / (latest_update.name + TMP_EXTENSION)).string();
if (!get_file(download_url, download_file)) {
return;
}
auto dataObj = jsonObj.value("data", json::object());
auto buildNumer = dataObj.value("build_number", "");
auto minSupportPcVersion = dataObj.value("min_support_pc_version", "");
auto maxSupportPcVersion = dataObj.value("max_support_pc_version", "");
// extract the file downloaded
BOOST_LOG_TRIVIAL(info) << "[Orca Updater]start to unzip the downloaded file " << download_file;
if (!extract_file(download_file, cache_profile_path)) {
BOOST_LOG_TRIVIAL(warning) << "[Orca Updater]extract downloaded file"
<< " failed, path: " << download_file;
return;
auto isForceUpgrade = dataObj.value("is_force_upgrade", false);
auto fileVersion = dataObj.value("file_version", "");
auto fileSize = dataObj.value("file_size", 0);
auto fileMd5 = dataObj.value("file_md5", "");
auto fileSha256 = dataObj.value("file_sha256", "");
auto fileUrl = dataObj.value("file_url", "");
auto description = dataObj.value("file_describe", "");
auto reservedData = dataObj.value("reserved_1", "");
auto reservedData2 = dataObj.value("reserved_2", "");
auto localProfilesjson = cache_path / "flutter_web/version.json";
std::string json_path = data_dir() + "/web/flutter_web/version.json";
std::string fileName = cache_profile_path.string() + "/flutter_web.zip";
Semver currentPresetVersion = get_version_from_json(json_path);
Semver remoteVersion(fileVersion);
Semver minSpVersion(minSupportPcVersion);
Semver maxSpVersion(maxSupportPcVersion);
std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9]+)?(\\+[A-Za-z0-9]+)?");
auto get_version = [this](const std::string& str, const std::regex& regexp)
{
std::smatch match;
if (std::regex_match(str, match, regexp)) {
std::string version_cleaned = match[0];
const boost::optional<Semver> version = Semver::parse(version_cleaned);
if (version.has_value()) {
return *version;
}
}
BOOST_LOG_TRIVIAL(info) << "[Orca Updater]finished unzip the downloaded file " << download_file;
boost::nowide::ofstream f(cache_profile_update_file.string());
json data;
data["name"] = latest_update.name;
f << data << std::endl;
f.close();
} else {
// The current Orca version does not have any OTA updates, delete the cache file
if (fs::exists(cache_profile_path / "profiles"))
fs::remove_all(cache_profile_path / "profiles");
if (fs::exists(cache_profile_update_file))
fs::remove(cache_profile_update_file);
return Semver::invalid();
};
Semver currentSoftVersion = get_version(Snapmaker_VERSION, matcher);
if (fileVersion.empty())
{
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_WEB_RESOURCE_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the web update.");
}
return;
}
if (currentSoftVersion > maxSpVersion || currentSoftVersion < minSpVersion) {
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_PRESET_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the web update.");
}
return;
}
if (currentPresetVersion < remoteVersion)
download_file(fileUrl, fileName);
else {
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_WEB_RESOURCE_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the web update local no profiles.");
}
}
} catch (...) {}
})
.perform_sync();
}
// Orca: sync config update for currect App version
void PresetUpdater::priv::sync_config(bool isAuto_check)
{
auto cache_profile_path = cache_path;
AppConfig *app_config = GUI::wxGetApp().app_config;
auto profile_update_url = app_config->get_preset_upgrade_url();
// parse the assets section and get the latest asset by comparing the name
Http::get(profile_update_url)
.on_error([cache_profile_path, isAuto_check](std::string body, std::string error, unsigned http_status) {
// Orca: we check the response body to see if it's "Not Found", if so, it means for the current Orca version we don't have OTA
// updates, we can delete the cache file
wxCommandEvent* evt = new wxCommandEvent(EVT_REQUEST_SERVER_FAIL);
wxString errorMsg = wxString::Format(_L("request to server update preset resource fail with body:%s,error:%s,status:%d"), body,error, http_status);
evt->SetString(errorMsg);
if (!isAuto_check)
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("Error getting: `%1%`: HTTP %2%, %3%", "sync_config_orca", http_status, error);
})
.timeout_connect(TIMEOUT_CONNECT)
.on_complete([this, cache_profile_path, isAuto_check](std::string body, unsigned http_status) {
// Http response OK
if (http_status != 200)
return;
try {
json jsonObj = json::parse(body);
auto errCode = jsonObj["code"];
if (errCode != 200)
return;
auto dataObj = jsonObj.value("data", json::object());
auto isForceUpgrade = dataObj.value("is_force_upgrade", false);
auto minSupportPcVersion = dataObj.value("min_support_pc_version", "");
auto maxSupportPcVersion = dataObj.value("max_support_pc_version", "");
auto fileVersion = dataObj.value("file_version", "");
auto fileSize = dataObj.value("file_size", 0);
auto fileMd5 = dataObj.value("file_md5", "");
auto fileSha256 = dataObj.value("file_sha256", "");
auto fileUrl = dataObj.value("file_url", "");
auto description = dataObj.value("file_describe", "");
auto reservedData = dataObj.value("reserved_1", "");
auto reservedData2 = dataObj.value("reserved_2", "");
auto localProfilesjson = cache_path / "profiles/Snapmaker.json";
std::string json_path = data_dir() + "/system/Snapmaker.json";
std::string fileName = cache_profile_path.string() + "/profiles.zip";
Semver currentPresetVersion = get_version_from_json(json_path);
Semver remoteVersion(fileVersion);
Semver minSpVersion(minSupportPcVersion);
Semver maxSpVersion(maxSupportPcVersion);
std::regex matcher("[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[A-Za-z0-9]+)?(\\+[A-Za-z0-9]+)?");
auto get_version = [this](const std::string& str, const std::regex& regexp) {
std::smatch match;
if (std::regex_match(str, match, regexp)) {
std::string version_cleaned = match[0];
const boost::optional<Semver> version = Semver::parse(version_cleaned);
if (version.has_value()) {
return *version;
}
}
return Semver::invalid();
};
Semver currentSoftVersion = get_version(Snapmaker_VERSION, matcher);
if (fileVersion.empty()) {
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_PRESET_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the web update.");
}
return;
}
if (currentSoftVersion > maxSpVersion || currentSoftVersion < minSpVersion)
{
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_PRESET_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the web update.");
}
return;
}
if (currentPresetVersion < remoteVersion)
download_file(fileUrl, fileName);
else {
if (!isAuto_check) {
wxCommandEvent* evt = new wxCommandEvent(EVT_NO_PRESET_UPDATE);
GUI::wxGetApp().QueueEvent(evt);
BOOST_LOG_TRIVIAL(info) << format("use check the preset update local no profiles.");
}
}
} catch (...) {}
})
.perform_sync();
@@ -1384,6 +1538,12 @@ PresetUpdater::~PresetUpdater()
p->cancel = true;
p->thread.join();
}
if (p && p->m_web_resource_thread.joinable())
{
p->m_web_thread_cancel = true;
p->m_web_resource_thread.join();
}
}
//BBS: change directories by design
@@ -1543,6 +1703,45 @@ bool PresetUpdater::install_bundles_rsrc(std::vector<std::string> bundles, bool
return p->install_bundles_rsrc(bundles, snapshot);
}
void PresetUpdater::sync_web_async(bool isAutoUpdata)
{
if (p->m_web_resource_thread.joinable()) {
p->m_web_thread_cancel = true;
p->m_web_resource_thread.join();
}
p->m_web_thread_cancel = false;
p->m_web_resource_thread = std::thread([this, isAutoUpdata]() {
BOOST_LOG_TRIVIAL(debug) << "[Orca Updater] sync_web_async started";
this->p->sync_update_flutter_resource(isAutoUpdata);
GUI::wxGetApp().CallAfter([this] {
std::string zipfilepath = this->p->cache_path.string() + "/flutter_web.zip";
BOOST_LOG_TRIVIAL(debug) << "[Orca Updater] sync_web_async completed, checking updates...";
load_lutter_web(zipfilepath, true);
});
});
}
void PresetUpdater::sync_config_async()
{
if (p->thread.joinable()) {
p->cancel = true;
p->thread.join();
}
p->cancel = false;
p->thread = std::thread([this]() {
BOOST_LOG_TRIVIAL(debug) << "[Orca Updater] sync_config_async started";
this->p->sync_config(false);
GUI::wxGetApp().CallAfter([] {
BOOST_LOG_TRIVIAL(debug) << "[Orca Updater] sync_config_async completed, checking updates...";
GUI::wxGetApp().check_config_updates_from_updater(true);
});
});
}
void PresetUpdater::on_update_notification_confirm()
{
if (!p->has_waiting_updates)
@@ -1602,31 +1801,21 @@ bool PresetUpdater::version_check_enabled() const
return p->enabled_version_check;
}
void PresetUpdater::import_flutter_web()
void PresetUpdater::load_lutter_web(const std::string& zip_file, bool serverUpdate)
{
// 1. 弹出文件选择框
wxFileDialog dialog(nullptr, _L("Please choose a web resource package file:"), "", "", "resource packages (*.zip)|*.zip",
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() != wxID_OK)
return;
std::string zip_file = dialog.GetPath().ToUTF8().data();
// 2. 创建临时目录用于解压
boost::filesystem::path temp_path = boost::filesystem::temp_directory_path() / "orca_temp_flutter_import";
try {
if (boost::filesystem::exists(temp_path))
boost::filesystem::remove_all(temp_path);
boost::filesystem::create_directories(temp_path);
// 3. 解压zip文件到临时目录
if (!p->extract_file(zip_file, temp_path.string())) {
GUI::MessageDialog(nullptr, _L("Import Failed")).ShowModal();
if (!serverUpdate)
GUI::MessageDialog(nullptr, _L("Import Failed")).ShowModal();
return;
}
// 4. 检查版本并导入
std::vector<std::string> outdated_presets;
Updates updates;
@@ -1635,40 +1824,33 @@ void PresetUpdater::import_flutter_web()
GUI::MessageDialog(nullptr, _L("Import Failed")).ShowModal();
}
// 读取当前flutter资源包版本
std::string ori_version_str = "0";
std::string ori_version_str = "0";
std::string ori_build_number_str = "0";
auto ori_version_file = boost::filesystem::path(data_dir()) / "web" / "flutter_web" / "version.json";
auto ori_version_file = boost::filesystem::path(data_dir()) / "web" / "flutter_web" / "version.json";
boost::property_tree::ptree ori_config;
boost::property_tree::read_json(ori_version_file.string(), ori_config);
ori_version_str = ori_config.get<std::string>("version", "0");
ori_build_number_str = ori_config.get<std::string>("build_number", "0");
// 遍历解压的文件夹
for (auto& dir_entry : boost::filesystem::directory_iterator(temp_path / "flutter_web")) {
if (dir_entry.path().filename() == "version.json") {
try {
// 读取json文件获取版本信息
boost::property_tree::ptree config;
boost::property_tree::read_json(dir_entry.path().string(), config);
std::string version_str = config.get<std::string>("version", "0");
std::string version_str = config.get<std::string>("version", "0");
std::string build_number_str = config.get<std::string>("build_number", "0");
// std::string vendor = dir_entry.path().stem().string();
// 使用 Semver 进行版本比较
Semver online_version = version_str;
Semver current_version = ori_version_str;
if (/* current_version < online_version && */ori_build_number_str < build_number_str) {
if (/* current_version < online_version && */ ori_build_number_str < build_number_str) {
auto source_folder_path = fs::path(dir_entry.path().parent_path());
auto target_folder_path = (boost::filesystem::path(data_dir()) / "web" / "flutter_web");
// 创建Version对象
Version version;
version.config_version = online_version; // 将Semver赋值给Version的config_version
version.config_version = online_version;
// changelog
std::string changelog = "";
@@ -1679,16 +1861,14 @@ void PresetUpdater::import_flutter_web()
oss << ifs.rdbuf();
changelog = oss.str();
ifs.close();
// 替换所有的 \\n 为 \n
size_t pos = 0;
while ((pos = changelog.find("\\n", pos)) != std::string::npos) {
changelog.replace(pos, 2, "\n");
pos += 1; // 移动到下一个可能的位置
pos += 1;
}
}
// 检查最小要求软件版本
Semver min_ver = get_min_version_from_json(dir_entry.path().string());
Semver min_ver = get_min_version_from_json(dir_entry.path().string());
Semver soft_ver = Semver(std::string(Snapmaker_VERSION));
bool legal = true;
@@ -1699,13 +1879,10 @@ void PresetUpdater::import_flutter_web()
.ToStdString();
}
// 版本较新且兼容,添加到更新列表
updates.updates.emplace_back(std::move(source_folder_path), std::move(target_folder_path), version, "flutter_web", changelog, "",
false, true, legal);
updates.updates.emplace_back(std::move(source_folder_path), std::move(target_folder_path), version, "flutter_web",
changelog, "", false, true, legal);
} else {
// 版本较旧或不兼容,添加到提示列表
outdated_presets.push_back("flutter_web");
}
} catch (std::exception& e) {
@@ -1715,7 +1892,6 @@ void PresetUpdater::import_flutter_web()
}
}
// 5. 执行更新并提示结果
bool need_restart = false;
if (!updates.updates.empty()) {
std::vector<GUI::MsgUpdateConfig::Update> updates_msg;
@@ -1744,7 +1920,7 @@ void PresetUpdater::import_flutter_web()
}
wxString message;
if (!outdated_presets.empty()) {
if (!outdated_presets.empty() && !serverUpdate) {
message = _L("This web resouce could not be imported due to outdated versions.") + "\n";
for (const auto& preset : outdated_presets) {
message += "" + preset + "\n";
@@ -1752,8 +1928,6 @@ void PresetUpdater::import_flutter_web()
GUI::MessageDialog(nullptr, message).ShowModal();
}
if (need_restart) {
GUI::MessageDialog msg_wingow(nullptr,
_L("Updating the web resources requires application restart.") + "\n" +
@@ -1765,17 +1939,29 @@ void PresetUpdater::import_flutter_web()
app->recreate_GUI(_L("Update web resources"));
}
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "Failed to importweb resources: " << e.what();
GUI::MessageDialog(nullptr, _L("Import Failed")).ShowModal();
}
// 6. 清理临时目录
boost::filesystem::remove_all(temp_path);
}
void PresetUpdater::import_flutter_web()
{
wxFileDialog dialog(nullptr, _L("Please choose a web resource package file:"), "", "", "resource packages (*.zip)|*.zip",
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (dialog.ShowModal() != wxID_OK)
return;
std::string zip_file = dialog.GetPath().ToUTF8().data();
load_lutter_web(zip_file);
}
void PresetUpdater::import_system_profile()
{
// 1. 弹出文件选择框
@@ -1810,7 +1996,7 @@ void PresetUpdater::import_system_profile()
}
// 遍历解压的文件夹
for (auto& dir_entry : boost::filesystem::directory_iterator(temp_path / "profiles")) {
for (auto& dir_entry : boost::filesystem::directory_iterator(temp_path)) {
if (dir_entry.path().extension() == ".json") {
try {
// 读取json文件获取版本信息

View File

@@ -65,11 +65,18 @@ public:
void import_flutter_web();
void load_lutter_web(const std::string& zip_file,bool serverUpdate = false);
void sync_config_async();
void sync_web_async(bool isAutoUpdata = false);
public:
struct priv;
std::unique_ptr<priv> p;
};
wxDECLARE_EVENT(EVT_REQUEST_SERVER_FAIL, wxCommandEvent);
wxDECLARE_EVENT(EVT_NO_WEB_RESOURCE_UPDATE, wxCommandEvent);
wxDECLARE_EVENT(EVT_NO_PRESET_UPDATE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
wxDECLARE_EVENT(EVT_SLIC3R_EXPERIMENTAL_VERSION_ONLINE, wxCommandEvent);