mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-23 01:50:17 +08:00
refactor: remove geo assets
This commit is contained in:
parent
e288bfb476
commit
667040cf1d
@ -13,11 +13,6 @@ service LibcoreService {
|
||||
rpc QueryStats(EmptyReq) returns (QueryStatsResp);
|
||||
rpc ListConnections(EmptyReq) returns (ListConnectionsResp);
|
||||
//
|
||||
rpc GetGeoIPList(GeoListRequest) returns (GetGeoIPListResponse);
|
||||
rpc GetGeoSiteList(GeoListRequest) returns (GetGeoSiteListResponse);
|
||||
rpc CompileGeoIPToSrs(CompileGeoIPToSrsRequest) returns (EmptyResp);
|
||||
rpc CompileGeoSiteToSrs(CompileGeoSiteToSrsRequest) returns (EmptyResp);
|
||||
//
|
||||
rpc SetSystemDNS(SetSystemDNSRequest) returns (EmptyResp);
|
||||
//
|
||||
rpc IsPrivileged(EmptyReq) returns (IsPrivilegedResponse);
|
||||
@ -86,28 +81,6 @@ message ConnectionMetaData {
|
||||
optional string process = 10 [default = ""];
|
||||
}
|
||||
|
||||
message GetGeoIPListResponse {
|
||||
repeated string items = 1;
|
||||
}
|
||||
|
||||
message GetGeoSiteListResponse {
|
||||
repeated string items = 2;
|
||||
}
|
||||
|
||||
message GeoListRequest {
|
||||
optional string path = 1 [default = ""];
|
||||
}
|
||||
|
||||
message CompileGeoIPToSrsRequest {
|
||||
optional string item = 1 [default = ""];
|
||||
optional string path = 2 [default = ""];
|
||||
}
|
||||
|
||||
message CompileGeoSiteToSrsRequest {
|
||||
optional string item = 1 [default = ""];
|
||||
optional string path = 2 [default = ""];
|
||||
}
|
||||
|
||||
message SetSystemDNSRequest {
|
||||
optional bool clear = 1 [default = false];
|
||||
}
|
||||
@ -150,3 +123,7 @@ message QuerySpeedTestResponse {
|
||||
message QueryURLTestResponse {
|
||||
repeated URLTestResp results = 1;
|
||||
}
|
||||
|
||||
message RuleSet{
|
||||
map<string, string> items = 1;
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ require (
|
||||
github.com/gofrs/uuid/v5 v5.3.2
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
github.com/sagernet/sing v0.7.5
|
||||
github.com/sagernet/sing-box v1.12.1
|
||||
github.com/sagernet/sing-tun v0.7.0-beta.1
|
||||
|
||||
@ -132,8 +132,6 @@ github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc
|
||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
"github.com/oschwald/maxminddb-golang"
|
||||
)
|
||||
|
||||
var (
|
||||
geoipReader *maxminddb.Reader
|
||||
)
|
||||
|
||||
func geoipPreRun(path string) error {
|
||||
reader, err := maxminddb.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if reader.Metadata.DatabaseType != "sing-geoip" {
|
||||
reader.Close()
|
||||
return E.New("incorrect database type, expected sing-geoip, got ", reader.Metadata.DatabaseType)
|
||||
}
|
||||
geoipReader = reader
|
||||
return nil
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
|
||||
"github.com/oschwald/maxminddb-golang"
|
||||
)
|
||||
|
||||
func geoipExport(path string, countryCode string) ([]byte, error) {
|
||||
if err := geoipPreRun(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
networks := geoipReader.Networks(maxminddb.SkipAliasedNetworks)
|
||||
countryMap := make(map[string][]*net.IPNet)
|
||||
var (
|
||||
ipNet *net.IPNet
|
||||
nextCountryCode string
|
||||
err error
|
||||
)
|
||||
for networks.Next() {
|
||||
ipNet, err = networks.Network(&nextCountryCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
countryMap[nextCountryCode] = append(countryMap[nextCountryCode], ipNet)
|
||||
}
|
||||
ipNets := countryMap[strings.ToLower(countryCode)]
|
||||
if len(ipNets) == 0 {
|
||||
return nil, E.New("country code not found: ", countryCode)
|
||||
}
|
||||
|
||||
outputWriter := &bytes.Buffer{}
|
||||
|
||||
encoder := json.NewEncoder(outputWriter)
|
||||
encoder.SetIndent("", " ")
|
||||
var headlessRule option.DefaultHeadlessRule
|
||||
headlessRule.IPCIDR = make([]string, 0, len(ipNets))
|
||||
for _, cidr := range ipNets {
|
||||
headlessRule.IPCIDR = append(headlessRule.IPCIDR, cidr.String())
|
||||
}
|
||||
var plainRuleSet option.PlainRuleSetCompat
|
||||
plainRuleSet.Version = C.RuleSetVersion1
|
||||
plainRuleSet.Options.Rules = []option.HeadlessRule{
|
||||
{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: headlessRule,
|
||||
},
|
||||
}
|
||||
|
||||
err = encoder.Encode(plainRuleSet)
|
||||
return outputWriter.Bytes(), err
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
func ListGeoip(path string) ([]string, error) {
|
||||
if err := geoipPreRun(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return geoipReader.Metadata.Languages, nil
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/common/geosite"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
var (
|
||||
geositeReader *geosite.Reader
|
||||
geositeCodeList []string
|
||||
)
|
||||
|
||||
func geositePreRun(path string) error {
|
||||
reader, codeList, err := geosite.Open(path)
|
||||
if err != nil {
|
||||
return E.Cause(err, "open geosite file ")
|
||||
}
|
||||
geositeReader = reader
|
||||
geositeCodeList = codeList
|
||||
return nil
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/sagernet/sing-box/common/geosite"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
)
|
||||
|
||||
func geositeExport(path string, category string) ([]byte, error) {
|
||||
if err := geositePreRun(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceSet, err := geositeReader.Read(category)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outputWriter := &bytes.Buffer{}
|
||||
|
||||
encoder := json.NewEncoder(outputWriter)
|
||||
encoder.SetIndent("", " ")
|
||||
var headlessRule option.DefaultHeadlessRule
|
||||
defaultRule := geosite.Compile(sourceSet)
|
||||
headlessRule.Domain = defaultRule.Domain
|
||||
headlessRule.DomainSuffix = defaultRule.DomainSuffix
|
||||
headlessRule.DomainKeyword = defaultRule.DomainKeyword
|
||||
headlessRule.DomainRegex = defaultRule.DomainRegex
|
||||
var plainRuleSet option.PlainRuleSetCompat
|
||||
plainRuleSet.Version = C.RuleSetVersion1
|
||||
plainRuleSet.Options.Rules = []option.HeadlessRule{
|
||||
{
|
||||
Type: C.RuleTypeDefault,
|
||||
DefaultOptions: headlessRule,
|
||||
},
|
||||
}
|
||||
|
||||
err = encoder.Encode(plainRuleSet)
|
||||
return outputWriter.Bytes(), err
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
func GeositeList(path string) ([]string, error) {
|
||||
if err := geositePreRun(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return geositeCodeList, nil
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
package boxmain
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/common/srs"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type RuleSetType int
|
||||
|
||||
const (
|
||||
IpRuleSet RuleSetType = iota
|
||||
SiteRuleSet
|
||||
)
|
||||
|
||||
func CompileRuleSet(path string, category string, ruleSetType RuleSetType, destPath string) error {
|
||||
var (
|
||||
content []byte
|
||||
err error
|
||||
)
|
||||
|
||||
if ruleSetType == IpRuleSet {
|
||||
content, err = geoipExport(path, category)
|
||||
} else {
|
||||
content, err = geositeExport(path, category)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plainRuleSet, err := json.UnmarshalExtended[option.PlainRuleSetCompat](content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ruleSet, err := plainRuleSet.Upgrade()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outputFile, err := os.Create(destPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = srs.Write(outputFile, ruleSet, plainRuleSet.Version)
|
||||
if err != nil {
|
||||
outputFile.Close()
|
||||
os.Remove(destPath)
|
||||
return err
|
||||
}
|
||||
outputFile.Close()
|
||||
return nil
|
||||
}
|
||||
@ -296,58 +296,6 @@ func (s *server) ListConnections(in *gen.EmptyReq, out *gen.ListConnectionsResp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) GetGeoIPList(in *gen.GeoListRequest, out *gen.GetGeoIPListResponse) error {
|
||||
resp, err := boxmain.ListGeoip(*in.Path + string(os.PathSeparator) + "geoip.db")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res := make([]string, 0)
|
||||
for _, r := range resp {
|
||||
r += "_IP"
|
||||
res = append(res, r)
|
||||
}
|
||||
|
||||
out.Items = res
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) GetGeoSiteList(in *gen.GeoListRequest, out *gen.GetGeoSiteListResponse) error {
|
||||
resp, err := boxmain.GeositeList(*in.Path + string(os.PathSeparator) + "geosite.db")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res := make([]string, 0)
|
||||
for _, r := range resp {
|
||||
r += "_SITE"
|
||||
res = append(res, r)
|
||||
}
|
||||
|
||||
out.Items = res
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) CompileGeoIPToSrs(in *gen.CompileGeoIPToSrsRequest, out *gen.EmptyResp) error {
|
||||
category := strings.TrimSuffix(*in.Item, "_IP")
|
||||
err := boxmain.CompileRuleSet(*in.Path+string(os.PathSeparator)+"geoip.db", category, boxmain.IpRuleSet, "./rule_sets/"+*in.Item+".srs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) CompileGeoSiteToSrs(in *gen.CompileGeoSiteToSrsRequest, out *gen.EmptyResp) error {
|
||||
category := strings.TrimSuffix(*in.Item, "_SITE")
|
||||
err := boxmain.CompileRuleSet(*in.Path+string(os.PathSeparator)+"geosite.db", category, boxmain.SiteRuleSet, "./rule_sets/"+*in.Item+".srs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) IsPrivileged(in *gen.EmptyReq, out *gen.IsPrivilegedResponse) error {
|
||||
if runtime.GOOS == "windows" {
|
||||
out.HasPrivilege = To(false)
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
#include "3rdparty/protorpc/rpc_client.h"
|
||||
|
||||
namespace API {
|
||||
enum GeoRuleSetType {ip, site};
|
||||
|
||||
class Client {
|
||||
public:
|
||||
explicit Client(std::function<void(const QString &)> onError, const QString &host, int port);
|
||||
@ -27,10 +25,6 @@ namespace API {
|
||||
|
||||
libcore::QueryURLTestResponse QueryURLTest(bool *rpcOK);
|
||||
|
||||
QStringList GetGeoList(bool *rpcOK, GeoRuleSetType mode, const QString& basePath);
|
||||
|
||||
QString CompileGeoSet(bool *rpcOK, GeoRuleSetType mode, std::string category, const QString& basePath);
|
||||
|
||||
QString SetSystemDNS(bool *rpcOK, bool clear) const;
|
||||
|
||||
libcore::ListConnectionsResp ListConnections(bool *rpcOK) const;
|
||||
|
||||
@ -54,11 +54,11 @@ namespace Configs {
|
||||
|
||||
bool IsValid(const std::shared_ptr<ProxyEntity> &ent);
|
||||
|
||||
std::shared_ptr<BuildTestConfigResult> BuildTestConfig(const QList<std::shared_ptr<ProxyEntity>>& profiles);
|
||||
std::shared_ptr<BuildTestConfigResult> BuildTestConfig(const QList<std::shared_ptr<ProxyEntity>>& profiles, const std::map<std::string, std::string>& ruleSetMap);
|
||||
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, bool forTest, bool forExport, int chainID = 0);
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, const std::map<std::string, std::string>& ruleSetMap, bool forTest, bool forExport, int chainID = 0);
|
||||
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status, const std::map<std::string, std::string>& ruleSetMap);
|
||||
|
||||
QJsonObject BuildDnsObject(QString address, bool tunEnabled);
|
||||
|
||||
|
||||
@ -13,12 +13,7 @@ namespace Configs {
|
||||
bool IsAdmin(bool forceRenew=false);
|
||||
|
||||
QString GetBasePath();
|
||||
|
||||
QString GetCoreAssetDir(const QString &name);
|
||||
|
||||
bool NeedGeoAssets();
|
||||
} // namespace Configs
|
||||
|
||||
#define ROUTES_PREFIX_NAME QString("route_profiles")
|
||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||
#define RULE_SETS_DIR QString("rule_sets")
|
||||
|
||||
@ -29,12 +29,6 @@ namespace Configs {
|
||||
inline QString SimpleRuleInfo = "You can add rules with the following format:\ndomain:<your-domain>\nsuffix:<your-domain-suffix>\nkeyword:<your-domain-keyword>\nregex:<your-domain-keyword>\nruleset:<ruleset-name> or ruleset:<remote-ruleset-URL>\nip:<ip-cidr>\nprocessName:<process name>\nprocessPath:<process path>\nRules are validated on tab change or when pressing ok.\nImportant: On saving the rules, the previous rules are discarded, meaning\nany changes made to the generated rules in the Advanced tab will be lost.";
|
||||
}
|
||||
|
||||
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"};
|
||||
inline QList ResetAssetsOptions = {0, 86400, 259200, 604800};
|
||||
}
|
||||
|
||||
namespace TestConfig
|
||||
{
|
||||
enum SpeedTestMode
|
||||
|
||||
@ -94,12 +94,6 @@ namespace Configs {
|
||||
bool sub_insecure = false;
|
||||
int sub_auto_update = -30;
|
||||
|
||||
// Assets
|
||||
QString geoip_download_url = "";
|
||||
QString geosite_download_url = "";
|
||||
int auto_reset_assets_idx = 0;
|
||||
long long last_asset_reset_epoch_secs = 0;
|
||||
|
||||
// Security
|
||||
bool skip_cert = false;
|
||||
QString utlsFingerprint = "";
|
||||
|
||||
@ -84,10 +84,6 @@ public:
|
||||
|
||||
bool StopVPNProcess();
|
||||
|
||||
void DownloadAssets(const QString &geoipUrl, const QString &geositeUrl);
|
||||
|
||||
void ResetAssets(const QString& geoipUrl, const QString& geositeUrl);
|
||||
|
||||
void UpdateConnectionList(const QMap<QString, Stats::ConnectionMetadata>& toUpdate, const QMap<QString, Stats::ConnectionMetadata>& toAdd);
|
||||
|
||||
void UpdateConnectionListWithRecreate(const QList<Stats::ConnectionMetadata>& connections);
|
||||
@ -196,9 +192,7 @@ private:
|
||||
QSemaphore sem_stopped;
|
||||
int exit_reason = 0;
|
||||
//
|
||||
QMutex mu_download_assets;
|
||||
QMutex mu_download_update;
|
||||
QMutex mu_reset_assets;
|
||||
//
|
||||
int toolTipID;
|
||||
//
|
||||
@ -212,6 +206,8 @@ private:
|
||||
libcore::SpeedTestResult currentTestResult;
|
||||
DownloadProgressReport currentDownloadReport; // could use a list, but don't think can show more than one anyways
|
||||
|
||||
std::map<std::string, std::string> ruleSetMap;
|
||||
|
||||
QStringList remoteRouteProfiles;
|
||||
QMutex mu_remoteRouteProfiles;
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ class RouteItem : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RouteItem(QWidget *parent = nullptr, const std::shared_ptr<Configs::RoutingChain>& routeChain = nullptr);
|
||||
explicit RouteItem(QWidget *parent = nullptr, const std::shared_ptr<Configs::RoutingChain>& routeChain = nullptr, const std::map<std::string, std::string>& ruleSetMap = {});
|
||||
~RouteItem() override;
|
||||
|
||||
std::shared_ptr<Configs::RoutingChain> chain;
|
||||
@ -66,7 +66,7 @@ private:
|
||||
void updateRulePreview();
|
||||
|
||||
void updateRouteItemsView();
|
||||
private slots:
|
||||
private slots:
|
||||
void accept() override;
|
||||
|
||||
void on_new_route_item_clicked();
|
||||
|
||||
@ -761,108 +761,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Assets</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Geo Assets and Rule-sets</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="auto_reset">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Every Day</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Every 3 Days</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Every Week</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QPushButton" name="download_geo_btn">
|
||||
<property name="text">
|
||||
<string>Download and Replace Geo files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="geosite_url"/>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Auto Reset Assets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="geoip_url"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="geosite_url_l">
|
||||
<property name="text">
|
||||
<string>GeoSite URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QPushButton" name="reset_assets">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Downloads and replaces the geo asstes, and removes all generated rule-sets, then restarts the proxy</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset All Assets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="geoip_url_l">
|
||||
<property name="text">
|
||||
<string>GeoIP URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QPushButton" name="remove_srs_btn">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Remove the
|
||||
currently generated rule-sets so that they can be regenerated</p></body></html>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove Generated Rule-sets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_5">
|
||||
<attribute name="title">
|
||||
<string>Security</string>
|
||||
|
||||
@ -18,7 +18,7 @@ class DialogManageRoutes : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogManageRoutes(QWidget *parent = nullptr);
|
||||
explicit DialogManageRoutes(QWidget *parent = nullptr, const std::map<std::string, std::string>& dataMap = {});
|
||||
|
||||
~DialogManageRoutes() override;
|
||||
|
||||
@ -35,6 +35,8 @@ private:
|
||||
|
||||
int tooltipID = 0;
|
||||
|
||||
std::map<std::string, std::string> ruleSetMap;
|
||||
|
||||
void set_dns_hijack_enability(bool enable) const;
|
||||
|
||||
static bool validate_dns_rules(const QString &rawString);
|
||||
|
||||
@ -102,90 +102,6 @@ namespace API {
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Client::GetGeoList(bool *rpcOK, GeoRuleSetType mode, const QString& basePath) {
|
||||
switch (mode) {
|
||||
case GeoRuleSetType::ip: {
|
||||
libcore::GeoListRequest request;
|
||||
libcore::GetGeoIPListResponse reply;
|
||||
request.path = basePath.toStdString();
|
||||
std::string resp, req = spb::pb::serialize<std::string>(request);
|
||||
auto err = make_rpc_client()->CallMethod("LibcoreService.GetGeoIPList", &req, &resp);
|
||||
|
||||
if(err.IsNil()) {
|
||||
QStringList res;
|
||||
reply = spb::pb::deserialize< libcore::GetGeoIPListResponse >( resp );
|
||||
for (const auto & i : reply.items) {
|
||||
res.append(QString::fromStdString(i));
|
||||
}
|
||||
*rpcOK = true;
|
||||
return res;
|
||||
} else {
|
||||
NOT_OK
|
||||
return {};
|
||||
}
|
||||
}
|
||||
case GeoRuleSetType::site: {
|
||||
libcore::GeoListRequest request;
|
||||
libcore::GetGeoSiteListResponse reply;
|
||||
request.path = basePath.toStdString();
|
||||
std::string resp, req = spb::pb::serialize<std::string>(request);
|
||||
auto err = make_rpc_client()->CallMethod("LibcoreService.GetGeoSiteList", &req, &resp);
|
||||
|
||||
if(err.IsNil()) {
|
||||
QStringList res;
|
||||
reply = spb::pb::deserialize< libcore::GetGeoSiteListResponse >( resp );
|
||||
for (const auto & i : reply.items) {
|
||||
res.append(QString::fromStdString(i));
|
||||
}
|
||||
*rpcOK = true;
|
||||
return res;
|
||||
} else {
|
||||
NOT_OK
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString Client::CompileGeoSet(bool *rpcOK, GeoRuleSetType mode, std::string category, const QString& basePath) {
|
||||
switch (mode) {
|
||||
case ip: {
|
||||
libcore::CompileGeoIPToSrsRequest request;
|
||||
libcore::EmptyResp reply;
|
||||
request.item = category;
|
||||
request.path = basePath.toStdString();
|
||||
std::string resp, req = spb::pb::serialize<std::string>(request);
|
||||
|
||||
auto err = make_rpc_client()->CallMethod("LibcoreService.CompileGeoIPToSrs", &req, &resp);
|
||||
if(err.IsNil()) {
|
||||
*rpcOK = true;
|
||||
return "";
|
||||
} else {
|
||||
NOT_OK
|
||||
return QString::fromStdString(err.String());
|
||||
}
|
||||
}
|
||||
case site: {
|
||||
libcore::CompileGeoSiteToSrsRequest request;
|
||||
libcore::EmptyResp reply;
|
||||
request.item = category;
|
||||
request.path = basePath.toStdString();
|
||||
std::string resp, req = spb::pb::serialize<std::string>(request);
|
||||
|
||||
auto err = make_rpc_client()->CallMethod("LibcoreService.CompileGeoSiteToSrs", &req, &resp);
|
||||
if(err.IsNil()) {
|
||||
*rpcOK = true;
|
||||
return "";
|
||||
} else {
|
||||
NOT_OK
|
||||
return QString::fromStdString(err.String());
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString Client::SetSystemDNS(bool *rpcOK, const bool clear) const {
|
||||
libcore::SetSystemDNSRequest request;
|
||||
request.clear = clear;
|
||||
|
||||
@ -41,7 +41,7 @@ namespace Configs {
|
||||
|
||||
// Common
|
||||
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, bool forTest, bool forExport, int chainID) {
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, const std::map<std::string, std::string>& ruleSetMap, bool forTest, bool forExport, int chainID) {
|
||||
auto result = std::make_shared<BuildConfigResult>();
|
||||
result->extraCoreData = std::make_shared<ExtraCoreData>();
|
||||
auto status = std::make_shared<BuildConfigStatus>();
|
||||
@ -60,7 +60,7 @@ namespace Configs {
|
||||
}
|
||||
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
||||
} else {
|
||||
BuildConfigSingBox(status);
|
||||
BuildConfigSingBox(status, ruleSetMap);
|
||||
}
|
||||
|
||||
// apply custom config
|
||||
@ -116,7 +116,7 @@ namespace Configs {
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<BuildTestConfigResult> BuildTestConfig(const QList<std::shared_ptr<ProxyEntity>>& profiles) {
|
||||
std::shared_ptr<BuildTestConfigResult> BuildTestConfig(const QList<std::shared_ptr<ProxyEntity>>& profiles, const std::map<std::string, std::string>& ruleSetMap) {
|
||||
auto results = std::make_shared<BuildTestConfigResult>();
|
||||
|
||||
QJsonArray outboundArray = {
|
||||
@ -140,7 +140,7 @@ namespace Configs {
|
||||
item->latency = -1;
|
||||
continue;
|
||||
}
|
||||
auto res = BuildConfig(item, true, false, ++index);
|
||||
auto res = BuildConfig(item, ruleSetMap, true, false, ++index);
|
||||
if (!res->error.isEmpty()) {
|
||||
results->error = res->error;
|
||||
return results;
|
||||
@ -498,7 +498,7 @@ namespace Configs {
|
||||
}
|
||||
|
||||
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status, const std::map<std::string, std::string>& ruleSetMap) {
|
||||
// Prefetch
|
||||
auto routeChain = profileManager->GetRouteChain(dataStore->routing->current_route_id);
|
||||
if (routeChain == nullptr) {
|
||||
@ -656,12 +656,6 @@ namespace Configs {
|
||||
// custom inbound
|
||||
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
||||
|
||||
// Routing
|
||||
if (NeedGeoAssets()) {
|
||||
status->result->error = "Geo Assets are missing, please download them through Basic Settings -> Assets";
|
||||
return;
|
||||
}
|
||||
|
||||
// manage routing section
|
||||
auto routeObj = QJsonObject();
|
||||
if (dataStore->spmode_vpn) {
|
||||
@ -749,8 +743,6 @@ namespace Configs {
|
||||
}
|
||||
|
||||
auto ruleSetArray = QJsonArray();
|
||||
auto geoSitePath = GetCoreAssetDir("geosite.db");
|
||||
auto geoIpPath = GetCoreAssetDir("geoip.db");
|
||||
for (const auto &item: *neededRuleSets) {
|
||||
if(auto url = QUrl(item); url.isValid() && url.fileName().contains(".srs")) {
|
||||
ruleSetArray += QJsonObject{
|
||||
@ -761,26 +753,13 @@ namespace Configs {
|
||||
};
|
||||
}
|
||||
else {
|
||||
QString srsUrl = QString::fromStdString(ruleSetMap.at(item.toStdString()));
|
||||
ruleSetArray += QJsonObject{
|
||||
{"type", "local"},
|
||||
{"tag", item},
|
||||
{"type", "remote"},
|
||||
{"tag", get_rule_set_name(srsUrl)},
|
||||
{"format", "binary"},
|
||||
{"path", RULE_SETS_DIR + QString("/%1.srs").arg(item)},
|
||||
{"url", srsUrl},
|
||||
};
|
||||
if (QFile(QString(RULE_SETS_DIR + "/%1.srs").arg(item)).exists()) continue;
|
||||
bool ok;
|
||||
auto mode = API::GeoRuleSetType::site;
|
||||
auto geoAssertPath = geoSitePath;
|
||||
if (item.contains("_IP")) {
|
||||
mode = API::GeoRuleSetType::ip;
|
||||
geoAssertPath = geoIpPath;
|
||||
}
|
||||
auto err = API::defaultClient->CompileGeoSet(&ok, mode, item.toStdString(), geoAssertPath);
|
||||
if (!ok) {
|
||||
MW_show_log("Failed to generate rule set asset for " + item);
|
||||
status->result->error = err;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
routeObj["rule_set"] = ruleSetArray;
|
||||
|
||||
@ -291,10 +291,6 @@ namespace Configs {
|
||||
_add(new configItem("ntp_server_address", &ntp_server_address, itemType::string));
|
||||
_add(new configItem("ntp_server_port", &ntp_server_port, itemType::integer));
|
||||
_add(new configItem("ntp_interval", &ntp_interval, itemType::string));
|
||||
_add(new configItem("geoip_download_url", &geoip_download_url, itemType::string));
|
||||
_add(new configItem("geosite_download_url", &geosite_download_url, itemType::string));
|
||||
_add(new configItem("auto_reset_assets_idx", &auto_reset_assets_idx, itemType::integer));
|
||||
_add(new configItem("last_asset_reset_unix_secs", &last_asset_reset_epoch_secs, itemType::integer64));
|
||||
_add(new configItem("enable_dns_server", &enable_dns_server, itemType::boolean));
|
||||
_add(new configItem("dns_server_listen_lan", &dns_server_listen_lan, itemType::boolean));
|
||||
_add(new configItem("dns_server_listen_port", &dns_server_listen_port, itemType::integer));
|
||||
@ -389,27 +385,4 @@ namespace Configs {
|
||||
QStandardPaths::AppConfigLocation);
|
||||
return qApp->applicationDirPath();
|
||||
}
|
||||
|
||||
QString GetCoreAssetDir(const QString &name) {
|
||||
QStringList search = {
|
||||
GetBasePath(),
|
||||
QString("/usr/share/sing-geoip"),
|
||||
QString("/usr/share/sing-geosite"),
|
||||
QString("/usr/share/sing-box"),
|
||||
};
|
||||
|
||||
for (const auto &dir: search) {
|
||||
if (dir.isEmpty())
|
||||
continue;
|
||||
|
||||
if (QFile(QString("%1/%2").arg(dir, name)).exists())
|
||||
return dir;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool NeedGeoAssets(){
|
||||
return GetCoreAssetDir("geoip.db").isEmpty() || GetCoreAssetDir("geosite.db").isEmpty();
|
||||
}
|
||||
} // namespace Configs
|
||||
|
||||
@ -139,9 +139,6 @@ int main(int argc, char* argv[]) {
|
||||
if (!dir.exists(ROUTES_PREFIX_NAME)) {
|
||||
dir_success &= dir.mkdir(ROUTES_PREFIX_NAME);
|
||||
}
|
||||
if (!dir.exists(RULE_SETS_DIR)) {
|
||||
dir_success &= dir.mkdir(RULE_SETS_DIR);
|
||||
}
|
||||
if (!dir_success) {
|
||||
QMessageBox::critical(nullptr, "Error", "No permission to write " + dir.absolutePath());
|
||||
return 1;
|
||||
|
||||
@ -417,6 +417,25 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
}
|
||||
});
|
||||
|
||||
auto getRuleSet = [=,this]
|
||||
{
|
||||
QString err;
|
||||
for(int retry = 0; retry < 3; retry++) {
|
||||
auto resp = NetworkRequestHelper::HttpGet("https://raw.githubusercontent.com/throneproj/routeprofiles/rule-set/list");
|
||||
if (resp.error.isEmpty()) {
|
||||
std::vector<uint8_t> respvec;
|
||||
respvec.assign(resp.data.begin(), resp.data.end());
|
||||
auto reply = spb::pb::deserialize<libcore::RuleSet>(respvec);
|
||||
ruleSetMap = reply.items;
|
||||
return;
|
||||
}
|
||||
else
|
||||
err = resp.error;
|
||||
}
|
||||
MW_show_log(QObject::tr("Requesting rule-set error: %1").arg(err));
|
||||
};
|
||||
runOnNewThread(getRuleSet);
|
||||
|
||||
auto getRemoteRouteProfiles = [=,this]
|
||||
{
|
||||
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/throneproj/routeprofiles/releases/latest");
|
||||
@ -439,7 +458,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
|
||||
connect(ui->menuRouting_Menu, &QMenu::aboutToShow, this, [=,this]()
|
||||
{
|
||||
// refresh it on every menu show
|
||||
if(remoteRouteProfiles.isEmpty())
|
||||
runOnNewThread(getRemoteRouteProfiles);
|
||||
ui->menuRouting_Menu->clear();
|
||||
ui->menuRouting_Menu->addAction(ui->menu_routing_settings);
|
||||
@ -562,33 +581,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
connect(TM_auto_update_subsctiption, &QTimer::timeout, this, [&] { UI_update_all_groups(true); });
|
||||
TM_auto_update_subsctiption_Reset_Minute(Configs::dataStore->sub_auto_update);
|
||||
|
||||
// asset updater timer
|
||||
auto TM_auto_reset_assets = new QTimer(this);
|
||||
connect(TM_auto_reset_assets, &QTimer::timeout, this, [&]()
|
||||
{
|
||||
auto reset_interval = Configs::GeoAssets::ResetAssetsOptions[Configs::dataStore->auto_reset_assets_idx];
|
||||
if (reset_interval > 0 && QDateTime::currentSecsSinceEpoch() - Configs::dataStore->last_asset_reset_epoch_secs > reset_interval)
|
||||
{
|
||||
runOnNewThread([=,this]
|
||||
{
|
||||
ResetAssets(Configs::dataStore->geoip_download_url, Configs::dataStore->geosite_download_url);
|
||||
});
|
||||
}
|
||||
});
|
||||
TM_auto_reset_assets->start(1000 * 60 * 5); // check every 5 minutes
|
||||
|
||||
if (!Configs::dataStore->flag_tray) show();
|
||||
|
||||
if (Configs::NeedGeoAssets()) {
|
||||
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Geo Assets are missing, want to download them now?"), QMessageBox::Yes | QMessageBox::No);
|
||||
if (n == QMessageBox::Yes) {
|
||||
runOnNewThread([=,this]
|
||||
{
|
||||
DownloadAssets(!Configs::dataStore->geoip_download_url.isEmpty() ? Configs::dataStore->geoip_download_url : Configs::GeoAssets::GeoIPURLs[0],
|
||||
!Configs::dataStore->geosite_download_url.isEmpty() ? Configs::dataStore->geosite_download_url : Configs::GeoAssets::GeoSiteURLs[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
ui->data_view->setStyleSheet("background: transparent; border: none;");
|
||||
}
|
||||
|
||||
@ -721,19 +715,6 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info)
|
||||
on_menu_exit_triggered();
|
||||
}
|
||||
}
|
||||
if (info.contains("DownloadAssets")) {
|
||||
auto splitted = info.split(";");
|
||||
runOnNewThread([=,this](){
|
||||
DownloadAssets(splitted[1], splitted[2]);
|
||||
});
|
||||
}
|
||||
if (info.contains("ResetAssets"))
|
||||
{
|
||||
auto splitted = info.split(";");
|
||||
runOnNewThread([=,this](){
|
||||
ResetAssets(splitted[1], splitted[2]);
|
||||
});
|
||||
}
|
||||
//
|
||||
if (info == "RestartProgram") {
|
||||
this->exit_reason = 2;
|
||||
@ -822,7 +803,14 @@ void MainWindow::on_menu_manage_groups_triggered() {
|
||||
}
|
||||
|
||||
void MainWindow::on_menu_routing_settings_triggered() {
|
||||
USE_DIALOG(DialogManageRoutes)
|
||||
if (dialog_is_using) return;
|
||||
dialog_is_using = true;
|
||||
auto dialog = new DialogManageRoutes(this, ruleSetMap);
|
||||
connect(dialog, &QDialog::finished, this, [=,this] {
|
||||
dialog->deleteLater();
|
||||
dialog_is_using = false;
|
||||
});
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_menu_vpn_settings_triggered() {
|
||||
@ -1642,7 +1630,7 @@ void MainWindow::on_menu_export_config_triggered() {
|
||||
auto ent = ents.first();
|
||||
if (ent->bean->DisplayCoreType() != software_core_name) return;
|
||||
|
||||
auto result = BuildConfig(ent, false, true);
|
||||
auto result = BuildConfig(ent, ruleSetMap, false, true);
|
||||
QString config_core = QJsonObject2QString(result->coreConfig, true);
|
||||
QApplication::clipboard()->setText(config_core);
|
||||
|
||||
@ -1654,11 +1642,11 @@ void MainWindow::on_menu_export_config_triggered() {
|
||||
msg.setDefaultButton(QMessageBox::Ok);
|
||||
msg.exec();
|
||||
if (msg.clickedButton() == button_1) {
|
||||
result = BuildConfig(ent, false, false);
|
||||
result = BuildConfig(ent, ruleSetMap, false, false);
|
||||
config_core = QJsonObject2QString(result->coreConfig, true);
|
||||
QApplication::clipboard()->setText(config_core);
|
||||
} else if (msg.clickedButton() == button_2) {
|
||||
result = BuildConfig(ent, true, false);
|
||||
result = BuildConfig(ent, ruleSetMap, true, false);
|
||||
config_core = QJsonObject2QString(result->coreConfig, true);
|
||||
QApplication::clipboard()->setText(config_core);
|
||||
}
|
||||
@ -2298,62 +2286,6 @@ bool MainWindow::StopVPNProcess() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::DownloadAssets(const QString &geoipUrl, const QString &geositeUrl) {
|
||||
if (!mu_download_assets.tryLock()) {
|
||||
runOnUiThread([=,this](){
|
||||
MessageBoxWarning(tr("Cannot start"), tr("Last download request has not finished yet"));
|
||||
});
|
||||
return;
|
||||
}
|
||||
MW_show_log("Start downloading...");
|
||||
QString errors;
|
||||
if (!geoipUrl.isEmpty()) {
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geoipUrl, "geoip.db");
|
||||
if (!resp.isEmpty()) {
|
||||
MW_show_log(QString(tr("Failed to download geoip: %1")).arg(resp));
|
||||
errors += "geoip: " + resp;
|
||||
}
|
||||
}
|
||||
if (!geositeUrl.isEmpty()) {
|
||||
auto resp = NetworkRequestHelper::DownloadAsset(geositeUrl, "geosite.db");
|
||||
if (!resp.isEmpty()) {
|
||||
MW_show_log(QString(tr("Failed to download geosite: %1")).arg(resp));
|
||||
errors += "\ngeosite: " + resp;
|
||||
}
|
||||
}
|
||||
mu_download_assets.unlock();
|
||||
if (!errors.isEmpty()) {
|
||||
runOnUiThread([=,this](){
|
||||
MessageBoxWarning(tr("Failed to download geo assets"), errors);
|
||||
});
|
||||
}
|
||||
MW_show_log(tr("Geo Asset update completed!"));
|
||||
}
|
||||
|
||||
void MainWindow::ResetAssets(const QString& geoipUrl, const QString& geositeUrl)
|
||||
{
|
||||
if (!mu_reset_assets.try_lock())
|
||||
{
|
||||
MW_show_log(tr("A reset of assets is already in progress"));
|
||||
return;
|
||||
}
|
||||
DownloadAssets(geoipUrl, geositeUrl);
|
||||
auto entries = QDir(RULE_SETS_DIR).entryList(QDir::Files);
|
||||
for (const auto &item: entries) {
|
||||
if (!QFile(RULE_SETS_DIR + "/" + item).remove()) {
|
||||
MW_show_log("Failed to remove " + item + ", stop the core then try again");
|
||||
}
|
||||
}
|
||||
MW_show_log(tr("Removed all rule-set files"));
|
||||
|
||||
runOnUiThread([=,this]
|
||||
{
|
||||
if (Configs::dataStore->started_id >= 0) profile_start(Configs::dataStore->started_id);
|
||||
});
|
||||
Configs::dataStore->last_asset_reset_epoch_secs = QDateTime::currentSecsSinceEpoch();
|
||||
mu_reset_assets.unlock();
|
||||
}
|
||||
|
||||
bool isNewer(QString assetName) {
|
||||
if (QString(NKR_VERSION).isEmpty()) return false;
|
||||
assetName = assetName.mid(7); // take out Throne-
|
||||
|
||||
@ -141,7 +141,7 @@ void MainWindow::urltest_current_group(const QList<std::shared_ptr<Configs::Prox
|
||||
}
|
||||
|
||||
runOnNewThread([this, profiles]() {
|
||||
auto buildObject = Configs::BuildTestConfig(profiles);
|
||||
auto buildObject = Configs::BuildTestConfig(profiles, ruleSetMap);
|
||||
if (!buildObject->error.isEmpty()) {
|
||||
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
||||
speedtestRunning.unlock();
|
||||
@ -236,7 +236,7 @@ void MainWindow::speedtest_current_group(const QList<std::shared_ptr<Configs::Pr
|
||||
runOnNewThread([this, profiles, testCurrent]() {
|
||||
if (!testCurrent)
|
||||
{
|
||||
auto buildObject = Configs::BuildTestConfig(profiles);
|
||||
auto buildObject = Configs::BuildTestConfig(profiles, ruleSetMap);
|
||||
if (!buildObject->error.isEmpty()) {
|
||||
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
||||
speedtestRunning.unlock();
|
||||
@ -420,7 +420,7 @@ void MainWindow::profile_start(int _id) {
|
||||
auto group = Configs::profileManager->GetGroup(ent->gid);
|
||||
if (group == nullptr || group->archive) return;
|
||||
|
||||
auto result = BuildConfig(ent, false, false);
|
||||
auto result = BuildConfig(ent, ruleSetMap, false, false);
|
||||
if (!result->error.isEmpty()) {
|
||||
MessageBoxWarning(tr("BuildConfig return error"), result->error);
|
||||
return;
|
||||
|
||||
@ -47,7 +47,7 @@ QStringList get_all_outbounds() {
|
||||
return res;
|
||||
}
|
||||
|
||||
RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChain>& routeChain)
|
||||
RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChain>& routeChain, const std::map<std::string, std::string>& ruleSetMap)
|
||||
: QDialog(parent), ui(new Ui::RouteItem) {
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -64,10 +64,9 @@ RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChai
|
||||
}
|
||||
|
||||
// setup rule set helper
|
||||
bool ok; // for now we discard this
|
||||
auto geoIpList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::ip, Configs::GetCoreAssetDir("geoip.db"));
|
||||
auto geoSiteList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::site, Configs::GetCoreAssetDir("geosite.db"));
|
||||
geo_items << geoIpList << geoSiteList;
|
||||
for (const auto& item : ruleSetMap) {
|
||||
geo_items.append("ruleset:" + QString::fromStdString(item.first));
|
||||
}
|
||||
rule_set_editor = new AutoCompleteTextEdit("", geo_items, this);
|
||||
ui->rule_attr_data->layout()->addWidget(rule_set_editor);
|
||||
ui->rule_attr_data->adjustSize();
|
||||
@ -124,11 +123,8 @@ RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChai
|
||||
|
||||
// simple rules setup
|
||||
QStringList ruleItems = {"domain:", "suffix:", "regex:", "keyword:", "ip:", "processName:", "processPath:", "ruleset:"};
|
||||
for (const auto& geoIP : geoIpList) {
|
||||
ruleItems.append("ruleset:"+geoIP);
|
||||
}
|
||||
for (const auto& geoSite: geoSiteList) {
|
||||
ruleItems.append("ruleset:"+geoSite);
|
||||
for (const auto& item : ruleSetMap) {
|
||||
ruleItems.append("ruleset:" + QString::fromStdString(item.first));
|
||||
}
|
||||
simpleDirect = new AutoCompleteTextEdit("", ruleItems, this);
|
||||
simpleBlock = new AutoCompleteTextEdit("", ruleItems, this);
|
||||
|
||||
@ -120,33 +120,6 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
||||
// Core
|
||||
ui->groupBox_core->setTitle(software_core_name);
|
||||
|
||||
// Assets
|
||||
ui->geoip_url->setEditable(true);
|
||||
ui->geosite_url->setEditable(true);
|
||||
ui->geoip_url->addItems(Configs::GeoAssets::GeoIPURLs);
|
||||
ui->geosite_url->addItems(Configs::GeoAssets::GeoSiteURLs);
|
||||
ui->geoip_url->setCurrentText(Configs::dataStore->geoip_download_url);
|
||||
ui->geosite_url->setCurrentText(Configs::dataStore->geosite_download_url);
|
||||
ui->auto_reset->setCurrentIndex(Configs::dataStore->auto_reset_assets_idx);
|
||||
|
||||
connect(ui->download_geo_btn, &QPushButton::clicked, this, [=,this]() {
|
||||
MW_dialog_message(Dialog_DialogBasicSettings, "DownloadAssets;"+ui->geoip_url->currentText()+";"+ui->geosite_url->currentText());
|
||||
});
|
||||
connect(ui->remove_srs_btn, &QPushButton::clicked, this, [=,this](){
|
||||
auto rsDir = QDir(RULE_SETS_DIR);
|
||||
auto entries = rsDir.entryList(QDir::Files);
|
||||
for (const auto &item: entries) {
|
||||
if (!QFile(RULE_SETS_DIR + "/" + item).remove()) {
|
||||
MW_show_log("Failed to remove " + item + ", stop the core then try again");
|
||||
}
|
||||
}
|
||||
MW_show_log(tr("Removed all rule-set files"));
|
||||
});
|
||||
connect(ui->reset_assets, &QPushButton::clicked, this, [=,this]()
|
||||
{
|
||||
MW_dialog_message(Dialog_DialogBasicSettings, "ResetAssets;"+ui->geoip_url->currentText()+";"+ui->geosite_url->currentText());
|
||||
});
|
||||
|
||||
// Mux
|
||||
D_LOAD_INT(mux_concurrency)
|
||||
D_LOAD_COMBO_STRING(mux_protocol)
|
||||
@ -230,11 +203,6 @@ void DialogBasicSettings::accept() {
|
||||
// Core
|
||||
Configs::dataStore->disable_traffic_stats = ui->disable_stats->isChecked();
|
||||
|
||||
// Assets
|
||||
Configs::dataStore->geoip_download_url = ui->geoip_url->currentText();
|
||||
Configs::dataStore->geosite_download_url = ui->geosite_url->currentText();
|
||||
Configs::dataStore->auto_reset_assets_idx = ui->auto_reset->currentIndex();
|
||||
|
||||
// Mux
|
||||
D_SAVE_INT(mux_concurrency)
|
||||
D_SAVE_COMBO_STRING(mux_protocol)
|
||||
|
||||
@ -59,7 +59,7 @@ bool DialogManageRoutes::validate_dns_rules(const QString &rawString) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(new Ui::DialogManageRoutes) {
|
||||
DialogManageRoutes::DialogManageRoutes(QWidget *parent, const std::map<std::string, std::string>& dataMap) : QDialog(parent), ui(new Ui::DialogManageRoutes) {
|
||||
ui->setupUi(this);
|
||||
auto profiles = Configs::profileManager->routes;
|
||||
for (const auto &item: profiles) {
|
||||
@ -139,15 +139,10 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
||||
MessageBoxInfo("What is this?", Configs::Information::HijackInfo);
|
||||
});
|
||||
|
||||
bool ok;
|
||||
auto geoIpList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::ip, Configs::GetCoreAssetDir("geoip.db"));
|
||||
auto geoSiteList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::site, Configs::GetCoreAssetDir("geosite.db"));
|
||||
ruleSetMap = dataMap;
|
||||
QStringList ruleItems = {"domain:", "suffix:", "regex:"};
|
||||
for (const auto& geoIP : geoIpList) {
|
||||
ruleItems.append("ruleset:"+geoIP);
|
||||
}
|
||||
for (const auto& geoSite: geoSiteList) {
|
||||
ruleItems.append("ruleset:"+geoSite);
|
||||
for (const auto& item : ruleSetMap) {
|
||||
ruleItems.append("ruleset:" + QString::fromStdString(item.first));
|
||||
}
|
||||
rule_editor = new AutoCompleteTextEdit("", ruleItems, this);
|
||||
ui->hijack_box->layout()->replaceWidget(ui->dnshijack_rules, rule_editor);
|
||||
@ -235,7 +230,7 @@ void DialogManageRoutes::accept() {
|
||||
}
|
||||
|
||||
void DialogManageRoutes::on_new_route_clicked() {
|
||||
routeChainWidget = new RouteItem(this, Configs::ProfileManager::NewRouteChain());
|
||||
routeChainWidget = new RouteItem(this, Configs::ProfileManager::NewRouteChain(), ruleSetMap);
|
||||
routeChainWidget->setWindowModality(Qt::ApplicationModal);
|
||||
routeChainWidget->show();
|
||||
connect(routeChainWidget, &RouteItem::settingsChanged, this, [=,this](const std::shared_ptr<Configs::RoutingChain>& chain) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user