add country emoji to speed test and its result

This commit is contained in:
Nova 2025-10-03 16:19:14 +03:30
parent f98c77eb1e
commit 10e0b3158d
11 changed files with 80 additions and 32 deletions

View File

@ -111,6 +111,7 @@ message SpeedTestResult {
optional string server_name = 6 [default = ""]; optional string server_name = 6 [default = ""];
optional string server_country = 7 [default = ""]; optional string server_country = 7 [default = ""];
optional bool cancelled = 8 [default = false]; optional bool cancelled = 8 [default = false];
optional string server_country_emoji = 9 [default = ""];
} }
message SpeedTestResponse { message SpeedTestResponse {

View File

@ -30,6 +30,7 @@ require (
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/anytls/sing-anytls v0.0.8 // 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/bits-and-blooms/bitset v1.13.0 // indirect
github.com/caddyserver/certmagic v0.23.0 // indirect github.com/caddyserver/certmagic v0.23.0 // indirect
github.com/caddyserver/zerossl v0.1.3 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect

View File

@ -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/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 h1:1u/fnH1HoeeMV5mX7/eUOjLBvPdkd1UJRmXiRi6Vymc=
github.com/anytls/sing-anytls v0.0.8/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8= 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 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 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= github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU=

View File

@ -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
}

View File

@ -355,6 +355,7 @@ func (s *server) SpeedTest(in *gen.SpeedTestRequest, out *gen.SpeedTestResponse)
Error: To(errStr), Error: To(errStr),
ServerName: To(data.ServerName), ServerName: To(data.ServerName),
ServerCountry: To(data.ServerCountry), ServerCountry: To(data.ServerCountry),
ServerCountryEmoji: To(data.ServerCountryEmoji),
Cancelled: To(data.Cancelled), Cancelled: To(data.Cancelled),
}) })
} }
@ -377,6 +378,7 @@ func (s *server) QuerySpeedTest(in *gen.EmptyReq, out *gen.QuerySpeedTestRespons
Error: To(errStr), Error: To(errStr),
ServerName: To(res.ServerName), ServerName: To(res.ServerName),
ServerCountry: To(res.ServerCountry), ServerCountry: To(res.ServerCountry),
ServerCountryEmoji: To(res.ServerCountryEmoji),
Cancelled: To(res.Cancelled), Cancelled: To(res.Cancelled),
} }
out.IsRunning = To(isRunning) out.IsRunning = To(isRunning)

View File

@ -59,6 +59,7 @@ type SpeedTestResult struct {
Latency int32 Latency int32
ServerName string ServerName string
ServerCountry string ServerCountry string
ServerCountryEmoji string
Error error Error error
Cancelled bool Cancelled bool
} }
@ -295,6 +296,12 @@ func speedTestWithDialer(ctx context.Context, dialer func(ctx context.Context, n
} }
res.ServerName = srv[0].Name res.ServerName = srv[0].Name
res.ServerCountry = srv[0].Country 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{}) done := make(chan struct{})

View File

@ -41,6 +41,7 @@ namespace Configs {
int latency = 0; int latency = 0;
QString dl_speed; QString dl_speed;
QString ul_speed; QString ul_speed;
QString test_country_emoji;
std::shared_ptr<Configs::AbstractBean> bean; std::shared_ptr<Configs::AbstractBean> bean;
std::shared_ptr<Stats::TrafficData> traffic_data = std::make_shared<Stats::TrafficData>(""); std::shared_ptr<Stats::TrafficData> traffic_data = std::make_shared<Stats::TrafficData>("");

View File

@ -100,7 +100,7 @@ namespace Configs {
bool enable_stats = true; bool enable_stats = true;
int stats_tab = 0; // either connection or log int stats_tab = 0; // either connection or log
int speed_test_mode = TestConfig::FULL; 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"; QString simple_dl_url = "http://cachefly.cachefly.net/1mb.test";
bool allow_beta_update = false; bool allow_beta_update = false;

View File

@ -12,6 +12,7 @@ namespace Configs
_add(new configItem("dl", &dl_speed, itemType::string)); _add(new configItem("dl", &dl_speed, itemType::string));
_add(new configItem("ul", &ul_speed, itemType::string)); _add(new configItem("ul", &ul_speed, itemType::string));
_add(new configItem("report", &full_test_report, itemType::string)); _add(new configItem("report", &full_test_report, itemType::string));
_add(new configItem("country_emoji", &test_country_emoji, itemType::string));
if (bean != nullptr) { if (bean != nullptr) {
this->bean = std::shared_ptr<Configs::AbstractBean>(bean); this->bean = std::shared_ptr<Configs::AbstractBean>(bean);
@ -25,21 +26,25 @@ namespace Configs
if (latency < 0) { if (latency < 0) {
result = "Unavailable"; result = "Unavailable";
} else if (latency > 0) { } 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 (!dl_speed.isEmpty() && dl_speed != "N/A") result += "" + dl_speed;
if (!ul_speed.isEmpty()) result += "" + ul_speed; if (!ul_speed.isEmpty() && ul_speed != "N/A") result += "" + ul_speed;
return result; return result;
} }
QColor ProxyEntity::DisplayLatencyColor() const { QColor ProxyEntity::DisplayLatencyColor() const {
if (latency < 0) { if (latency < 0) {
return Qt::red; return Qt::darkGray;
} else if (latency > 0) { } else if (latency > 0) {
if (latency <= 200) { if (latency <= 100) {
return Qt::darkGreen; return Qt::darkGreen;
} else { } else if (latency <= 300)
{
return Qt::darkYellow; return Qt::darkYellow;
} else {
return Qt::red;
} }
} else { } else {
return {}; return {};

View File

@ -1080,10 +1080,11 @@ void MainWindow::UpdateDataView(bool force)
"<span style='color: #3299FF;'>Dl↓ %2</span> " "<span style='color: #3299FF;'>Dl↓ %2</span> "
"<span style='color: #86C43F;'>Ul↑ %3</span>" "<span style='color: #86C43F;'>Ul↑ %3</span>"
"</div>" "</div>"
"<p style='text-align:center;margin:0;'>Server: %4, %5</p>" "<p style='text-align:center;margin:0;'>Server: %4%5, %6</p>"
).arg(currentSptProfileName, ).arg(currentSptProfileName,
currentTestResult.dl_speed.value().c_str(), currentTestResult.dl_speed.value().c_str(),
currentTestResult.ul_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_country.value().c_str(),
currentTestResult.server_name.value().c_str()); currentTestResult.server_name.value().c_str());
} }

View File

@ -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().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 (!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 (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); refresh_proxy_list(profile->id);
lastProxyListUpdate = QDateTime::currentDateTime(); 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->dl_speed = QString::fromStdString(res.dl_speed.value());
ent->ul_speed = QString::fromStdString(res.ul_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 (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 { } 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;
ent->test_country_emoji = "";
MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value())));
} }
ent->Save(); ent->Save();