diff --git a/core/server/gen/libcore.proto b/core/server/gen/libcore.proto index 4c07518..04b3508 100644 --- a/core/server/gen/libcore.proto +++ b/core/server/gen/libcore.proto @@ -111,6 +111,7 @@ message SpeedTestResult { optional string server_name = 6 [default = ""]; optional string server_country = 7 [default = ""]; optional bool cancelled = 8 [default = false]; + optional string server_country_emoji = 9 [default = ""]; } message SpeedTestResponse { diff --git a/core/server/go.mod b/core/server/go.mod index 7c09637..be1f74a 100644 --- a/core/server/go.mod +++ b/core/server/go.mod @@ -30,6 +30,7 @@ require ( github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/anytls/sing-anytls v0.0.8 // indirect + github.com/biter777/countries v1.7.5 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/caddyserver/certmagic v0.23.0 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect diff --git a/core/server/go.sum b/core/server/go.sum index 6d2000e..7ff62c0 100644 --- a/core/server/go.sum +++ b/core/server/go.sum @@ -12,6 +12,8 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/anytls/sing-anytls v0.0.8 h1:1u/fnH1HoeeMV5mX7/eUOjLBvPdkd1UJRmXiRi6Vymc= github.com/anytls/sing-anytls v0.0.8/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8= +github.com/biter777/countries v1.7.5 h1:MJ+n3+rSxWQdqVJU8eBy9RqcdH6ePPn4PJHocVWUa+Q= +github.com/biter777/countries v1.7.5/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= diff --git a/core/server/internal/country_helper.go b/core/server/internal/country_helper.go new file mode 100644 index 0000000..7141227 --- /dev/null +++ b/core/server/internal/country_helper.go @@ -0,0 +1,25 @@ +package internal + +import "github.com/biter777/countries" + +var countryMap map[string]*countries.Country + +func init() { + countryMap = make(map[string]*countries.Country) + allCountries := countries.AllInfo() + for _, country := range allCountries { + countryMap[country.Name] = country + } +} + +func GetCountryByName(name string) *countries.Country { + return countryMap[name] +} + +func GetCountryEmojiByName(name string) string { + country, ok := countryMap[name] + if !ok { + return "" + } + return country.Emoji +} diff --git a/core/server/server.go b/core/server/server.go index 9deed14..8dc9e76 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -348,14 +348,15 @@ func (s *server) SpeedTest(in *gen.SpeedTestRequest, out *gen.SpeedTestResponse) errStr = data.Error.Error() } res = append(res, &gen.SpeedTestResult{ - DlSpeed: To(data.DlSpeed), - UlSpeed: To(data.UlSpeed), - Latency: To(data.Latency), - OutboundTag: To(data.Tag), - Error: To(errStr), - ServerName: To(data.ServerName), - ServerCountry: To(data.ServerCountry), - Cancelled: To(data.Cancelled), + DlSpeed: To(data.DlSpeed), + UlSpeed: To(data.UlSpeed), + Latency: To(data.Latency), + OutboundTag: To(data.Tag), + Error: To(errStr), + ServerName: To(data.ServerName), + ServerCountry: To(data.ServerCountry), + ServerCountryEmoji: To(data.ServerCountryEmoji), + Cancelled: To(data.Cancelled), }) } @@ -370,14 +371,15 @@ func (s *server) QuerySpeedTest(in *gen.EmptyReq, out *gen.QuerySpeedTestRespons errStr = res.Error.Error() } out.Result = &gen.SpeedTestResult{ - DlSpeed: To(res.DlSpeed), - UlSpeed: To(res.UlSpeed), - Latency: To(res.Latency), - OutboundTag: To(res.Tag), - Error: To(errStr), - ServerName: To(res.ServerName), - ServerCountry: To(res.ServerCountry), - Cancelled: To(res.Cancelled), + DlSpeed: To(res.DlSpeed), + UlSpeed: To(res.UlSpeed), + Latency: To(res.Latency), + OutboundTag: To(res.Tag), + Error: To(errStr), + ServerName: To(res.ServerName), + ServerCountry: To(res.ServerCountry), + ServerCountryEmoji: To(res.ServerCountryEmoji), + Cancelled: To(res.Cancelled), } out.IsRunning = To(isRunning) return nil diff --git a/core/server/test_utils.go b/core/server/test_utils.go index 4da92d2..84bcfb3 100644 --- a/core/server/test_utils.go +++ b/core/server/test_utils.go @@ -53,14 +53,15 @@ func (u *URLTestReporter) Results() []*URLTestResult { } type SpeedTestResult struct { - Tag string - DlSpeed string - UlSpeed string - Latency int32 - ServerName string - ServerCountry string - Error error - Cancelled bool + Tag string + DlSpeed string + UlSpeed string + Latency int32 + ServerName string + ServerCountry string + ServerCountryEmoji string + Error error + Cancelled bool } type SpeedTestResultQuerier struct { @@ -295,6 +296,12 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n } res.ServerName = srv[0].Name res.ServerCountry = srv[0].Country + countryEmoji := internal.GetCountryEmojiByName(srv[0].Country) + if countryEmoji == "" { + fmt.Println("Failed to get country emoji for", srv[0].Name) + } else { + res.ServerCountryEmoji = countryEmoji + } done := make(chan struct{}) diff --git a/include/dataStore/ProxyEntity.hpp b/include/dataStore/ProxyEntity.hpp index 4b02e32..2d729d1 100644 --- a/include/dataStore/ProxyEntity.hpp +++ b/include/dataStore/ProxyEntity.hpp @@ -41,6 +41,7 @@ namespace Configs { int latency = 0; QString dl_speed; QString ul_speed; + QString test_country_emoji; std::shared_ptr bean; std::shared_ptr traffic_data = std::make_shared(""); diff --git a/include/global/DataStore.hpp b/include/global/DataStore.hpp index 9918a38..3af8f6c 100644 --- a/include/global/DataStore.hpp +++ b/include/global/DataStore.hpp @@ -100,7 +100,7 @@ namespace Configs { bool enable_stats = true; int stats_tab = 0; // either connection or log int speed_test_mode = TestConfig::FULL; - int speed_test_timeout_ms = 3000; + int speed_test_timeout_ms = 5000; QString simple_dl_url = "http://cachefly.cachefly.net/1mb.test"; bool allow_beta_update = false; diff --git a/src/dataStore/ProxyEntity.cpp b/src/dataStore/ProxyEntity.cpp index b1fc1d3..e5235fc 100644 --- a/src/dataStore/ProxyEntity.cpp +++ b/src/dataStore/ProxyEntity.cpp @@ -12,6 +12,7 @@ namespace Configs _add(new configItem("dl", &dl_speed, itemType::string)); _add(new configItem("ul", &ul_speed, itemType::string)); _add(new configItem("report", &full_test_report, itemType::string)); + _add(new configItem("country_emoji", &test_country_emoji, itemType::string)); if (bean != nullptr) { this->bean = std::shared_ptr(bean); @@ -25,21 +26,25 @@ namespace Configs if (latency < 0) { result = "Unavailable"; } else if (latency > 0) { - result = UNICODE_LRO + QString("%1 ms").arg(latency); + if (!test_country_emoji.isEmpty()) result += UNICODE_LRO + test_country_emoji + " "; + result += QString("%1 ms").arg(latency); } - if (!dl_speed.isEmpty()) result += " ↓" + dl_speed; - if (!ul_speed.isEmpty()) result += " ↑" + ul_speed; + if (!dl_speed.isEmpty() && dl_speed != "N/A") result += " ↓" + dl_speed; + if (!ul_speed.isEmpty() && ul_speed != "N/A") result += " ↑" + ul_speed; return result; } QColor ProxyEntity::DisplayLatencyColor() const { if (latency < 0) { - return Qt::red; + return Qt::darkGray; } else if (latency > 0) { - if (latency <= 200) { + if (latency <= 100) { return Qt::darkGreen; - } else { + } else if (latency <= 300) + { return Qt::darkYellow; + } else { + return Qt::red; } } else { return {}; diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 4c54cae..1be26ba 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1080,10 +1080,11 @@ void MainWindow::UpdateDataView(bool force) "Dl↓ %2 " "Ul↑ %3" "" - "

Server: %4, %5

" + "

Server: %4%5, %6

" ).arg(currentSptProfileName, currentTestResult.dl_speed.value().c_str(), currentTestResult.ul_speed.value().c_str(), + currentTestResult.server_country_emoji.value().c_str(), currentTestResult.server_country.value().c_str(), currentTestResult.server_name.value().c_str()); } diff --git a/src/ui/mainwindow_grpc.cpp b/src/ui/mainwindow_grpc.cpp index 6ef7b60..12f63e2 100644 --- a/src/ui/mainwindow_grpc.cpp +++ b/src/ui/mainwindow_grpc.cpp @@ -323,6 +323,7 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC if (!res.result.value().dl_speed.value().empty()) profile->dl_speed = QString::fromStdString(res.result.value().dl_speed.value()); if (!res.result.value().ul_speed.value().empty()) profile->ul_speed = QString::fromStdString(res.result.value().ul_speed.value()); if (profile->latency <= 0 && res.result.value().latency.value() > 0) profile->latency = res.result.value().latency.value(); + if (!res.result->server_country_emoji.value().empty()) profile->test_country_emoji = QString::fromStdString(res.result.value().server_country_emoji.value()); refresh_proxy_list(profile->id); lastProxyListUpdate = QDateTime::currentDateTime(); } @@ -364,10 +365,12 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC ent->dl_speed = QString::fromStdString(res.dl_speed.value()); ent->ul_speed = QString::fromStdString(res.ul_speed.value()); if (ent->latency <= 0 && res.latency.value() > 0) ent->latency = res.latency.value(); + if (!res.server_country_emoji.value().empty()) ent->test_country_emoji = QString::fromStdString(res.server_country_emoji.value()); } else { ent->dl_speed = "N/A"; ent->ul_speed = "N/A"; ent->latency = -1; + ent->test_country_emoji = ""; MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); } ent->Save();