mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-01 07:12:07 +00:00
List same-series OTA plugin builds in the version selector
This commit is contained in:
@@ -1272,6 +1272,9 @@ wxBoxSizer *PreferencesDialog::create_item_network_plugin_version(wxString title
|
|||||||
|
|
||||||
if (ver.is_latest) {
|
if (ver.is_latest) {
|
||||||
label += " " + _L("(Latest)");
|
label += " " + _L("(Latest)");
|
||||||
|
} else if (ver.is_discovered && ver.suffix.empty()) {
|
||||||
|
// A same-series build found on disk (usually installed by the OTA update).
|
||||||
|
label += " " + _L("(installed)");
|
||||||
}
|
}
|
||||||
m_network_version_combo->Append(label);
|
m_network_version_combo->Append(label);
|
||||||
if (current_version == ver.version) {
|
if (current_version == ver.version) {
|
||||||
|
|||||||
@@ -833,6 +833,58 @@ std::vector<NetworkLibraryVersionInfo> get_all_available_versions()
|
|||||||
NetworkLibraryVersionInfo::from_discovered(full, base, sfx));
|
NetworkLibraryVersionInfo::from_discovered(full, base, sfx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also surface discovered versions WITHOUT a suffix (typically installed by the
|
||||||
|
// OTA plug-in update) when they belong to a whitelisted release series: the plugin
|
||||||
|
// ABI is stable within an AA.BB.CC series (the OTA sync only ever accepts same-series
|
||||||
|
// updates), so these load with the same struct layout as the static entry they follow.
|
||||||
|
// The legacy entry is excluded as an anchor - is_legacy_version() matches exactly, so
|
||||||
|
// a different 01.x build would be loaded with the modern layout and break.
|
||||||
|
std::vector<std::pair<std::string, std::string>> series_versions; // {anchor whitelist version, discovered version}
|
||||||
|
for (const auto& version : discovered) {
|
||||||
|
if (all_known_versions.count(version) > 0)
|
||||||
|
continue;
|
||||||
|
if (!extract_suffix(version).empty())
|
||||||
|
continue;
|
||||||
|
if (version.size() < 8)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (const auto& base : known_base_versions) {
|
||||||
|
if (BBLNetworkPlugin::is_legacy_version(base))
|
||||||
|
continue;
|
||||||
|
if (base.size() >= 8 && base.compare(0, 8, version, 0, 8) == 0) {
|
||||||
|
series_versions.emplace_back(base, version);
|
||||||
|
all_known_versions.insert(version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ascending sort + insertion right behind the anchor leaves the newest build
|
||||||
|
// closest to its whitelist entry.
|
||||||
|
std::sort(series_versions.begin(), series_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& [anchor, full] : series_versions) {
|
||||||
|
size_t insert_pos = result.size();
|
||||||
|
for (size_t i = 0; i < result.size(); ++i) {
|
||||||
|
if (result[i].version == anchor) {
|
||||||
|
// Skip past the whole base-version block (the entry itself plus any
|
||||||
|
// suffixed dev builds shown under it) so the tree glyphs stay adjacent.
|
||||||
|
insert_pos = i + 1;
|
||||||
|
while (insert_pos < result.size() &&
|
||||||
|
result[insert_pos].base_version == anchor) {
|
||||||
|
++insert_pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.insert(result.begin() + insert_pos,
|
||||||
|
NetworkLibraryVersionInfo::from_discovered(full, full, ""));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
|||||||
add_executable(${_TEST_NAME}_tests
|
add_executable(${_TEST_NAME}_tests
|
||||||
${_TEST_NAME}_tests_main.cpp
|
${_TEST_NAME}_tests_main.cpp
|
||||||
test_dev_mapping.cpp
|
test_dev_mapping.cpp
|
||||||
|
test_network_versions.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
|
|||||||
112
tests/slic3rutils/test_network_versions.cpp
Normal file
112
tests/slic3rutils/test_network_versions.cpp
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#include <catch2/catch_all.hpp>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/nowide/fstream.hpp>
|
||||||
|
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
#include "slic3r/Utils/bambu_networking.hpp"
|
||||||
|
|
||||||
|
using namespace Slic3r;
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Platform naming used by BBLNetworkPlugin::scan_plugin_versions().
|
||||||
|
#if defined(_MSC_VER) || defined(_WIN32)
|
||||||
|
static const char* PLUGIN_PREFIX = "bambu_networking_";
|
||||||
|
static const char* PLUGIN_EXT = ".dll";
|
||||||
|
#elif defined(__WXMAC__) || defined(__APPLE__)
|
||||||
|
static const char* PLUGIN_PREFIX = "libbambu_networking_";
|
||||||
|
static const char* PLUGIN_EXT = ".dylib";
|
||||||
|
#else
|
||||||
|
static const char* PLUGIN_PREFIX = "libbambu_networking_";
|
||||||
|
static const char* PLUGIN_EXT = ".so";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct PluginFolderFixture
|
||||||
|
{
|
||||||
|
fs::path root;
|
||||||
|
std::string previous_data_dir;
|
||||||
|
|
||||||
|
PluginFolderFixture()
|
||||||
|
{
|
||||||
|
previous_data_dir = data_dir();
|
||||||
|
root = fs::temp_directory_path() / fs::unique_path("orca-netver-%%%%%%%%");
|
||||||
|
fs::create_directories(root / "plugins");
|
||||||
|
set_data_dir(root.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
~PluginFolderFixture()
|
||||||
|
{
|
||||||
|
set_data_dir(previous_data_dir);
|
||||||
|
boost::system::error_code ec;
|
||||||
|
fs::remove_all(root, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_plugin(const std::string& version)
|
||||||
|
{
|
||||||
|
boost::nowide::ofstream f((root / "plugins" / (PLUGIN_PREFIX + version + PLUGIN_EXT)).string());
|
||||||
|
f << "stub";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int count_version(const std::vector<NetworkLibraryVersionInfo>& versions, const std::string& v)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
for (const auto& info : versions)
|
||||||
|
if (info.version == v)
|
||||||
|
++n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(PluginFolderFixture, "Same-series OTA plugin versions are surfaced", "[NetworkVersions]")
|
||||||
|
{
|
||||||
|
add_plugin("02.08.01.55"); // same series as the whitelisted latest -> listed
|
||||||
|
add_plugin("02.09.00.10"); // unknown series -> not listed
|
||||||
|
add_plugin("02.08.01.52-custom"); // suffixed build of a whitelisted base -> listed (existing behavior)
|
||||||
|
add_plugin("02.03.00.62"); // exactly a whitelisted version -> no duplicate
|
||||||
|
|
||||||
|
auto versions = get_all_available_versions();
|
||||||
|
|
||||||
|
REQUIRE(count_version(versions, "02.08.01.55") == 1);
|
||||||
|
REQUIRE(count_version(versions, "02.09.00.10") == 0);
|
||||||
|
REQUIRE(count_version(versions, "02.08.01.52-custom") == 1);
|
||||||
|
REQUIRE(count_version(versions, "02.03.00.62") == 1);
|
||||||
|
|
||||||
|
size_t latest_pos = versions.size(), ota_pos = versions.size();
|
||||||
|
for (size_t i = 0; i < versions.size(); ++i) {
|
||||||
|
if (versions[i].version == "02.08.01.52") latest_pos = i;
|
||||||
|
if (versions[i].version == "02.08.01.55") ota_pos = i;
|
||||||
|
}
|
||||||
|
REQUIRE(latest_pos < versions.size());
|
||||||
|
// The discovered build lands right after the whole 02.08.01.52 block
|
||||||
|
// (the whitelist entry plus its suffixed dev build).
|
||||||
|
REQUIRE(ota_pos == latest_pos + 2);
|
||||||
|
REQUIRE(versions[ota_pos - 1].base_version == "02.08.01.52");
|
||||||
|
REQUIRE(versions[ota_pos - 1].version == "02.08.01.52-custom");
|
||||||
|
|
||||||
|
const auto& ota = versions[ota_pos];
|
||||||
|
REQUIRE(ota.is_discovered);
|
||||||
|
REQUIRE(ota.suffix.empty());
|
||||||
|
REQUIRE_FALSE(ota.is_latest);
|
||||||
|
|
||||||
|
// The static whitelist entry keeps its "latest" role.
|
||||||
|
REQUIRE(versions[latest_pos].is_latest);
|
||||||
|
REQUIRE(std::string(get_latest_network_version()) == "02.08.01.52");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(PluginFolderFixture, "Legacy series never adopts discovered builds", "[NetworkVersions]")
|
||||||
|
{
|
||||||
|
// A different build of the legacy series must not be surfaced: is_legacy_version()
|
||||||
|
// matches exactly, so it would be loaded with the modern struct layout.
|
||||||
|
std::string legacy = BAMBU_NETWORK_AGENT_VERSION_LEGACY;
|
||||||
|
std::string legacy_sibling = legacy.substr(0, 9) + (legacy.substr(9) == "99" ? "98" : "99");
|
||||||
|
add_plugin(legacy_sibling);
|
||||||
|
|
||||||
|
auto versions = get_all_available_versions();
|
||||||
|
|
||||||
|
REQUIRE(count_version(versions, legacy_sibling) == 0);
|
||||||
|
REQUIRE(count_version(versions, legacy) == 1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user