diff --git a/CMakeLists.txt b/CMakeLists.txt index dbc1449..f2369e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set(PROJECT_SOURCES src/global/Utils.cpp src/global/HTTPRequestHelper.cpp src/global/DeviceDetailsHelper.cpp + src/global/CountryHelper.cpp 3rdparty/base64.cpp 3rdparty/qrcodegen.cpp diff --git a/core/server/gen/libcore.proto b/core/server/gen/libcore.proto index 04b3508..4c07518 100644 --- a/core/server/gen/libcore.proto +++ b/core/server/gen/libcore.proto @@ -111,7 +111,6 @@ 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 6abfe0b..2bc6068 100644 --- a/core/server/go.mod +++ b/core/server/go.mod @@ -4,7 +4,6 @@ go 1.23.6 require ( github.com/Mahdi-zarei/speedtest-go v1.7.12 - github.com/biter777/countries v1.7.5 github.com/chai2010/protorpc v0.0.0-00010101000000-000000000000 github.com/dustin/go-humanize v1.0.1 github.com/gofrs/uuid/v5 v5.3.2 diff --git a/core/server/go.sum b/core/server/go.sum index 1b0b67c..0705cd2 100644 --- a/core/server/go.sum +++ b/core/server/go.sum @@ -12,8 +12,6 @@ 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.11 h1:w8e9Uj1oP3m4zxkyZDewPk0EcQbvVxb7Nn+rapEx4fc= github.com/anytls/sing-anytls v0.0.11/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 deleted file mode 100644 index 7141227..0000000 --- a/core/server/internal/country_helper.go +++ /dev/null @@ -1,25 +0,0 @@ -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 8dc9e76..9deed14 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -348,15 +348,14 @@ 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), - ServerCountryEmoji: To(data.ServerCountryEmoji), - 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), + Cancelled: To(data.Cancelled), }) } @@ -371,15 +370,14 @@ 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), - ServerCountryEmoji: To(res.ServerCountryEmoji), - 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), + 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 84bcfb3..4da92d2 100644 --- a/core/server/test_utils.go +++ b/core/server/test_utils.go @@ -53,15 +53,14 @@ func (u *URLTestReporter) Results() []*URLTestResult { } type SpeedTestResult struct { - Tag string - DlSpeed string - UlSpeed string - Latency int32 - ServerName string - ServerCountry string - ServerCountryEmoji string - Error error - Cancelled bool + Tag string + DlSpeed string + UlSpeed string + Latency int32 + ServerName string + ServerCountry string + Error error + Cancelled bool } type SpeedTestResultQuerier struct { @@ -296,12 +295,6 @@ 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 2d729d1..e2c9b4b 100644 --- a/include/dataStore/ProxyEntity.hpp +++ b/include/dataStore/ProxyEntity.hpp @@ -4,6 +4,9 @@ #include "include/stats/traffic/TrafficData.hpp" #include "include/configs/proxy/AbstractBean.hpp" #include "include/configs/proxy/ExtraCore.h" +#ifndef Q_MOC_RUN +#include "include/global/CountryHelper.hpp" +#endif namespace Configs { class SocksHttpBean; @@ -41,7 +44,7 @@ namespace Configs { int latency = 0; QString dl_speed; QString ul_speed; - QString test_country_emoji; + QString test_country; std::shared_ptr bean; std::shared_ptr traffic_data = std::make_shared(""); diff --git a/include/global/CountryHelper.hpp b/include/global/CountryHelper.hpp new file mode 100644 index 0000000..16fc271 --- /dev/null +++ b/include/global/CountryHelper.hpp @@ -0,0 +1,255 @@ +#pragma once + +#include + +static const QMap CountryMap = { + { "Afghanistan", "AF" }, + { "Aland Islands", "AX" }, + { "Albania", "AL" }, + { "Algeria", "DZ" }, + { "American Samoa", "AS" }, + { "Andorra", "AD" }, + { "Angola", "AO" }, + { "Anguilla", "AI" }, + { "Antarctica", "AQ" }, + { "Antigua And Barbuda", "AG" }, + { "Argentina", "AR" }, + { "Armenia", "AM" }, + { "Netherlands Antilles", "AN" }, + { "Aruba", "AW" }, + { "Australia", "AU" }, + { "Austria", "AT" }, + { "Azerbaijan", "AZ" }, + { "Bahamas", "BS" }, + { "Bahrain", "BH" }, + { "Bangladesh", "BD" }, + { "Barbados", "BB" }, + { "Belarus", "BY" }, + { "Belgium", "BE" }, + { "Belize", "BZ" }, + { "Benin", "BJ" }, + { "Bermuda", "BM" }, + { "Bhutan", "BT" }, + { "Bolivia", "BO" }, + { "Bosnia And Herzegovina", "BA" }, + { "Botswana", "BW" }, + { "Bouvet Island", "BV" }, + { "Brazil", "BR" }, + { "British Indian Ocean Territory", "IO" }, + { "Brunei Darussalam", "BN" }, + { "Bulgaria", "BG" }, + { "Burkina Faso", "BF" }, + { "Burundi", "BI" }, + { "Cambodia", "KH" }, + { "Cameroon", "CM" }, + { "Canada", "CA" }, + { "Cape Verde", "CV" }, + { "Cayman Islands", "KY" }, + { "Central African Republic", "CF" }, + { "Chad", "TD" }, + { "Chile", "CL" }, + { "China", "CN" }, + { "Christmas Island", "CX" }, + { "Cocos (Keeling) Islands", "CC" }, + { "Colombia", "CO" }, + { "Comoros", "KM" }, + { "Congo", "CG" }, + { "Congo, Democratic Republic", "CD" }, + { "Cook Islands", "CK" }, + { "Costa Rica", "CR" }, + { "Cote D\"Ivoire", "CI" }, + { "Croatia", "HR" }, + { "Cuba", "CU" }, + { "Cyprus", "CY" }, + { "Czech Republic", "CZ" }, + { "Denmark", "DK" }, + { "Djibouti", "DJ" }, + { "Dominica", "DM" }, + { "Dominican Republic", "DO" }, + { "Ecuador", "EC" }, + { "Egypt", "EG" }, + { "El Salvador", "SV" }, + { "Equatorial Guinea", "GQ" }, + { "Eritrea", "ER" }, + { "Estonia", "EE" }, + { "Ethiopia", "ET" }, + { "Falkland Islands (Malvinas)", "FK" }, + { "Faroe Islands", "FO" }, + { "Fiji", "FJ" }, + { "Finland", "FI" }, + { "France", "FR" }, + { "French Guiana", "GF" }, + { "French Polynesia", "PF" }, + { "French Southern Territories", "TF" }, + { "Gabon", "GA" }, + { "Gambia", "GM" }, + { "Georgia", "GE" }, + { "Germany", "DE" }, + { "Ghana", "GH" }, + { "Gibraltar", "GI" }, + { "Greece", "GR" }, + { "Greenland", "GL" }, + { "Grenada", "GD" }, + { "Guadeloupe", "GP" }, + { "Guam", "GU" }, + { "Guatemala", "GT" }, + { "Guernsey", "GG" }, + { "Guinea", "GN" }, + { "Guinea-Bissau", "GW" }, + { "Guyana", "GY" }, + { "Haiti", "HT" }, + { "Heard Island & Mcdonald Islands", "HM" }, + { "Holy See (Vatican City State)", "VA" }, + { "Honduras", "HN" }, + { "Hong Kong", "HK" }, + { "Hungary", "HU" }, + { "Iceland", "IS" }, + { "India", "IN" }, + { "Indonesia", "ID" }, + { "Iran, Islamic Republic Of", "IR" }, + { "Iraq", "IQ" }, + { "Ireland", "IE" }, + { "Isle Of Man", "IM" }, + { "Israel", "IL" }, + { "Italy", "IT" }, + { "Jamaica", "JM" }, + { "Japan", "JP" }, + { "Jersey", "JE" }, + { "Jordan", "JO" }, + { "Kazakhstan", "KZ" }, + { "Kenya", "KE" }, + { "Kiribati", "KI" }, + { "Korea", "KR" }, + { "Kuwait", "KW" }, + { "Kyrgyzstan", "KG" }, + { "Lao People\"s Democratic Republic", "LA" }, + { "Latvia", "LV" }, + { "Lebanon", "LB" }, + { "Lesotho", "LS" }, + { "Liberia", "LR" }, + { "Libyan Arab Jamahiriya", "LY" }, + { "Liechtenstein", "LI" }, + { "Lithuania", "LT" }, + { "Luxembourg", "LU" }, + { "Macao", "MO" }, + { "Macedonia", "MK" }, + { "Madagascar", "MG" }, + { "Malawi", "MW" }, + { "Malaysia", "MY" }, + { "Maldives", "MV" }, + { "Mali", "ML" }, + { "Malta", "MT" }, + { "Marshall Islands", "MH" }, + { "Martinique", "MQ" }, + { "Mauritania", "MR" }, + { "Mauritius", "MU" }, + { "Mayotte", "YT" }, + { "Mexico", "MX" }, + { "Micronesia, Federated States Of", "FM" }, + { "Moldova", "MD" }, + { "Monaco", "MC" }, + { "Mongolia", "MN" }, + { "Montenegro", "ME" }, + { "Montserrat", "MS" }, + { "Morocco", "MA" }, + { "Mozambique", "MZ" }, + { "Myanmar", "MM" }, + { "Namibia", "NA" }, + { "Nauru", "NR" }, + { "Nepal", "NP" }, + { "Netherlands", "NL" }, + { "Netherlands Antilles", "AN" }, + { "New Caledonia", "NC" }, + { "New Zealand", "NZ" }, + { "Nicaragua", "NI" }, + { "Niger", "NE" }, + { "Nigeria", "NG" }, + { "Niue", "NU" }, + { "Norfolk Island", "NF" }, + { "Northern Mariana Islands", "MP" }, + { "Norway", "NO" }, + { "Oman", "OM" }, + { "Pakistan", "PK" }, + { "Palau", "PW" }, + { "Palestinian Territory, Occupied", "PS" }, + { "Panama", "PA" }, + { "Papua New Guinea", "PG" }, + { "Paraguay", "PY" }, + { "Peru", "PE" }, + { "Philippines", "PH" }, + { "Pitcairn", "PN" }, + { "Poland", "PL" }, + { "Portugal", "PT" }, + { "Puerto Rico", "PR" }, + { "Qatar", "QA" }, + { "Reunion", "RE" }, + { "Romania", "RO" }, + { "Russian Federation", "RU" }, + { "Rwanda", "RW" }, + { "Saint Barthelemy", "BL" }, + { "Saint Helena", "SH" }, + { "Saint Kitts And Nevis", "KN" }, + { "Saint Lucia", "LC" }, + { "Saint Martin", "MF" }, + { "Saint Pierre And Miquelon", "PM" }, + { "Saint Vincent And Grenadines", "VC" }, + { "Samoa", "WS" }, + { "San Marino", "SM" }, + { "Sao Tome And Principe", "ST" }, + { "Saudi Arabia", "SA" }, + { "Senegal", "SN" }, + { "Serbia", "RS" }, + { "Seychelles", "SC" }, + { "Sierra Leone", "SL" }, + { "Singapore", "SG" }, + { "Slovakia", "SK" }, + { "Slovenia", "SI" }, + { "Solomon Islands", "SB" }, + { "Somalia", "SO" }, + { "South Africa", "ZA" }, + { "South Georgia And Sandwich Isl.", "GS" }, + { "Spain", "ES" }, + { "Sri Lanka", "LK" }, + { "Sudan", "SD" }, + { "Suriname", "SR" }, + { "Svalbard And Jan Mayen", "SJ" }, + { "Swaziland", "SZ" }, + { "Sweden", "SE" }, + { "Switzerland", "CH" }, + { "Syrian Arab Republic", "SY" }, + { "Taiwan", "TW" }, + { "Tajikistan", "TJ" }, + { "Tanzania", "TZ" }, + { "Thailand", "TH" }, + { "Timor-Leste", "TL" }, + { "Togo", "TG" }, + { "Tokelau", "TK" }, + { "Tonga", "TO" }, + { "Trinidad And Tobago", "TT" }, + { "Tunisia", "TN" }, + { "Turkey", "TR" }, + { "Turkmenistan", "TM" }, + { "Turks And Caicos Islands", "TC" }, + { "Tuvalu", "TV" }, + { "Uganda", "UG" }, + { "Ukraine", "UA" }, + { "United Arab Emirates", "AE" }, + { "United Kingdom", "GB" }, + { "United States", "US" }, + { "United States Outlying Islands", "UM" }, + { "Uruguay", "UY" }, + { "Uzbekistan", "UZ" }, + { "Vanuatu", "VU" }, + { "Venezuela", "VE" }, + { "Viet Nam", "VN" }, + { "Virgin Islands, British", "VG" }, + { "Virgin Islands, U.S.", "VI" }, + { "Wallis And Futuna", "WF" }, + { "Western Sahara", "EH" }, + { "Yemen", "YE" }, + { "Zambia", "ZM" }, +}; + +QString CountryNameToCode(const QString& countryName); + +QString CountryCodeToFlag(const QString& countryCode); diff --git a/src/dataStore/ProxyEntity.cpp b/src/dataStore/ProxyEntity.cpp index e5235fc..89f924a 100644 --- a/src/dataStore/ProxyEntity.cpp +++ b/src/dataStore/ProxyEntity.cpp @@ -12,7 +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)); + _add(new configItem("country", &test_country, itemType::string)); if (bean != nullptr) { this->bean = std::shared_ptr(bean); @@ -26,7 +26,7 @@ namespace Configs if (latency < 0) { result = "Unavailable"; } else if (latency > 0) { - if (!test_country_emoji.isEmpty()) result += UNICODE_LRO + test_country_emoji + " "; + if (!test_country.isEmpty()) result += UNICODE_LRO + CountryCodeToFlag(test_country) + " "; result += QString("%1 ms").arg(latency); } if (!dl_speed.isEmpty() && dl_speed != "N/A") result += " ↓" + dl_speed; diff --git a/src/global/CountryHelper.cpp b/src/global/CountryHelper.cpp new file mode 100644 index 0000000..492330d --- /dev/null +++ b/src/global/CountryHelper.cpp @@ -0,0 +1,13 @@ +#include "include/global/CountryHelper.hpp" + +QString CountryNameToCode(const QString& countryName) { + return CountryMap.value(countryName, ""); +} + +QString CountryCodeToFlag(const QString& countryCode) { + QVector ucs4 = countryCode.toUcs4(); + for (uint& code : ucs4) { + code += 0x1F1A5; + } + return QString::fromUcs4(ucs4.data(), countryCode.length()); +} \ No newline at end of file diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 7633cb0..3475d62 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1158,7 +1158,7 @@ void MainWindow::UpdateDataView(bool force) ).arg(currentSptProfileName, currentTestResult.dl_speed.value().c_str(), currentTestResult.ul_speed.value().c_str(), - currentTestResult.server_country_emoji.value().c_str(), + CountryCodeToFlag(CountryNameToCode(QString::fromStdString(currentTestResult.server_country.value()))), currentTestResult.server_country.value().c_str(), currentTestResult.server_name.value().c_str()); } @@ -1325,7 +1325,9 @@ QList> MainWindow::filterProfilesList(cons MW_show_log("Null profile, maybe data is corrupted"); continue; } - if (searchString.isEmpty() || profile->bean->name.contains(searchString, Qt::CaseInsensitive) || profile->bean->serverAddress.contains(searchString, Qt::CaseInsensitive)) res.append(profile); + if (searchString.isEmpty() || profile->bean->name.contains(searchString, Qt::CaseInsensitive) || profile->bean->serverAddress.contains(searchString, Qt::CaseInsensitive) + || (searchString.startsWith("CODE:") && searchString.mid(5) == profile->test_country)) + res.append(profile); } return res; } diff --git a/src/ui/mainwindow_grpc.cpp b/src/ui/mainwindow_grpc.cpp index 12f63e2..dfd752c 100644 --- a/src/ui/mainwindow_grpc.cpp +++ b/src/ui/mainwindow_grpc.cpp @@ -323,7 +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()); + if (!res.result->server_country.value().empty()) profile->test_country = CountryNameToCode(QString::fromStdString(res.result.value().server_country.value())); refresh_proxy_list(profile->id); lastProxyListUpdate = QDateTime::currentDateTime(); } @@ -365,12 +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()); + if (!res.server_country.value().empty()) ent->test_country = CountryNameToCode(QString::fromStdString(res.server_country.value())); } else { ent->dl_speed = "N/A"; ent->ul_speed = "N/A"; ent->latency = -1; - ent->test_country_emoji = ""; + ent->test_country = ""; MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); } ent->Save();