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 QueryStats(EmptyReq) returns (QueryStatsResp);
|
||||||
rpc ListConnections(EmptyReq) returns (ListConnectionsResp);
|
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 SetSystemDNS(SetSystemDNSRequest) returns (EmptyResp);
|
||||||
//
|
//
|
||||||
rpc IsPrivileged(EmptyReq) returns (IsPrivilegedResponse);
|
rpc IsPrivileged(EmptyReq) returns (IsPrivilegedResponse);
|
||||||
@ -86,28 +81,6 @@ message ConnectionMetaData {
|
|||||||
optional string process = 10 [default = ""];
|
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 {
|
message SetSystemDNSRequest {
|
||||||
optional bool clear = 1 [default = false];
|
optional bool clear = 1 [default = false];
|
||||||
}
|
}
|
||||||
@ -150,3 +123,7 @@ message QuerySpeedTestResponse {
|
|||||||
message QueryURLTestResponse {
|
message QueryURLTestResponse {
|
||||||
repeated URLTestResp results = 1;
|
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/gofrs/uuid/v5 v5.3.2
|
||||||
github.com/golang/protobuf v1.5.4
|
github.com/golang/protobuf v1.5.4
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
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 v0.7.5
|
||||||
github.com/sagernet/sing-box v1.12.1
|
github.com/sagernet/sing-box v1.12.1
|
||||||
github.com/sagernet/sing-tun v0.7.0-beta.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/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 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
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 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
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=
|
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
|
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 {
|
func (s *server) IsPrivileged(in *gen.EmptyReq, out *gen.IsPrivilegedResponse) error {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
out.HasPrivilege = To(false)
|
out.HasPrivilege = To(false)
|
||||||
|
|||||||
@ -7,8 +7,6 @@
|
|||||||
#include "3rdparty/protorpc/rpc_client.h"
|
#include "3rdparty/protorpc/rpc_client.h"
|
||||||
|
|
||||||
namespace API {
|
namespace API {
|
||||||
enum GeoRuleSetType {ip, site};
|
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
explicit Client(std::function<void(const QString &)> onError, const QString &host, int port);
|
explicit Client(std::function<void(const QString &)> onError, const QString &host, int port);
|
||||||
@ -27,10 +25,6 @@ namespace API {
|
|||||||
|
|
||||||
libcore::QueryURLTestResponse QueryURLTest(bool *rpcOK);
|
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;
|
QString SetSystemDNS(bool *rpcOK, bool clear) const;
|
||||||
|
|
||||||
libcore::ListConnectionsResp ListConnections(bool *rpcOK) const;
|
libcore::ListConnectionsResp ListConnections(bool *rpcOK) const;
|
||||||
|
|||||||
@ -54,11 +54,11 @@ namespace Configs {
|
|||||||
|
|
||||||
bool IsValid(const std::shared_ptr<ProxyEntity> &ent);
|
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);
|
QJsonObject BuildDnsObject(QString address, bool tunEnabled);
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,7 @@ namespace Configs {
|
|||||||
bool IsAdmin(bool forceRenew=false);
|
bool IsAdmin(bool forceRenew=false);
|
||||||
|
|
||||||
QString GetBasePath();
|
QString GetBasePath();
|
||||||
|
|
||||||
QString GetCoreAssetDir(const QString &name);
|
|
||||||
|
|
||||||
bool NeedGeoAssets();
|
|
||||||
} // namespace Configs
|
} // namespace Configs
|
||||||
|
|
||||||
#define ROUTES_PREFIX_NAME QString("route_profiles")
|
#define ROUTES_PREFIX_NAME QString("route_profiles")
|
||||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
#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.";
|
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
|
namespace TestConfig
|
||||||
{
|
{
|
||||||
enum SpeedTestMode
|
enum SpeedTestMode
|
||||||
|
|||||||
@ -94,12 +94,6 @@ namespace Configs {
|
|||||||
bool sub_insecure = false;
|
bool sub_insecure = false;
|
||||||
int sub_auto_update = -30;
|
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
|
// Security
|
||||||
bool skip_cert = false;
|
bool skip_cert = false;
|
||||||
QString utlsFingerprint = "";
|
QString utlsFingerprint = "";
|
||||||
|
|||||||
@ -84,10 +84,6 @@ public:
|
|||||||
|
|
||||||
bool StopVPNProcess();
|
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 UpdateConnectionList(const QMap<QString, Stats::ConnectionMetadata>& toUpdate, const QMap<QString, Stats::ConnectionMetadata>& toAdd);
|
||||||
|
|
||||||
void UpdateConnectionListWithRecreate(const QList<Stats::ConnectionMetadata>& connections);
|
void UpdateConnectionListWithRecreate(const QList<Stats::ConnectionMetadata>& connections);
|
||||||
@ -196,9 +192,7 @@ private:
|
|||||||
QSemaphore sem_stopped;
|
QSemaphore sem_stopped;
|
||||||
int exit_reason = 0;
|
int exit_reason = 0;
|
||||||
//
|
//
|
||||||
QMutex mu_download_assets;
|
|
||||||
QMutex mu_download_update;
|
QMutex mu_download_update;
|
||||||
QMutex mu_reset_assets;
|
|
||||||
//
|
//
|
||||||
int toolTipID;
|
int toolTipID;
|
||||||
//
|
//
|
||||||
@ -212,6 +206,8 @@ private:
|
|||||||
libcore::SpeedTestResult currentTestResult;
|
libcore::SpeedTestResult currentTestResult;
|
||||||
DownloadProgressReport currentDownloadReport; // could use a list, but don't think can show more than one anyways
|
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;
|
QStringList remoteRouteProfiles;
|
||||||
QMutex mu_remoteRouteProfiles;
|
QMutex mu_remoteRouteProfiles;
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ class RouteItem : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
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;
|
~RouteItem() override;
|
||||||
|
|
||||||
std::shared_ptr<Configs::RoutingChain> chain;
|
std::shared_ptr<Configs::RoutingChain> chain;
|
||||||
@ -66,7 +66,7 @@ private:
|
|||||||
void updateRulePreview();
|
void updateRulePreview();
|
||||||
|
|
||||||
void updateRouteItemsView();
|
void updateRouteItemsView();
|
||||||
private slots:
|
private slots:
|
||||||
void accept() override;
|
void accept() override;
|
||||||
|
|
||||||
void on_new_route_item_clicked();
|
void on_new_route_item_clicked();
|
||||||
|
|||||||
@ -761,108 +761,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</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">
|
<widget class="QWidget" name="tab_5">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Security</string>
|
<string>Security</string>
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class DialogManageRoutes : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DialogManageRoutes(QWidget *parent = nullptr);
|
explicit DialogManageRoutes(QWidget *parent = nullptr, const std::map<std::string, std::string>& dataMap = {});
|
||||||
|
|
||||||
~DialogManageRoutes() override;
|
~DialogManageRoutes() override;
|
||||||
|
|
||||||
@ -35,6 +35,8 @@ private:
|
|||||||
|
|
||||||
int tooltipID = 0;
|
int tooltipID = 0;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> ruleSetMap;
|
||||||
|
|
||||||
void set_dns_hijack_enability(bool enable) const;
|
void set_dns_hijack_enability(bool enable) const;
|
||||||
|
|
||||||
static bool validate_dns_rules(const QString &rawString);
|
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 {
|
QString Client::SetSystemDNS(bool *rpcOK, const bool clear) const {
|
||||||
libcore::SetSystemDNSRequest request;
|
libcore::SetSystemDNSRequest request;
|
||||||
request.clear = clear;
|
request.clear = clear;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ namespace Configs {
|
|||||||
|
|
||||||
// Common
|
// 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>();
|
auto result = std::make_shared<BuildConfigResult>();
|
||||||
result->extraCoreData = std::make_shared<ExtraCoreData>();
|
result->extraCoreData = std::make_shared<ExtraCoreData>();
|
||||||
auto status = std::make_shared<BuildConfigStatus>();
|
auto status = std::make_shared<BuildConfigStatus>();
|
||||||
@ -60,7 +60,7 @@ namespace Configs {
|
|||||||
}
|
}
|
||||||
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
||||||
} else {
|
} else {
|
||||||
BuildConfigSingBox(status);
|
BuildConfigSingBox(status, ruleSetMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply custom config
|
// 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>();
|
auto results = std::make_shared<BuildTestConfigResult>();
|
||||||
|
|
||||||
QJsonArray outboundArray = {
|
QJsonArray outboundArray = {
|
||||||
@ -140,7 +140,7 @@ namespace Configs {
|
|||||||
item->latency = -1;
|
item->latency = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto res = BuildConfig(item, true, false, ++index);
|
auto res = BuildConfig(item, ruleSetMap, true, false, ++index);
|
||||||
if (!res->error.isEmpty()) {
|
if (!res->error.isEmpty()) {
|
||||||
results->error = res->error;
|
results->error = res->error;
|
||||||
return results;
|
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
|
// Prefetch
|
||||||
auto routeChain = profileManager->GetRouteChain(dataStore->routing->current_route_id);
|
auto routeChain = profileManager->GetRouteChain(dataStore->routing->current_route_id);
|
||||||
if (routeChain == nullptr) {
|
if (routeChain == nullptr) {
|
||||||
@ -656,12 +656,6 @@ namespace Configs {
|
|||||||
// custom inbound
|
// custom inbound
|
||||||
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
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
|
// manage routing section
|
||||||
auto routeObj = QJsonObject();
|
auto routeObj = QJsonObject();
|
||||||
if (dataStore->spmode_vpn) {
|
if (dataStore->spmode_vpn) {
|
||||||
@ -749,8 +743,6 @@ namespace Configs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto ruleSetArray = QJsonArray();
|
auto ruleSetArray = QJsonArray();
|
||||||
auto geoSitePath = GetCoreAssetDir("geosite.db");
|
|
||||||
auto geoIpPath = GetCoreAssetDir("geoip.db");
|
|
||||||
for (const auto &item: *neededRuleSets) {
|
for (const auto &item: *neededRuleSets) {
|
||||||
if(auto url = QUrl(item); url.isValid() && url.fileName().contains(".srs")) {
|
if(auto url = QUrl(item); url.isValid() && url.fileName().contains(".srs")) {
|
||||||
ruleSetArray += QJsonObject{
|
ruleSetArray += QJsonObject{
|
||||||
@ -761,26 +753,13 @@ namespace Configs {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
QString srsUrl = QString::fromStdString(ruleSetMap.at(item.toStdString()));
|
||||||
ruleSetArray += QJsonObject{
|
ruleSetArray += QJsonObject{
|
||||||
{"type", "local"},
|
{"type", "remote"},
|
||||||
{"tag", item},
|
{"tag", get_rule_set_name(srsUrl)},
|
||||||
{"format", "binary"},
|
{"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;
|
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_address", &ntp_server_address, itemType::string));
|
||||||
_add(new configItem("ntp_server_port", &ntp_server_port, itemType::integer));
|
_add(new configItem("ntp_server_port", &ntp_server_port, itemType::integer));
|
||||||
_add(new configItem("ntp_interval", &ntp_interval, itemType::string));
|
_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("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_lan", &dns_server_listen_lan, itemType::boolean));
|
||||||
_add(new configItem("dns_server_listen_port", &dns_server_listen_port, itemType::integer));
|
_add(new configItem("dns_server_listen_port", &dns_server_listen_port, itemType::integer));
|
||||||
@ -389,27 +385,4 @@ namespace Configs {
|
|||||||
QStandardPaths::AppConfigLocation);
|
QStandardPaths::AppConfigLocation);
|
||||||
return qApp->applicationDirPath();
|
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
|
} // namespace Configs
|
||||||
|
|||||||
@ -139,9 +139,6 @@ int main(int argc, char* argv[]) {
|
|||||||
if (!dir.exists(ROUTES_PREFIX_NAME)) {
|
if (!dir.exists(ROUTES_PREFIX_NAME)) {
|
||||||
dir_success &= dir.mkdir(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) {
|
if (!dir_success) {
|
||||||
QMessageBox::critical(nullptr, "Error", "No permission to write " + dir.absolutePath());
|
QMessageBox::critical(nullptr, "Error", "No permission to write " + dir.absolutePath());
|
||||||
return 1;
|
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 getRemoteRouteProfiles = [=,this]
|
||||||
{
|
{
|
||||||
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/throneproj/routeprofiles/releases/latest");
|
auto resp = NetworkRequestHelper::HttpGet("https://api.github.com/repos/throneproj/routeprofiles/releases/latest");
|
||||||
@ -439,8 +458,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
|
|
||||||
connect(ui->menuRouting_Menu, &QMenu::aboutToShow, this, [=,this]()
|
connect(ui->menuRouting_Menu, &QMenu::aboutToShow, this, [=,this]()
|
||||||
{
|
{
|
||||||
// refresh it on every menu show
|
if(remoteRouteProfiles.isEmpty())
|
||||||
runOnNewThread(getRemoteRouteProfiles);
|
runOnNewThread(getRemoteRouteProfiles);
|
||||||
ui->menuRouting_Menu->clear();
|
ui->menuRouting_Menu->clear();
|
||||||
ui->menuRouting_Menu->addAction(ui->menu_routing_settings);
|
ui->menuRouting_Menu->addAction(ui->menu_routing_settings);
|
||||||
mu_remoteRouteProfiles.lock();
|
mu_remoteRouteProfiles.lock();
|
||||||
@ -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); });
|
connect(TM_auto_update_subsctiption, &QTimer::timeout, this, [&] { UI_update_all_groups(true); });
|
||||||
TM_auto_update_subsctiption_Reset_Minute(Configs::dataStore->sub_auto_update);
|
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::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;");
|
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();
|
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") {
|
if (info == "RestartProgram") {
|
||||||
this->exit_reason = 2;
|
this->exit_reason = 2;
|
||||||
@ -822,7 +803,14 @@ void MainWindow::on_menu_manage_groups_triggered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_menu_routing_settings_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() {
|
void MainWindow::on_menu_vpn_settings_triggered() {
|
||||||
@ -1642,7 +1630,7 @@ void MainWindow::on_menu_export_config_triggered() {
|
|||||||
auto ent = ents.first();
|
auto ent = ents.first();
|
||||||
if (ent->bean->DisplayCoreType() != software_core_name) return;
|
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);
|
QString config_core = QJsonObject2QString(result->coreConfig, true);
|
||||||
QApplication::clipboard()->setText(config_core);
|
QApplication::clipboard()->setText(config_core);
|
||||||
|
|
||||||
@ -1654,11 +1642,11 @@ void MainWindow::on_menu_export_config_triggered() {
|
|||||||
msg.setDefaultButton(QMessageBox::Ok);
|
msg.setDefaultButton(QMessageBox::Ok);
|
||||||
msg.exec();
|
msg.exec();
|
||||||
if (msg.clickedButton() == button_1) {
|
if (msg.clickedButton() == button_1) {
|
||||||
result = BuildConfig(ent, false, false);
|
result = BuildConfig(ent, ruleSetMap, false, false);
|
||||||
config_core = QJsonObject2QString(result->coreConfig, true);
|
config_core = QJsonObject2QString(result->coreConfig, true);
|
||||||
QApplication::clipboard()->setText(config_core);
|
QApplication::clipboard()->setText(config_core);
|
||||||
} else if (msg.clickedButton() == button_2) {
|
} else if (msg.clickedButton() == button_2) {
|
||||||
result = BuildConfig(ent, true, false);
|
result = BuildConfig(ent, ruleSetMap, true, false);
|
||||||
config_core = QJsonObject2QString(result->coreConfig, true);
|
config_core = QJsonObject2QString(result->coreConfig, true);
|
||||||
QApplication::clipboard()->setText(config_core);
|
QApplication::clipboard()->setText(config_core);
|
||||||
}
|
}
|
||||||
@ -2298,62 +2286,6 @@ bool MainWindow::StopVPNProcess() {
|
|||||||
return true;
|
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) {
|
bool isNewer(QString assetName) {
|
||||||
if (QString(NKR_VERSION).isEmpty()) return false;
|
if (QString(NKR_VERSION).isEmpty()) return false;
|
||||||
assetName = assetName.mid(7); // take out Throne-
|
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]() {
|
runOnNewThread([this, profiles]() {
|
||||||
auto buildObject = Configs::BuildTestConfig(profiles);
|
auto buildObject = Configs::BuildTestConfig(profiles, ruleSetMap);
|
||||||
if (!buildObject->error.isEmpty()) {
|
if (!buildObject->error.isEmpty()) {
|
||||||
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
||||||
speedtestRunning.unlock();
|
speedtestRunning.unlock();
|
||||||
@ -236,7 +236,7 @@ void MainWindow::speedtest_current_group(const QList<std::shared_ptr<Configs::Pr
|
|||||||
runOnNewThread([this, profiles, testCurrent]() {
|
runOnNewThread([this, profiles, testCurrent]() {
|
||||||
if (!testCurrent)
|
if (!testCurrent)
|
||||||
{
|
{
|
||||||
auto buildObject = Configs::BuildTestConfig(profiles);
|
auto buildObject = Configs::BuildTestConfig(profiles, ruleSetMap);
|
||||||
if (!buildObject->error.isEmpty()) {
|
if (!buildObject->error.isEmpty()) {
|
||||||
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
MW_show_log(tr("Failed to build test config: ") + buildObject->error);
|
||||||
speedtestRunning.unlock();
|
speedtestRunning.unlock();
|
||||||
@ -420,7 +420,7 @@ void MainWindow::profile_start(int _id) {
|
|||||||
auto group = Configs::profileManager->GetGroup(ent->gid);
|
auto group = Configs::profileManager->GetGroup(ent->gid);
|
||||||
if (group == nullptr || group->archive) return;
|
if (group == nullptr || group->archive) return;
|
||||||
|
|
||||||
auto result = BuildConfig(ent, false, false);
|
auto result = BuildConfig(ent, ruleSetMap, false, false);
|
||||||
if (!result->error.isEmpty()) {
|
if (!result->error.isEmpty()) {
|
||||||
MessageBoxWarning(tr("BuildConfig return error"), result->error);
|
MessageBoxWarning(tr("BuildConfig return error"), result->error);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -47,7 +47,7 @@ QStringList get_all_outbounds() {
|
|||||||
return res;
|
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) {
|
: QDialog(parent), ui(new Ui::RouteItem) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -64,10 +64,9 @@ RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChai
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup rule set helper
|
// setup rule set helper
|
||||||
bool ok; // for now we discard this
|
for (const auto& item : ruleSetMap) {
|
||||||
auto geoIpList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::ip, Configs::GetCoreAssetDir("geoip.db"));
|
geo_items.append("ruleset:" + QString::fromStdString(item.first));
|
||||||
auto geoSiteList = API::defaultClient->GetGeoList(&ok, API::GeoRuleSetType::site, Configs::GetCoreAssetDir("geosite.db"));
|
}
|
||||||
geo_items << geoIpList << geoSiteList;
|
|
||||||
rule_set_editor = new AutoCompleteTextEdit("", geo_items, this);
|
rule_set_editor = new AutoCompleteTextEdit("", geo_items, this);
|
||||||
ui->rule_attr_data->layout()->addWidget(rule_set_editor);
|
ui->rule_attr_data->layout()->addWidget(rule_set_editor);
|
||||||
ui->rule_attr_data->adjustSize();
|
ui->rule_attr_data->adjustSize();
|
||||||
@ -124,11 +123,8 @@ RouteItem::RouteItem(QWidget *parent, const std::shared_ptr<Configs::RoutingChai
|
|||||||
|
|
||||||
// simple rules setup
|
// simple rules setup
|
||||||
QStringList ruleItems = {"domain:", "suffix:", "regex:", "keyword:", "ip:", "processName:", "processPath:", "ruleset:"};
|
QStringList ruleItems = {"domain:", "suffix:", "regex:", "keyword:", "ip:", "processName:", "processPath:", "ruleset:"};
|
||||||
for (const auto& geoIP : geoIpList) {
|
for (const auto& item : ruleSetMap) {
|
||||||
ruleItems.append("ruleset:"+geoIP);
|
ruleItems.append("ruleset:" + QString::fromStdString(item.first));
|
||||||
}
|
|
||||||
for (const auto& geoSite: geoSiteList) {
|
|
||||||
ruleItems.append("ruleset:"+geoSite);
|
|
||||||
}
|
}
|
||||||
simpleDirect = new AutoCompleteTextEdit("", ruleItems, this);
|
simpleDirect = new AutoCompleteTextEdit("", ruleItems, this);
|
||||||
simpleBlock = new AutoCompleteTextEdit("", ruleItems, this);
|
simpleBlock = new AutoCompleteTextEdit("", ruleItems, this);
|
||||||
|
|||||||
@ -120,33 +120,6 @@ DialogBasicSettings::DialogBasicSettings(QWidget *parent)
|
|||||||
// Core
|
// Core
|
||||||
ui->groupBox_core->setTitle(software_core_name);
|
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
|
// Mux
|
||||||
D_LOAD_INT(mux_concurrency)
|
D_LOAD_INT(mux_concurrency)
|
||||||
D_LOAD_COMBO_STRING(mux_protocol)
|
D_LOAD_COMBO_STRING(mux_protocol)
|
||||||
@ -230,11 +203,6 @@ void DialogBasicSettings::accept() {
|
|||||||
// Core
|
// Core
|
||||||
Configs::dataStore->disable_traffic_stats = ui->disable_stats->isChecked();
|
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
|
// Mux
|
||||||
D_SAVE_INT(mux_concurrency)
|
D_SAVE_INT(mux_concurrency)
|
||||||
D_SAVE_COMBO_STRING(mux_protocol)
|
D_SAVE_COMBO_STRING(mux_protocol)
|
||||||
|
|||||||
@ -59,7 +59,7 @@ bool DialogManageRoutes::validate_dns_rules(const QString &rawString) {
|
|||||||
return true;
|
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);
|
ui->setupUi(this);
|
||||||
auto profiles = Configs::profileManager->routes;
|
auto profiles = Configs::profileManager->routes;
|
||||||
for (const auto &item: profiles) {
|
for (const auto &item: profiles) {
|
||||||
@ -139,15 +139,10 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) : QDialog(parent), ui(ne
|
|||||||
MessageBoxInfo("What is this?", Configs::Information::HijackInfo);
|
MessageBoxInfo("What is this?", Configs::Information::HijackInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
bool ok;
|
ruleSetMap = dataMap;
|
||||||
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"));
|
|
||||||
QStringList ruleItems = {"domain:", "suffix:", "regex:"};
|
QStringList ruleItems = {"domain:", "suffix:", "regex:"};
|
||||||
for (const auto& geoIP : geoIpList) {
|
for (const auto& item : ruleSetMap) {
|
||||||
ruleItems.append("ruleset:"+geoIP);
|
ruleItems.append("ruleset:" + QString::fromStdString(item.first));
|
||||||
}
|
|
||||||
for (const auto& geoSite: geoSiteList) {
|
|
||||||
ruleItems.append("ruleset:"+geoSite);
|
|
||||||
}
|
}
|
||||||
rule_editor = new AutoCompleteTextEdit("", ruleItems, this);
|
rule_editor = new AutoCompleteTextEdit("", ruleItems, this);
|
||||||
ui->hijack_box->layout()->replaceWidget(ui->dnshijack_rules, rule_editor);
|
ui->hijack_box->layout()->replaceWidget(ui->dnshijack_rules, rule_editor);
|
||||||
@ -235,7 +230,7 @@ void DialogManageRoutes::accept() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DialogManageRoutes::on_new_route_clicked() {
|
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->setWindowModality(Qt::ApplicationModal);
|
||||||
routeChainWidget->show();
|
routeChainWidget->show();
|
||||||
connect(routeChainWidget, &RouteItem::settingsChanged, this, [=,this](const std::shared_ptr<Configs::RoutingChain>& chain) {
|
connect(routeChainWidget, &RouteItem::settingsChanged, this, [=,this](const std::shared_ptr<Configs::RoutingChain>& chain) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user