diff --git a/go/cmd/nekobox_core/go.mod b/go/cmd/nekobox_core/go.mod index e1f98d1..b2db815 100644 --- a/go/cmd/nekobox_core/go.mod +++ b/go/cmd/nekobox_core/go.mod @@ -8,16 +8,16 @@ require ( github.com/matsuridayo/libneko v0.0.0-20230913024055-5277a5bfc889 github.com/oschwald/maxminddb-golang v1.13.1 github.com/sagernet/sing v0.5.0-rc.2 - github.com/sagernet/sing-box v1.10.0-beta.12 + github.com/sagernet/sing-box v1.10.0 github.com/sagernet/sing-dns v0.3.0-rc.2 - github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b + github.com/sagernet/sing-tun v0.4.0-rc.4 github.com/spf13/cobra v1.8.1 golang.org/x/sys v0.25.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 grpc_server v1.0.0 ) -replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20241016190733-d626a7470382 +replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20241017140058-b3e4d700db51 replace github.com/sagernet/sing-dns => github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20241016191038-09d232d0a8a9 diff --git a/go/cmd/nekobox_core/go.sum b/go/cmd/nekobox_core/go.sum index 34dfc64..0677ce3 100644 --- a/go/cmd/nekobox_core/go.sum +++ b/go/cmd/nekobox_core/go.sum @@ -4,8 +4,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Mahdi-zarei/sing-box v1.3.5-0.20241016190733-d626a7470382 h1:BTUBM6MU5MFRwKj8gSsP2aPL1/jzUV53MneULed32k0= -github.com/Mahdi-zarei/sing-box v1.3.5-0.20241016190733-d626a7470382/go.mod h1:BAEiGv87fBO6hsop/I6KAW97IBlyy3MIjrw1gwuc+WE= +github.com/Mahdi-zarei/sing-box v1.3.5-0.20241017140058-b3e4d700db51 h1:DBU7LsrTT6k6Wuou0m+PwKZ+HeCRRLhIow6hQbz6XWs= +github.com/Mahdi-zarei/sing-box v1.3.5-0.20241017140058-b3e4d700db51/go.mod h1:vVb92PP7RjZxZwSCFpEQG16GokQFP7XbEpC+AUZgSqs= github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20241016191038-09d232d0a8a9 h1:1agKy0IGG6OX6IyFzDhgbplL/1FQQ4LfJLmRA+ufqt8= github.com/Mahdi-zarei/sing-dns v0.3.0-beta.14.0.20241016191038-09d232d0a8a9/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= @@ -163,8 +163,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wK github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b h1:a2VWOxv7uvIThhJyW6bB+D+bciLSkkqzq4bC4yg3U0g= -github.com/sagernet/sing-tun v0.4.0-rc.3.0.20241014141023-07278fb4705b/go.mod h1:+lQdWhqD4atzrCgRhoyrxBCg1OBru/hAv2BT3kdgmGM= +github.com/sagernet/sing-tun v0.4.0-rc.4 h1:EFz+UjLZTm+YS3ob1vpqjOga67wyvnxWcbQKfe5wE3Y= +github.com/sagernet/sing-tun v0.4.0-rc.4/go.mod h1:+lQdWhqD4atzrCgRhoyrxBCg1OBru/hAv2BT3kdgmGM= github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg= github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= diff --git a/go/cmd/nekobox_core/internal/boxdns/monitor_windows.go b/go/cmd/nekobox_core/internal/boxdns/monitor_windows.go index f3b24fd..41fdd26 100644 --- a/go/cmd/nekobox_core/internal/boxdns/monitor_windows.go +++ b/go/cmd/nekobox_core/internal/boxdns/monitor_windows.go @@ -2,6 +2,7 @@ package boxdns import ( "context" + "github.com/sagernet/sing/common/control" "log" "net/netip" "strings" @@ -32,12 +33,16 @@ func init() { }) logger := logFactory.NewLogger("windows-dns") + ifcFinder := control.NewDefaultInterfaceFinder() monitorNU, _ = tun.NewNetworkUpdateMonitor(logger) - monitorDI, _ = tun.NewDefaultInterfaceMonitor(monitorNU, logger, tun.DefaultInterfaceMonitorOptions{}) + monitorDI, _ = tun.NewDefaultInterfaceMonitor(monitorNU, logger, tun.DefaultInterfaceMonitorOptions{ + InterfaceFinder: ifcFinder, + }) monitorDI.RegisterCallback(monitorForUnderlyingDNS) monitorDI.RegisterCallback(handleInterfaceChange) monitorDI.Start() monitorNU.Start() + ifcFinder.Update() go func() { for { @@ -61,8 +66,10 @@ func monitorForUnderlyingDNS(event int) { guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], }) guidStr := "{" + u.String() + "}" - underlyingDNS = getFirstDNS(guidStr) - log.Println("underlyingDNS:", guidStr, underlyingDNS) + if getFirstDNS(guidStr) != underlyingDNS { + underlyingDNS = getFirstDNS(guidStr) + log.Println("underlyingDNS:", guidStr, underlyingDNS) + } } func getFirstDNS(guid string) string { diff --git a/main/Const.hpp b/main/Const.hpp index 671f4fd..365fd43 100644 --- a/main/Const.hpp +++ b/main/Const.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include namespace NekoGui { namespace DomainMatcher { @@ -26,4 +27,9 @@ namespace NekoGui { namespace Information { inline QString HijackInfo = "Listens on the given addr:port (on Windows, port is always 53) and redirects the requests to the DNS module. Domains that match the rules will have their requests hijacked and the A and AAAA queries will be responded with the Inet4 response and Inet6 response respectively.\nThe Redirect settings sets up an inbound that listens on the given addr:port, sniffs the destination if possible and redirects the requests to their true destination.\nThe use case of these settings is apps that do not respect the system proxy for resolving their DNS requests (one such example is discord), You can hijack their DNS requests to 127.0.0.1 and then route them through the Nekoray tunnel. The same effect could be achieved using Tun mode, but one may not want to tunnel the whole device (For example when Gaming), this is where DNS hijack can transparently handle things.\n\nCurrently you can Automatically set the System DNS in windows."; } + +namespace GeoAssets { + inline QStringList GeoIPURLs = {"https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geoip.db"}; + inline QStringList GeoSiteURLs = {"https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db", "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/release/geosite.db"}; + } } // namespace NekoGui diff --git a/main/HTTPRequestHelper.cpp b/main/HTTPRequestHelper.cpp index 8a042db..eae8176 100644 --- a/main/HTTPRequestHelper.cpp +++ b/main/HTTPRequestHelper.cpp @@ -47,33 +47,6 @@ namespace NekoGui_network { return ""; } - QString NetworkRequestHelper::GetLatestDownloadURL(const QString &url, const QString &assetName, bool* success) { - cpr::Session session; - session.SetUrl(cpr::Url{url.toStdString()}); - session.SetTimeout(3000); - if (NekoGui::dataStore->spmode_system_proxy) { - session.SetProxies({{"http", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}, - {"https", "127.0.0.1:" + QString(Int2String(NekoGui::dataStore->inbound_socks_port)).toStdString()}}); - } - cpr::Response r = session.Get(); - if (r.status_code != 200) { - *success = false; - return {r.status_line.c_str()}; - } - auto respObj = QString2QJsonObject(QString(r.text.c_str())); - auto assets = respObj["assets"].toArray(); - for (const auto &asset: assets) { - auto assetObj = asset.toObject(); - if (assetObj["name"] == assetName) { - *success = true; - return assetObj["browser_download_url"].toString(); - } - } - - *success = false; - return "not found"; - } - QString NetworkRequestHelper::DownloadGeoAsset(const QString &url, const QString &fileName) { cpr::Session session; session.SetUrl(cpr::Url{url.toStdString()}); @@ -83,6 +56,7 @@ namespace NekoGui_network { } auto filePath = qApp->applicationDirPath()+ "/" + fileName; std::ofstream fout; + QFile::remove(QString(filePath + ".1")); fout.open(QString(filePath + ".1").toStdString(), std::ios::trunc | std::ios::out | std::ios::binary); auto r = session.Download(fout); fout.close(); diff --git a/main/HTTPRequestHelper.hpp b/main/HTTPRequestHelper.hpp index e721b9c..c786ed0 100644 --- a/main/HTTPRequestHelper.hpp +++ b/main/HTTPRequestHelper.hpp @@ -26,8 +26,6 @@ namespace NekoGui_network { static QString GetHeader(const QList> &header, const QString &name); - static QString GetLatestDownloadURL(const QString &url, const QString &assetName, bool* success); - static QString DownloadGeoAsset(const QString &url, const QString &fileName); }; } // namespace NekoGui_network diff --git a/main/NekoGui.cpp b/main/NekoGui.cpp index 4971fd3..588ada6 100644 --- a/main/NekoGui.cpp +++ b/main/NekoGui.cpp @@ -259,6 +259,7 @@ namespace NekoGui { _add(new configItem("remember_enable", &remember_enable, itemType::boolean)); _add(new configItem("language", &language, itemType::integer)); _add(new configItem("font", &font, itemType::string)); + _add(new configItem("font_size", &font_size, itemType::integer)); _add(new configItem("spmode2", &remember_spmode, itemType::stringList)); _add(new configItem("skip_cert", &skip_cert, itemType::boolean)); _add(new configItem("hk_mw", &hotkey_mainwindow, itemType::string)); diff --git a/main/NekoGui_DataStore.hpp b/main/NekoGui_DataStore.hpp index bff2517..2d9d07e 100644 --- a/main/NekoGui_DataStore.hpp +++ b/main/NekoGui_DataStore.hpp @@ -85,7 +85,8 @@ namespace NekoGui { bool mux_default_on = false; QString theme = "0"; int language = 0; - QString font; + QString font = ""; + int font_size = 0; QString mw_size = ""; QStringList log_ignore = {}; bool start_minimal = false; diff --git a/main/main.cpp b/main/main.cpp index 767154b..bc09485 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -232,6 +232,11 @@ int main(int argc, char* argv[]) { if (!NekoGui::dataStore->font.isEmpty()) { qApp->setFont(NekoGui::dataStore->font); } + if (NekoGui::dataStore->font_size != 0) { + auto font = qApp->font(); + font.setPointSize(NekoGui::dataStore->font_size); + qApp->setFont(font); + } // Signals signal(SIGTERM, signal_handler); diff --git a/ui/Icon.cpp b/ui/Icon.cpp index a34beb3..f14291a 100644 --- a/ui/Icon.cpp +++ b/ui/Icon.cpp @@ -25,8 +25,8 @@ QPixmap Icon::GetTrayIcon(Icon::TrayIconStatus status) { auto side = pixmap.width(); auto radius = side * 0.4; - auto d = side * 0.3; - auto margin = side * 0.05; + auto d = side * 0.4; + auto margin = side * 0.04; if (status == TrayIconStatus::RUNNING) { p.setBrush(QBrush(Qt::darkGreen)); @@ -35,7 +35,7 @@ QPixmap Icon::GetTrayIcon(Icon::TrayIconStatus status) { } else if (status == TrayIconStatus::VPN) { p.setBrush(QBrush(Qt::red)); } else if (status == TrayIconStatus::DNS) { - p.setBrush(QBrush(Qt::yellow)); + p.setBrush(QBrush(Qt::darkMagenta)); } p.drawRoundedRect( QRect(side - d - margin, diff --git a/ui/dialog_basic_settings.cpp b/ui/dialog_basic_settings.cpp index 5ebc241..44d02ba 100644 --- a/ui/dialog_basic_settings.cpp +++ b/ui/dialog_basic_settings.cpp @@ -100,10 +100,23 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) connect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { CACHE.needRestart = true; }); - ui->font->addItems(QFontDatabase::families()); - ui->font->setCurrentText(qApp->font().family()); connect(ui->font, &QComboBox::currentTextChanged, this, [=](const QString &font) { - CACHE.needRestart = true; + qApp->setFont(font); + NekoGui::dataStore->font = font; + NekoGui::dataStore->Save(); + adjustSize(); + }); + for (int i=7;i<=26;i++) { + ui->font_size->addItem(Int2String(i)); + } + ui->font_size->setCurrentText(Int2String(qApp->font().pointSize())); + connect(ui->font_size, &QComboBox::currentTextChanged, this, [=](const QString &sizeStr) { + auto font = qApp->font(); + font.setPointSize(sizeStr.toInt()); + qApp->setFont(font); + NekoGui::dataStore->font_size = sizeStr.toInt(); + NekoGui::dataStore->Save(); + adjustSize(); }); // ui->theme->addItems(QStyleFactory::keys()); @@ -136,32 +149,15 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent) ui->groupBox_core->setTitle(software_core_name); // Assets - ui->geoip_url->setText(NekoGui::dataStore->geoip_download_url); - ui->geosite_url->setText(NekoGui::dataStore->geosite_download_url); - connect(ui->geoip_auto_btn, &QPushButton::clicked, this, [=](){ - bool success; - auto resp = NetworkRequestHelper::GetLatestDownloadURL("https://api.github.com/repos/SagerNet/sing-geoip/releases/latest", "geoip.db", &success); - if (!success) { - runOnUiThread([=](){ - MessageBoxWarning("Error", resp); - }); - return; - } - ui->geoip_url->setText(resp); - }); - connect(ui->geosite_auto_btn, &QPushButton::clicked, this, [=](){ - bool success; - auto resp = NetworkRequestHelper::GetLatestDownloadURL("https://api.github.com/repos/SagerNet/sing-geosite/releases/latest", "geosite.db", &success); - if (!success) { - runOnUiThread([=](){ - MessageBoxWarning("Error", resp); - }); - return; - } - ui->geosite_url->setText(resp); - }); + ui->geoip_url->setEditable(true); + ui->geosite_url->setEditable(true); + ui->geoip_url->addItems(NekoGui::GeoAssets::GeoIPURLs); + ui->geosite_url->addItems(NekoGui::GeoAssets::GeoSiteURLs); + ui->geoip_url->setCurrentText(NekoGui::dataStore->geoip_download_url); + ui->geosite_url->setCurrentText(NekoGui::dataStore->geosite_download_url); + connect(ui->download_geo_btn, &QPushButton::clicked, this, [=]() { - MW_dialog_message(Dialog_DialogBasicSettings, "DownloadAssets;"+ui->geoip_url->text()+";"+ui->geosite_url->text()); + MW_dialog_message(Dialog_DialogBasicSettings, "DownloadAssets;"+ui->geoip_url->currentText()+";"+ui->geosite_url->currentText()); }); connect(ui->remove_srs_btn, &QPushButton::clicked, this, [=](){ auto rsDir = QDir(RULE_SETS_DIR); @@ -259,7 +255,6 @@ void DialogBasicSettings::accept() { // Style NekoGui::dataStore->language = ui->language->currentIndex(); - NekoGui::dataStore->font = ui->font->currentText(); D_SAVE_BOOL(start_minimal) D_SAVE_INT(max_log_line) @@ -300,8 +295,8 @@ void DialogBasicSettings::accept() { NekoGui::dataStore->disable_traffic_stats = ui->disable_stats->isChecked(); // Assets - NekoGui::dataStore->geoip_download_url = ui->geoip_url->text(); - NekoGui::dataStore->geosite_download_url = ui->geosite_url->text(); + NekoGui::dataStore->geoip_download_url = ui->geoip_url->currentText(); + NekoGui::dataStore->geosite_download_url = ui->geosite_url->currentText(); // Mux D_SAVE_INT(mux_concurrency) diff --git a/ui/dialog_basic_settings.ui b/ui/dialog_basic_settings.ui index a182bd6..95e6f9b 100644 --- a/ui/dialog_basic_settings.ui +++ b/ui/dialog_basic_settings.ui @@ -70,7 +70,9 @@ - <html><head/><body><p>Socks + HTTP Proxy</p></body></html> + <html><head/><body><p>Socks + + HTTP Proxy</p></body></html> + Listen Port @@ -336,27 +338,7 @@ - - - - - 0 - 0 - - - - Language - - - - - - - Font - - - - + @@ -385,8 +367,38 @@ - - + + + + Font Size + + + + + + + Font + + + + + + + + 0 + 0 + + + + Language + + + + + + + + @@ -521,7 +533,9 @@ - <html><head/><body><p>Might Improve Ping and Performance</p></body></html> + <html><head/><body><p>Might + Improve Ping and Performance</p></body></html> + Disable Traffic Stats @@ -591,7 +605,9 @@ - <html><head/><body><p>Settings for the sing-box's built-in NTP client</p></body></html> + <html><head/><body><p>Settings for the + sing-box's built-in NTP client</p></body></html> + NTP Settings @@ -643,7 +659,9 @@ - <html><head/><body><p>In minutes</p></body></html> + <html><head/><body><p>In + minutes</p></body></html> + @@ -683,7 +701,9 @@ - <html><head/><body><p>Remove the currently generated rule-sets so that they can be regenerated</p></body></html> + <html><head/><body><p>Remove the + currently generated rule-sets so that they can be regenerated</p></body></html> + Remove Generated Rule-sets @@ -703,17 +723,7 @@ - - - - - - <html><head/><body><p>Sets the URL to the latest sing-geoip release URL</p></body></html> - - - Use Sing-Geoip - - + @@ -727,17 +737,7 @@ - - - - - - <html><head/><body><p>Sets the URL to the latest sing-geosite release URL</p></body></html> - - - Use Sing-Geosite - - + diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 64af2ee..5efeaeb 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -100,9 +100,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // software_name software_name = "NekoBox"; software_core_name = "sing-box"; - // replace default values - if (NekoGui::dataStore->log_level == "warning") NekoGui::dataStore->log_level = "info"; - if (NekoGui::dataStore->mux_protocol.isEmpty()) NekoGui::dataStore->mux_protocol = "h2mux"; // if (QDir("dashboard").count() == 0) { QDir().mkdir("dashboard"); diff --git a/ui/mainwindow_grpc.cpp b/ui/mainwindow_grpc.cpp index 790d12d..e97d2a0 100644 --- a/ui/mainwindow_grpc.cpp +++ b/ui/mainwindow_grpc.cpp @@ -364,7 +364,7 @@ void MainWindow::neko_start(int _id) { runOnNewThread([=] { // stop current running - if (NekoGui::dataStore->started_id >= 0) { + if (running != nullptr) { runOnUiThread([=] { neko_stop(false, true, true); }); sem_stopped.acquire(); }