mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 00:52:04 +00:00
Implement support for loading custom plugin binaries
This commit is contained in:
@@ -3225,7 +3225,8 @@ __retry:
|
||||
std::string loaded_version = Slic3r::NetworkAgent::get_version();
|
||||
if (app_config && !loaded_version.empty() && loaded_version != "00.00.00.00") {
|
||||
std::string config_version = app_config->get_network_plugin_version();
|
||||
if (config_version != loaded_version) {
|
||||
std::string config_base = BBL::extract_base_version(config_version);
|
||||
if (config_base != loaded_version) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": syncing config version from " << config_version << " to loaded " << loaded_version;
|
||||
app_config->set(SETTING_NETWORK_PLUGIN_VERSION, loaded_version);
|
||||
app_config->save();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "Tab.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/button.h>
|
||||
@@ -525,10 +527,22 @@ void MonitorPanel::jump_to_LiveView()
|
||||
|
||||
void MonitorPanel::update_network_version_footer()
|
||||
{
|
||||
std::string network_ver = Slic3r::NetworkAgent::get_version();
|
||||
if (!network_ver.empty()) {
|
||||
m_tabpanel->SetFooterText(wxString::Format("Network plugin v%s", network_ver));
|
||||
std::string binary_version = Slic3r::NetworkAgent::get_version();
|
||||
if (binary_version.empty())
|
||||
return;
|
||||
|
||||
std::string configured_version = wxGetApp().app_config->get_network_plugin_version();
|
||||
std::string suffix = BBL::extract_suffix(configured_version);
|
||||
std::string configured_base = BBL::extract_base_version(configured_version);
|
||||
|
||||
wxString footer_text;
|
||||
if (!suffix.empty() && configured_base == binary_version) {
|
||||
footer_text = wxString::Format("Network plugin v%s (%s)", binary_version, suffix);
|
||||
} else {
|
||||
footer_text = wxString::Format("Network plugin v%s", binary_version);
|
||||
}
|
||||
|
||||
m_tabpanel->SetFooterText(footer_text);
|
||||
}
|
||||
|
||||
} // GUI
|
||||
|
||||
@@ -211,12 +211,18 @@ void NetworkPluginDownloadDialog::setup_version_selector()
|
||||
wxDefaultPosition, wxSize(FromDIP(380), FromDIP(28)), 0, nullptr, wxCB_READONLY);
|
||||
m_version_combo->SetFont(::Label::Body_13);
|
||||
|
||||
for (size_t i = 0; i < BBL::AVAILABLE_NETWORK_VERSIONS_COUNT; ++i) {
|
||||
const auto& ver = BBL::AVAILABLE_NETWORK_VERSIONS[i];
|
||||
wxString label = wxString::FromUTF8(ver.display_name);
|
||||
m_available_versions = BBL::get_all_available_versions();
|
||||
for (size_t i = 0; i < m_available_versions.size(); ++i) {
|
||||
const auto& ver = m_available_versions[i];
|
||||
wxString label;
|
||||
if (!ver.suffix.empty()) {
|
||||
label = wxString::FromUTF8("\xE2\x94\x94 ") + wxString::FromUTF8(ver.display_name);
|
||||
} else {
|
||||
label = wxString::FromUTF8(ver.display_name);
|
||||
if (ver.is_latest) {
|
||||
label += wxString(" ") + _L("(Latest)");
|
||||
}
|
||||
}
|
||||
m_version_combo->Append(label);
|
||||
}
|
||||
|
||||
@@ -230,19 +236,19 @@ std::string NetworkPluginDownloadDialog::get_selected_version() const
|
||||
}
|
||||
|
||||
int selection = m_version_combo->GetSelection();
|
||||
if (selection < 0 || selection >= static_cast<int>(BBL::AVAILABLE_NETWORK_VERSIONS_COUNT)) {
|
||||
if (selection < 0 || selection >= static_cast<int>(m_available_versions.size())) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return BBL::AVAILABLE_NETWORK_VERSIONS[selection].version;
|
||||
return m_available_versions[selection].version;
|
||||
}
|
||||
|
||||
void NetworkPluginDownloadDialog::on_download(wxCommandEvent& evt)
|
||||
{
|
||||
int selection = m_version_combo ? m_version_combo->GetSelection() : 0;
|
||||
if (selection >= 0 && selection < static_cast<int>(BBL::AVAILABLE_NETWORK_VERSIONS_COUNT)) {
|
||||
const char* warning = BBL::AVAILABLE_NETWORK_VERSIONS[selection].warning;
|
||||
if (warning) {
|
||||
if (selection >= 0 && selection < static_cast<int>(m_available_versions.size())) {
|
||||
const std::string& warning = m_available_versions[selection].warning;
|
||||
if (!warning.empty()) {
|
||||
MessageDialog warn_dlg(this, wxString::FromUTF8(warning), _L("Warning"), wxOK | wxCANCEL | wxICON_WARNING);
|
||||
if (warn_dlg.ShowModal() != wxID_OK) {
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "MsgDialog.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
#include <wx/collpane.h>
|
||||
|
||||
namespace Slic3r {
|
||||
@@ -52,6 +53,7 @@ private:
|
||||
wxCollapsiblePane* m_details_pane{nullptr};
|
||||
std::string m_error_message;
|
||||
std::string m_error_details;
|
||||
std::vector<BBL::NetworkLibraryVersionInfo> m_available_versions;
|
||||
};
|
||||
|
||||
class NetworkPluginRestartDialog : public DPIDialog
|
||||
|
||||
@@ -1371,13 +1371,23 @@ void PreferencesDialog::create_items()
|
||||
std::string current_version = app_config->get("network_plugin_version");
|
||||
int current_selection = 0;
|
||||
|
||||
for (size_t i = 0; i < BBL::AVAILABLE_NETWORK_VERSIONS_COUNT; i++) {
|
||||
wxString label = wxString::FromUTF8(BBL::AVAILABLE_NETWORK_VERSIONS[i].display_name);
|
||||
if (BBL::AVAILABLE_NETWORK_VERSIONS[i].is_latest) {
|
||||
m_available_versions = BBL::get_all_available_versions();
|
||||
|
||||
for (size_t i = 0; i < m_available_versions.size(); i++) {
|
||||
const auto& ver = m_available_versions[i];
|
||||
wxString label;
|
||||
|
||||
if (!ver.suffix.empty()) {
|
||||
label = wxString::FromUTF8("\xE2\x94\x94 ") + wxString::FromUTF8(ver.display_name);
|
||||
} else {
|
||||
label = wxString::FromUTF8(ver.display_name);
|
||||
}
|
||||
|
||||
if (ver.is_latest) {
|
||||
label += " " + _L("(Latest)");
|
||||
}
|
||||
m_network_version_combo->Append(label);
|
||||
if (current_version == BBL::AVAILABLE_NETWORK_VERSIONS[i].version) {
|
||||
if (current_version == ver.version) {
|
||||
current_selection = i;
|
||||
}
|
||||
}
|
||||
@@ -1387,8 +1397,9 @@ void PreferencesDialog::create_items()
|
||||
|
||||
m_network_version_combo->GetDropDown().Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& e) {
|
||||
int selection = e.GetSelection();
|
||||
if (selection >= 0 && selection < (int)BBL::AVAILABLE_NETWORK_VERSIONS_COUNT) {
|
||||
std::string new_version = BBL::AVAILABLE_NETWORK_VERSIONS[selection].version;
|
||||
if (selection >= 0 && selection < (int)m_available_versions.size()) {
|
||||
const auto& selected_ver = m_available_versions[selection];
|
||||
std::string new_version = selected_ver.version;
|
||||
std::string old_version = app_config->get_network_plugin_version();
|
||||
if (old_version.empty()) {
|
||||
old_version = BBL::get_latest_network_version();
|
||||
@@ -1400,9 +1411,8 @@ void PreferencesDialog::create_items()
|
||||
if (new_version != old_version) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Network plugin version changed from " << old_version << " to " << new_version;
|
||||
|
||||
const char* warning = BBL::AVAILABLE_NETWORK_VERSIONS[selection].warning;
|
||||
if (warning) {
|
||||
MessageDialog warn_dlg(this, wxString::FromUTF8(warning), _L("Warning"), wxOK | wxCANCEL | wxICON_WARNING);
|
||||
if (!selected_ver.warning.empty()) {
|
||||
MessageDialog warn_dlg(this, wxString::FromUTF8(selected_ver.warning), _L("Warning"), wxOK | wxCANCEL | wxICON_WARNING);
|
||||
if (warn_dlg.ShowModal() != wxID_OK) {
|
||||
app_config->set(SETTING_NETWORK_PLUGIN_VERSION, old_version);
|
||||
app_config->save();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Widgets/CheckBox.hpp"
|
||||
#include "Widgets/TextInput.hpp"
|
||||
#include "Widgets/TabCtrl.hpp"
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -70,6 +71,7 @@ public:
|
||||
::CheckBox * m_legacy_networking_ckeckbox = {nullptr};
|
||||
::ComboBox * m_network_version_combo = {nullptr};
|
||||
wxBoxSizer * m_network_version_sizer = {nullptr};
|
||||
std::vector<BBL::NetworkLibraryVersionInfo> m_available_versions;
|
||||
|
||||
wxString m_developer_mode_def;
|
||||
wxString m_internal_developer_mode_def;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#else
|
||||
@@ -282,6 +284,52 @@ void NetworkAgent::remove_legacy_library()
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> NetworkAgent::scan_plugin_versions()
|
||||
{
|
||||
std::vector<std::string> discovered_versions;
|
||||
std::string data_dir_str = data_dir();
|
||||
boost::filesystem::path plugin_folder = boost::filesystem::path(data_dir_str) / "plugins";
|
||||
|
||||
if (!boost::filesystem::is_directory(plugin_folder)) {
|
||||
return discovered_versions;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
std::string prefix = std::string(BAMBU_NETWORK_LIBRARY) + "_";
|
||||
std::string extension = ".dll";
|
||||
#elif defined(__WXMAC__)
|
||||
std::string prefix = std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_";
|
||||
std::string extension = ".dylib";
|
||||
#else
|
||||
std::string prefix = std::string("lib") + std::string(BAMBU_NETWORK_LIBRARY) + "_";
|
||||
std::string extension = ".so";
|
||||
#endif
|
||||
|
||||
boost::system::error_code ec;
|
||||
for (auto& entry : boost::filesystem::directory_iterator(plugin_folder, ec)) {
|
||||
if (ec) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": error iterating directory: " << ec.message();
|
||||
break;
|
||||
}
|
||||
if (!boost::filesystem::is_regular_file(entry.status()))
|
||||
continue;
|
||||
|
||||
std::string filename = entry.path().filename().string();
|
||||
|
||||
if (filename.rfind(prefix, 0) != 0)
|
||||
continue;
|
||||
if (filename.size() <= extension.size() ||
|
||||
filename.compare(filename.size() - extension.size(), extension.size(), extension) != 0)
|
||||
continue;
|
||||
|
||||
std::string version = filename.substr(prefix.size(),
|
||||
filename.size() - prefix.size() - extension.size());
|
||||
discovered_versions.push_back(version);
|
||||
}
|
||||
|
||||
return discovered_versions;
|
||||
}
|
||||
|
||||
int NetworkAgent::initialize_network_module(bool using_backup, const std::string& version)
|
||||
{
|
||||
clear_load_error();
|
||||
@@ -1770,3 +1818,63 @@ int NetworkAgent::get_model_mall_rating_result(int job_id, std::string &rating_r
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
std::vector<BBL::NetworkLibraryVersionInfo> BBL::get_all_available_versions()
|
||||
{
|
||||
std::vector<NetworkLibraryVersionInfo> result;
|
||||
std::set<std::string> known_base_versions;
|
||||
std::set<std::string> all_known_versions;
|
||||
|
||||
for (size_t i = 0; i < AVAILABLE_NETWORK_VERSIONS_COUNT; ++i) {
|
||||
result.push_back(NetworkLibraryVersionInfo::from_static(AVAILABLE_NETWORK_VERSIONS[i]));
|
||||
known_base_versions.insert(AVAILABLE_NETWORK_VERSIONS[i].version);
|
||||
all_known_versions.insert(AVAILABLE_NETWORK_VERSIONS[i].version);
|
||||
}
|
||||
|
||||
std::vector<std::string> discovered = Slic3r::NetworkAgent::scan_plugin_versions();
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> suffixed_versions;
|
||||
|
||||
for (const auto& version : discovered) {
|
||||
if (all_known_versions.count(version) > 0)
|
||||
continue;
|
||||
|
||||
std::string base = extract_base_version(version);
|
||||
std::string suffix = extract_suffix(version);
|
||||
|
||||
if (suffix.empty())
|
||||
continue;
|
||||
|
||||
if (known_base_versions.count(base) == 0)
|
||||
continue;
|
||||
|
||||
suffixed_versions.emplace_back(base, version);
|
||||
all_known_versions.insert(version);
|
||||
}
|
||||
|
||||
std::sort(suffixed_versions.begin(), suffixed_versions.end(),
|
||||
[](const auto& a, const auto& b) {
|
||||
if (a.first != b.first) return a.first > b.first;
|
||||
return a.second < b.second;
|
||||
});
|
||||
|
||||
for (const auto& [base, full] : suffixed_versions) {
|
||||
size_t insert_pos = 0;
|
||||
for (size_t i = 0; i < result.size(); ++i) {
|
||||
if (result[i].base_version == base) {
|
||||
insert_pos = i + 1;
|
||||
while (insert_pos < result.size() &&
|
||||
result[insert_pos].base_version == base) {
|
||||
++insert_pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string sfx = extract_suffix(full);
|
||||
result.insert(result.begin() + insert_pos,
|
||||
NetworkLibraryVersionInfo::from_discovered(full, base, sfx));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ public:
|
||||
static bool versioned_library_exists(const std::string& version);
|
||||
static bool legacy_library_exists();
|
||||
static void remove_legacy_library();
|
||||
static std::vector<std::string> scan_plugin_versions();
|
||||
static int initialize_network_module(bool using_backup = false, const std::string& version = "");
|
||||
static int unload_network_module();
|
||||
static bool is_network_module_loaded();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
extern std::string g_log_folder;
|
||||
extern std::string g_log_start_time;
|
||||
@@ -329,6 +330,48 @@ inline const char* get_latest_network_version() {
|
||||
return AVAILABLE_NETWORK_VERSIONS[0].version;
|
||||
}
|
||||
|
||||
struct NetworkLibraryVersionInfo {
|
||||
std::string version;
|
||||
std::string base_version;
|
||||
std::string suffix;
|
||||
std::string display_name;
|
||||
std::string url_override;
|
||||
bool is_latest;
|
||||
std::string warning;
|
||||
bool is_discovered;
|
||||
|
||||
static NetworkLibraryVersionInfo from_static(const NetworkLibraryVersion& v) {
|
||||
return {
|
||||
v.version,
|
||||
v.version,
|
||||
"",
|
||||
v.display_name,
|
||||
v.url_override ? v.url_override : "",
|
||||
v.is_latest,
|
||||
v.warning ? v.warning : "",
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
static NetworkLibraryVersionInfo from_discovered(const std::string& full_version,
|
||||
const std::string& base,
|
||||
const std::string& sfx) {
|
||||
return {full_version, base, sfx, full_version, "", false, "", true};
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string extract_base_version(const std::string& full_version) {
|
||||
auto pos = full_version.find('-');
|
||||
return (pos == std::string::npos) ? full_version : full_version.substr(0, pos);
|
||||
}
|
||||
|
||||
inline std::string extract_suffix(const std::string& full_version) {
|
||||
auto pos = full_version.find('-');
|
||||
return (pos == std::string::npos) ? "" : full_version.substr(pos + 1);
|
||||
}
|
||||
|
||||
std::vector<NetworkLibraryVersionInfo> get_all_available_versions();
|
||||
|
||||
struct NetworkLibraryLoadError {
|
||||
bool has_error = false;
|
||||
std::string message;
|
||||
|
||||
@@ -5,6 +5,7 @@ add_executable(${_TEST_NAME}_tests
|
||||
test_3mf.cpp
|
||||
test_aabbindirect.cpp
|
||||
test_appconfig.cpp
|
||||
test_bambu_networking.cpp
|
||||
test_clipper_offset.cpp
|
||||
test_clipper_utils.cpp
|
||||
test_config.cpp
|
||||
@@ -30,6 +31,7 @@ if (TARGET OpenVDB::openvdb)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r Catch2::Catch2WithMain)
|
||||
target_include_directories(${_TEST_NAME}_tests PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests")
|
||||
|
||||
if (WIN32)
|
||||
|
||||
98
tests/libslic3r/test_bambu_networking.cpp
Normal file
98
tests/libslic3r/test_bambu_networking.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "slic3r/Utils/bambu_networking.hpp"
|
||||
|
||||
using namespace BBL;
|
||||
|
||||
TEST_CASE("extract_base_version", "[BambuNetworking]") {
|
||||
SECTION("version without suffix returns unchanged") {
|
||||
REQUIRE(extract_base_version("02.03.00.62") == "02.03.00.62");
|
||||
REQUIRE(extract_base_version("01.00.00.00") == "01.00.00.00");
|
||||
}
|
||||
|
||||
SECTION("version with suffix returns base only") {
|
||||
REQUIRE(extract_base_version("02.03.00.62-mod") == "02.03.00.62");
|
||||
REQUIRE(extract_base_version("02.03.00.62-patched") == "02.03.00.62");
|
||||
REQUIRE(extract_base_version("02.03.00.62-test-build") == "02.03.00.62");
|
||||
}
|
||||
|
||||
SECTION("empty string returns empty") {
|
||||
REQUIRE(extract_base_version("") == "");
|
||||
}
|
||||
|
||||
SECTION("suffix only returns empty") {
|
||||
REQUIRE(extract_base_version("-mod") == "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("extract_suffix", "[BambuNetworking]") {
|
||||
SECTION("version without suffix returns empty") {
|
||||
REQUIRE(extract_suffix("02.03.00.62") == "");
|
||||
REQUIRE(extract_suffix("01.00.00.00") == "");
|
||||
}
|
||||
|
||||
SECTION("version with suffix returns suffix without dash") {
|
||||
REQUIRE(extract_suffix("02.03.00.62-mod") == "mod");
|
||||
REQUIRE(extract_suffix("02.03.00.62-patched") == "patched");
|
||||
}
|
||||
|
||||
SECTION("version with multiple dashes returns everything after first dash") {
|
||||
REQUIRE(extract_suffix("02.03.00.62-test-build") == "test-build");
|
||||
}
|
||||
|
||||
SECTION("empty string returns empty") {
|
||||
REQUIRE(extract_suffix("") == "");
|
||||
}
|
||||
|
||||
SECTION("suffix only returns suffix without leading dash") {
|
||||
REQUIRE(extract_suffix("-mod") == "mod");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("NetworkLibraryVersionInfo::from_static", "[BambuNetworking]") {
|
||||
SECTION("converts static version info correctly") {
|
||||
NetworkLibraryVersion static_ver{"02.03.00.62", "02.03.00.62", nullptr, true, nullptr};
|
||||
auto info = NetworkLibraryVersionInfo::from_static(static_ver);
|
||||
|
||||
REQUIRE(info.version == "02.03.00.62");
|
||||
REQUIRE(info.base_version == "02.03.00.62");
|
||||
REQUIRE(info.suffix == "");
|
||||
REQUIRE(info.display_name == "02.03.00.62");
|
||||
REQUIRE(info.url_override == "");
|
||||
REQUIRE(info.is_latest == true);
|
||||
REQUIRE(info.warning == "");
|
||||
REQUIRE(info.is_discovered == false);
|
||||
}
|
||||
|
||||
SECTION("handles version with warning") {
|
||||
NetworkLibraryVersion static_ver{"02.00.02.50", "02.00.02.50", nullptr, false, "This is a warning"};
|
||||
auto info = NetworkLibraryVersionInfo::from_static(static_ver);
|
||||
|
||||
REQUIRE(info.version == "02.00.02.50");
|
||||
REQUIRE(info.is_latest == false);
|
||||
REQUIRE(info.warning == "This is a warning");
|
||||
REQUIRE(info.is_discovered == false);
|
||||
}
|
||||
|
||||
SECTION("handles version with url override") {
|
||||
NetworkLibraryVersion static_ver{"02.01.01.52", "02.01.01.52", "https://custom.url/plugin.zip", false, nullptr};
|
||||
auto info = NetworkLibraryVersionInfo::from_static(static_ver);
|
||||
|
||||
REQUIRE(info.url_override == "https://custom.url/plugin.zip");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("NetworkLibraryVersionInfo::from_discovered", "[BambuNetworking]") {
|
||||
SECTION("creates discovered version info correctly") {
|
||||
auto info = NetworkLibraryVersionInfo::from_discovered("02.03.00.62-mod", "02.03.00.62", "mod");
|
||||
|
||||
REQUIRE(info.version == "02.03.00.62-mod");
|
||||
REQUIRE(info.base_version == "02.03.00.62");
|
||||
REQUIRE(info.suffix == "mod");
|
||||
REQUIRE(info.display_name == "02.03.00.62-mod");
|
||||
REQUIRE(info.url_override == "");
|
||||
REQUIRE(info.is_latest == false);
|
||||
REQUIRE(info.warning == "");
|
||||
REQUIRE(info.is_discovered == true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user