Optional field (#542)

* Update libcore.proto

* refactor: protobuf optional fields

* fix more protobuf values

* Update mainwindow_grpc.cpp

* Update connectionLister.cpp

* Update mainwindow_grpc.cpp

---------

Co-authored-by: parhelia512 <0011d3@gmail.com>
This commit is contained in:
Mahdi 2025-07-18 01:05:47 +03:30 committed by GitHub
parent d2b8cdd76d
commit 6467c6f2d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 155 additions and 155 deletions

View File

@ -38,8 +38,8 @@ message ErrorResp {
} }
message LoadConfigReq { message LoadConfigReq {
required string core_config = 1 [default = ""]; optional string core_config = 1 [default = ""];
required bool disable_stats = 2 [default = false]; optional bool disable_stats = 2 [default = false];
optional bool need_extra_process = 3 [default = false]; optional bool need_extra_process = 3 [default = false];
optional string extra_process_path = 4 [default = ""]; optional string extra_process_path = 4 [default = ""];
optional string extra_process_args = 5 [default = ""]; optional string extra_process_args = 5 [default = ""];
@ -49,18 +49,18 @@ message LoadConfigReq {
} }
message URLTestResp { message URLTestResp {
required string outbound_tag = 1 [default = ""]; optional string outbound_tag = 1 [default = ""];
required int32 latency_ms = 2 [default = 0 ]; optional int32 latency_ms = 2 [default = 0 ];
required string error = 3 [default = ""]; optional string error = 3 [default = ""];
} }
message TestReq { message TestReq {
required string config = 1 [default = ""]; optional string config = 1 [default = ""];
repeated string outbound_tags = 2; repeated string outbound_tags = 2;
required bool use_default_outbound = 3 [default = false]; optional bool use_default_outbound = 3 [default = false];
required string url = 4 [default = ""]; optional string url = 4 [default = ""];
required bool test_current = 5 [default = false]; optional bool test_current = 5 [default = false];
required int32 max_concurrency = 6 [default = 0]; optional int32 max_concurrency = 6 [default = 0];
} }
message TestResp { message TestResp {
@ -77,16 +77,16 @@ message ListConnectionsResp {
} }
message ConnectionMetaData { message ConnectionMetaData {
required string id = 1 [default = ""]; optional string id = 1 [default = ""];
required int64 created_at = 2 [default = 0]; optional int64 created_at = 2 [default = 0];
required int64 upload = 3 [default = 0]; optional int64 upload = 3 [default = 0];
required int64 download = 4 [default = 0]; optional int64 download = 4 [default = 0];
required string outbound = 5 [default = ""]; optional string outbound = 5 [default = ""];
required string network = 6 [default = ""]; optional string network = 6 [default = ""];
required string dest = 7 [default = ""]; optional string dest = 7 [default = ""];
required string protocol = 8 [default = ""]; optional string protocol = 8 [default = ""];
required string domain = 9 [default = ""]; optional string domain = 9 [default = ""];
required string process = 10 [default = ""]; optional string process = 10 [default = ""];
} }
message GetGeoIPListResponse { message GetGeoIPListResponse {
@ -98,47 +98,47 @@ message GetGeoSiteListResponse {
} }
message GeoListRequest { message GeoListRequest {
required string path = 1 [default = ""]; optional string path = 1 [default = ""];
} }
message CompileGeoIPToSrsRequest { message CompileGeoIPToSrsRequest {
required string item = 1 [default = ""]; optional string item = 1 [default = ""];
required string path = 2 [default = ""]; optional string path = 2 [default = ""];
} }
message CompileGeoSiteToSrsRequest { message CompileGeoSiteToSrsRequest {
required string item = 1 [default = ""]; optional string item = 1 [default = ""];
required string path = 2 [default = ""]; optional string path = 2 [default = ""];
} }
message SetSystemDNSRequest { message SetSystemDNSRequest {
required bool clear = 1 [default = false]; optional bool clear = 1 [default = false];
} }
message IsPrivilegedResponse { message IsPrivilegedResponse {
required bool has_privilege = 1 [default = false]; optional bool has_privilege = 1 [default = false];
} }
message SpeedTestRequest { message SpeedTestRequest {
required string config = 1 [default = ""]; optional string config = 1 [default = ""];
repeated string outbound_tags = 2; repeated string outbound_tags = 2;
required bool test_current = 3 [default = false]; optional bool test_current = 3 [default = false];
required bool use_default_outbound = 4 [default = false]; optional bool use_default_outbound = 4 [default = false];
required bool test_download = 5 [default = false]; optional bool test_download = 5 [default = false];
required bool test_upload = 6 [default = false]; optional bool test_upload = 6 [default = false];
required bool simple_download = 7 [default = false]; optional bool simple_download = 7 [default = false];
required string simple_download_addr = 8 [default = ""]; optional string simple_download_addr = 8 [default = ""];
} }
message SpeedTestResult { message SpeedTestResult {
required string dl_speed = 1 [default = ""]; optional string dl_speed = 1 [default = ""];
required string ul_speed = 2 [default = ""]; optional string ul_speed = 2 [default = ""];
required int32 latency = 3 [default = 0]; optional int32 latency = 3 [default = 0];
required string outbound_tag = 4 [default = ""]; optional string outbound_tag = 4 [default = ""];
required string error = 5 [default = ""]; optional string error = 5 [default = ""];
required string server_name = 6 [default = ""]; optional string server_name = 6 [default = ""];
required string server_country = 7 [default = ""]; optional string server_country = 7 [default = ""];
required bool cancelled = 8 [default = false]; optional bool cancelled = 8 [default = false];
} }
message SpeedTestResponse { message SpeedTestResponse {
@ -146,10 +146,10 @@ message SpeedTestResponse {
} }
message QuerySpeedTestResponse { message QuerySpeedTestResponse {
required SpeedTestResult result = 1; optional SpeedTestResult result = 1;
required bool is_running = 2 [default = false]; optional bool is_running = 2 [default = false];
} }
message QueryURLTestResponse { message QueryURLTestResponse {
repeated URLTestResp results = 1; repeated URLTestResp results = 1;
} }

View File

@ -436,7 +436,7 @@ namespace API {
{ {
resp = spb::pb::deserialize< libcore::IsPrivilegedResponse >( rsp ); resp = spb::pb::deserialize< libcore::IsPrivilegedResponse >( rsp );
*rpcOK = true; *rpcOK = true;
return resp.has_privilege; return resp.has_privilege.value();
} else } else
{ {
NOT_OK NOT_OK

View File

@ -39,86 +39,86 @@ namespace Stats
void ConnectionLister::update() void ConnectionLister::update()
{ {
bool ok; bool ok;
libcore::ListConnectionsResp resp = API::defaultClient->ListConnections(&ok); libcore::ListConnectionsResp resp = API::defaultClient->ListConnections(&ok);
if (!ok) if (!ok || resp.connections.empty())
{ {
return; return;
} }
QMap<QString, ConnectionMetadata> toUpdate;
QMap<QString, ConnectionMetadata> toAdd;
QSet<QString> newState;
QList<ConnectionMetadata> sorted;
auto conns = resp.connections;
for (auto conn : conns)
{
auto c = ConnectionMetadata();
c.id = QString(conn.id.c_str());
c.createdAtMs = conn.created_at;
c.dest = QString(conn.dest.c_str());
c.upload = conn.upload;
c.download = conn.download;
c.domain = QString(conn.domain.c_str());
c.network = QString(conn.network.c_str());
c.outbound = QString(conn.outbound.c_str());
c.process = QString(conn.process.c_str());
c.protocol = QString(conn.protocol.c_str());
if (sort == Default)
{
if (state->contains(c.id))
{
toUpdate[c.id] = c;
} else
{
toAdd[c.id] = c;
}
} else
{
sorted.append(c);
}
newState.insert(c.id);
}
state->clear();
for (const auto& id : newState) state->insert(id);
QMap<QString, ConnectionMetadata> toUpdate;
QMap<QString, ConnectionMetadata> toAdd;
QSet<QString> newState;
QList<ConnectionMetadata> sorted;
auto conns = resp.connections;
for (auto conn : conns)
{
auto c = ConnectionMetadata();
c.id = QString(conn.id.value().c_str());
c.createdAtMs = conn.created_at.value();
c.dest = QString(conn.dest.value().c_str());
c.upload = conn.upload.value();
c.download = conn.download.value();
c.domain = QString(conn.domain.value().c_str());
c.network = QString(conn.network.value().c_str());
c.outbound = QString(conn.outbound.value().c_str());
c.process = QString(conn.process.value().c_str());
c.protocol = QString(conn.protocol.value().c_str());
if (sort == Default) if (sort == Default)
{ {
runOnUiThread([=] { if (state->contains(c.id))
auto m = GetMainWindow(); {
m->UpdateConnectionList(toUpdate, toAdd); toUpdate[c.id] = c;
}); } else
{
toAdd[c.id] = c;
}
} else } else
{ {
if (sort == ByDownload) sorted.append(c);
}
newState.insert(c.id);
}
state->clear();
for (const auto& id : newState) state->insert(id);
if (sort == Default)
{
runOnUiThread([=] {
auto m = GetMainWindow();
m->UpdateConnectionList(toUpdate, toAdd);
});
} else
{
if (sort == ByDownload)
{
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b)
{ {
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b) if (a.download == b.download) return asc ? a.id > b.id : a.id < b.id;
{ return asc ? a.download < b.download : a.download > b.download;
if (a.download == b.download) return asc ? a.id > b.id : a.id < b.id;
return asc ? a.download < b.download : a.download > b.download;
});
}
if (sort == ByUpload)
{
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b)
{
if (a.upload == b.upload) return asc ? a.id > b.id : a.id < b.id;
return asc ? a.upload < b.upload : a.upload > b.upload;
});
}
if (sort == ByProcess)
{
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b)
{
if (a.process == b.process) return asc ? a.id > b.id : a.id < b.id;
return asc ? a.process > b.process : a.process < b.process;
});
}
runOnUiThread([=] {
auto m = GetMainWindow();
m->UpdateConnectionListWithRecreate(sorted);
}); });
} }
if (sort == ByUpload)
{
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b)
{
if (a.upload == b.upload) return asc ? a.id > b.id : a.id < b.id;
return asc ? a.upload < b.upload : a.upload > b.upload;
});
}
if (sort == ByProcess)
{
std::sort(sorted.begin(), sorted.end(), [=](const ConnectionMetadata& a, const ConnectionMetadata& b)
{
if (a.process == b.process) return asc ? a.id > b.id : a.id < b.id;
return asc ? a.process > b.process : a.process < b.process;
});
}
runOnUiThread([=] {
auto m = GetMainWindow();
m->UpdateConnectionListWithRecreate(sorted);
});
}
} }
void ConnectionLister::stopLoop() void ConnectionLister::stopLoop()

View File

@ -962,10 +962,10 @@ void MainWindow::UpdateDataView(bool force)
"</div>" "</div>"
"<p style='text-align:center;margin:0;'>Server: %4, %5</p>" "<p style='text-align:center;margin:0;'>Server: %4, %5</p>"
).arg(currentSptProfileName, ).arg(currentSptProfileName,
currentTestResult.dl_speed.c_str(), currentTestResult.dl_speed.value().c_str(),
currentTestResult.ul_speed.c_str(), currentTestResult.ul_speed.value().c_str(),
currentTestResult.server_country.c_str(), currentTestResult.server_country.value().c_str(),
currentTestResult.server_name.c_str()); currentTestResult.server_name.value().c_str());
} }
ui->data_view->setHtml(html); ui->data_view->setHtml(html);
lastUpdated = QDateTime::currentDateTime(); lastUpdated = QDateTime::currentDateTime();

View File

@ -64,7 +64,7 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
{ {
int entid = -1; int entid = -1;
if (!tag2entID.empty()) { if (!tag2entID.empty()) {
entid = tag2entID.count(QString(res.outbound_tag.c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.c_str())]; entid = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())];
} }
if (entid == -1) { if (entid == -1) {
continue; continue;
@ -73,14 +73,14 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
if (ent == nullptr) { if (ent == nullptr) {
continue; continue;
} }
if (res.error.empty()) { if (res.error.value().empty()) {
ent->latency = res.latency_ms; ent->latency = res.latency_ms.value();
} else { } else {
if (QString(res.error.c_str()).contains("test aborted") || if (QString(res.error.value().c_str()).contains("test aborted") ||
QString(res.error.c_str()).contains("context canceled")) ent->latency=0; QString(res.error.value().c_str()).contains("context canceled")) ent->latency=0;
else { else {
ent->latency = -1; ent->latency = -1;
MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.c_str())); MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str()));
} }
} }
ent->Save(); ent->Save();
@ -100,11 +100,11 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
auto result = defaultClient->Test(&rpcOK, req); auto result = defaultClient->Test(&rpcOK, req);
done->unlock(); done->unlock();
// //
if (!rpcOK) return; if (!rpcOK || result.results.empty()) return;
for (const auto &res: result.results) { for (const auto &res: result.results) {
if (!tag2entID.empty()) { if (!tag2entID.empty()) {
entID = tag2entID.count(QString(res.outbound_tag.c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.c_str())]; entID = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())];
} }
if (entID == -1) { if (entID == -1) {
MW_show_log(tr("Something is very wrong, the subject ent cannot be found!")); MW_show_log(tr("Something is very wrong, the subject ent cannot be found!"));
@ -117,14 +117,14 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin
continue; continue;
} }
if (res.error.empty()) { if (res.error.value().empty()) {
ent->latency = res.latency_ms; ent->latency = res.latency_ms.value();
} else { } else {
if (QString(res.error.c_str()).contains("test aborted") || if (QString(res.error.value().c_str()).contains("test aborted") ||
QString(res.error.c_str()).contains("context canceled")) ent->latency=0; QString(res.error.value().c_str()).contains("context canceled")) ent->latency=0;
else { else {
ent->latency = -1; ent->latency = -1;
MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.c_str())); MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str()));
} }
} }
ent->Save(); ent->Save();
@ -205,14 +205,14 @@ void MainWindow::url_test_current() {
bool rpcOK; bool rpcOK;
auto result = defaultClient->Test(&rpcOK, req); auto result = defaultClient->Test(&rpcOK, req);
if (!rpcOK) return; if (!rpcOK || result.results.empty()) return;
auto latency = result.results[0].latency_ms; auto latency = result.results[0].latency_ms.value();
last_test_time = QTime::currentTime(); last_test_time = QTime::currentTime();
runOnUiThread([=] { runOnUiThread([=] {
if (!result.results[0].error.empty()) { if (!result.results[0].error.value().empty()) {
MW_show_log(QString("UrlTest error: %1").arg(result.results[0].error.c_str())); MW_show_log(QString("UrlTest error: %1").arg(result.results[0].error.value().c_str()));
} }
if (latency <= 0) { if (latency <= 0) {
ui->label_running->setText(tr("Test Result") + ": " + tr("Unavailable")); ui->label_running->setText(tr("Test Result") + ": " + tr("Unavailable"));
@ -300,11 +300,11 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC
break; break;
} }
auto res = defaultClient->QueryCurrentSpeedTests(&ok); auto res = defaultClient->QueryCurrentSpeedTests(&ok);
if (!ok || !res.is_running) if (!ok || !res.is_running.value())
{ {
continue; continue;
} }
auto profile = testCurrent ? running : Configs::profileManager->GetProfile(tag2entID[res.result.outbound_tag.c_str()]); auto profile = testCurrent ? running : Configs::profileManager->GetProfile(tag2entID[res.result.value().outbound_tag.value().c_str()]);
if (profile == nullptr) if (profile == nullptr)
{ {
continue; continue;
@ -313,14 +313,14 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC
{ {
showSpeedtestData = true; showSpeedtestData = true;
currentSptProfileName = profile->bean->name; currentSptProfileName = profile->bean->name;
currentTestResult = res.result; currentTestResult = res.result.value();
UpdateDataView(); UpdateDataView();
if (res.result.error.empty() && !res.result.cancelled && lastProxyListUpdate.msecsTo(QDateTime::currentDateTime()) >= 500) if (res.result.value().error.value().empty() && !res.result.value().cancelled.value() && lastProxyListUpdate.msecsTo(QDateTime::currentDateTime()) >= 500)
{ {
if (!res.result.dl_speed.empty()) profile->dl_speed = res.result.dl_speed.c_str(); if (!res.result.value().dl_speed.value().empty()) profile->dl_speed = res.result.value().dl_speed.value().c_str();
if (!res.result.ul_speed.empty()) profile->ul_speed = res.result.ul_speed.c_str(); if (!res.result.value().ul_speed.value().empty()) profile->ul_speed = res.result.value().ul_speed.value().c_str();
if (profile->latency <= 0 && res.result.latency > 0) profile->latency = res.result.latency; if (profile->latency <= 0 && res.result.value().latency.value() > 0) profile->latency = res.result.value().latency.value();
refresh_proxy_list(profile->id); refresh_proxy_list(profile->id);
lastProxyListUpdate = QDateTime::currentDateTime(); lastProxyListUpdate = QDateTime::currentDateTime();
} }
@ -338,12 +338,12 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC
auto result = defaultClient->SpeedTest(&rpcOK, req); auto result = defaultClient->SpeedTest(&rpcOK, req);
doneMu->unlock(); doneMu->unlock();
// //
if (!rpcOK) return; if (!rpcOK || result.results.empty()) return;
for (const auto &res: result.results) { for (const auto &res: result.results) {
if (testCurrent) entID = running ? running->id : -1; if (testCurrent) entID = running ? running->id : -1;
else { else {
entID = tag2entID.count(QString(res.outbound_tag.c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.c_str())]; entID = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())];
} }
if (entID == -1) { if (entID == -1) {
MW_show_log(tr("Something is very wrong, the subject ent cannot be found!")); MW_show_log(tr("Something is very wrong, the subject ent cannot be found!"));
@ -356,17 +356,17 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC
continue; continue;
} }
if (res.cancelled) continue; if (res.cancelled.value()) continue;
if (res.error.empty()) { if (res.error.value().empty()) {
ent->dl_speed = res.dl_speed.c_str(); ent->dl_speed = res.dl_speed.value().c_str();
ent->ul_speed = res.ul_speed.c_str(); ent->ul_speed = res.ul_speed.value().c_str();
if (ent->latency <= 0 && res.latency > 0) ent->latency = res.latency; if (ent->latency <= 0 && res.latency.value() > 0) ent->latency = res.latency.value();
} else { } else {
ent->dl_speed = "N/A"; ent->dl_speed = "N/A";
ent->ul_speed = "N/A"; ent->ul_speed = "N/A";
ent->latency = -1; ent->latency = -1;
MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.c_str())); MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str()));
} }
ent->Save(); ent->Save();
} }
@ -638,4 +638,4 @@ void MainWindow::profile_stop(bool crash, bool sem, bool manual) {
mu_stopping.unlock(); mu_stopping.unlock();
}); });
}); });
} }