feat: Add GeoAutoUpdate and GeoUpdateInterval to config (#857)

This commit is contained in:
Kuingsmile 2023-12-03 07:10:09 -08:00 committed by wwqgtxx
parent 5f493fbcfb
commit aef87b29ba
6 changed files with 91 additions and 26 deletions

View file

@ -55,6 +55,8 @@ type General struct {
Interface string `json:"interface-name"`
RoutingMark int `json:"-"`
GeoXUrl GeoXUrl `json:"geox-url"`
GeoAutoUpdate bool `json:"geo-auto-update"`
GeoUpdateInterval int `json:"geo-update-interval"`
GeodataMode bool `json:"geodata-mode"`
GeodataLoader string `json:"geodata-loader"`
TCPConcurrent bool `json:"tcp-concurrent"`
@ -298,6 +300,8 @@ type RawConfig struct {
Interface string `yaml:"interface-name"`
RoutingMark int `yaml:"routing-mark"`
Tunnels []LC.Tunnel `yaml:"tunnels"`
GeoAutoUpdate bool `yaml:"geo-auto-update" json:"geo-auto-update"`
GeoUpdateInterval int `yaml:"geo-update-interval" json:"geo-update-interval"`
GeodataMode bool `yaml:"geodata-mode" json:"geodata-mode"`
GeodataLoader string `yaml:"geodata-loader" json:"geodata-loader"`
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
@ -377,22 +381,24 @@ func Parse(buf []byte) (*Config, error) {
func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
// config with default value
rawCfg := &RawConfig{
AllowLan: false,
BindAddress: "*",
IPv6: true,
Mode: T.Rule,
GeodataMode: C.GeodataMode,
GeodataLoader: "memconservative",
UnifiedDelay: false,
Authentication: []string{},
LogLevel: log.INFO,
Hosts: map[string]any{},
Rule: []string{},
Proxy: []map[string]any{},
ProxyGroup: []map[string]any{},
TCPConcurrent: false,
FindProcessMode: P.FindProcessStrict,
GlobalUA: "clash.meta",
AllowLan: false,
BindAddress: "*",
IPv6: true,
Mode: T.Rule,
GeoAutoUpdate: false,
GeoUpdateInterval: 24,
GeodataMode: C.GeodataMode,
GeodataLoader: "memconservative",
UnifiedDelay: false,
Authentication: []string{},
LogLevel: log.INFO,
Hosts: map[string]any{},
Rule: []string{},
Proxy: []map[string]any{},
ProxyGroup: []map[string]any{},
TCPConcurrent: false,
FindProcessMode: P.FindProcessStrict,
GlobalUA: "clash.meta",
Tun: RawTun{
Enable: false,
Device: "",
@ -590,6 +596,8 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
func parseGeneral(cfg *RawConfig) (*General, error) {
geodata.SetLoader(cfg.GeodataLoader)
C.GeoAutoUpdate = cfg.GeoAutoUpdate
C.GeoUpdateInterval = cfg.GeoUpdateInterval
C.GeoIpUrl = cfg.GeoXUrl.GeoIp
C.GeoSiteUrl = cfg.GeoXUrl.GeoSite
C.MmdbUrl = cfg.GeoXUrl.Mmdb
@ -652,6 +660,8 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
Interface: cfg.Interface,
RoutingMark: cfg.RoutingMark,
GeoXUrl: cfg.GeoXUrl,
GeoAutoUpdate: cfg.GeoAutoUpdate,
GeoUpdateInterval: cfg.GeoUpdateInterval,
GeodataMode: cfg.GeodataMode,
GeodataLoader: cfg.GeodataLoader,
TCPConcurrent: cfg.TCPConcurrent,

View file

@ -28,7 +28,7 @@ func UpdateGeoDatabases() error {
return fmt.Errorf("invalid GeoIP database file: %s", err)
}
if saveFile(data, C.Path.GeoIP()) != nil {
if err = saveFile(data, C.Path.GeoIP()); err != nil {
return fmt.Errorf("can't save GeoIP database file: %w", err)
}
@ -43,8 +43,7 @@ func UpdateGeoDatabases() error {
return fmt.Errorf("invalid MMDB database file: %s", err)
}
_ = instance.Close()
if saveFile(data, C.Path.MMDB()) != nil {
if err = saveFile(data, C.Path.MMDB()); err != nil {
return fmt.Errorf("can't save MMDB database file: %w", err)
}
}
@ -58,7 +57,7 @@ func UpdateGeoDatabases() error {
return fmt.Errorf("invalid GeoSite database file: %s", err)
}
if saveFile(data, C.Path.GeoSite()) != nil {
if err = saveFile(data, C.Path.GeoSite()); err != nil {
return fmt.Errorf("can't save GeoSite database file: %w", err)
}

View file

@ -40,7 +40,7 @@ func UpdateUI() error {
}
saved := path.Join(C.Path.HomeDir(), "download.zip")
if saveFile(data, saved) != nil {
if err = saveFile(data, saved); err != nil {
return fmt.Errorf("can't save zip file: %w", err)
}
defer os.Remove(saved)

View file

@ -1,8 +1,10 @@
package constant
var (
GeodataMode bool
GeoIpUrl string
MmdbUrl string
GeoSiteUrl string
GeodataMode bool
GeoAutoUpdate bool
GeoUpdateInterval int
GeoIpUrl string
MmdbUrl string
GeoSiteUrl string
)

View file

@ -28,6 +28,9 @@ geox-url:
geosite: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat"
mmdb: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb"
geo-auto-update: false # 是否自动更新 geodata
geo-update-interval: 24 # 更新间隔,单位:小时
log-level: debug # 日志等级 silent/error/warning/info/debug
ipv6: true # 开启 IPv6 总开关,关闭阻断所有 IPv6 链接和屏蔽 DNS 请求 AAAA 记录

53
main.go
View file

@ -3,16 +3,18 @@ package main
import (
"flag"
"fmt"
"github.com/metacubex/mihomo/constant/features"
"os"
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"
"github.com/metacubex/mihomo/config"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
"github.com/metacubex/mihomo/hub"
"github.com/metacubex/mihomo/hub/executor"
"github.com/metacubex/mihomo/log"
@ -29,6 +31,8 @@ var (
externalUI string
externalController string
secret string
updateGeoMux sync.Mutex
updatingGeo = false
)
func init() {
@ -107,6 +111,17 @@ func main() {
log.Fatalln("Parse config error: %s", err.Error())
}
if C.GeoAutoUpdate {
ticker := time.NewTicker(time.Duration(C.GeoUpdateInterval) * time.Hour)
log.Infoln("[GEO] Start update GEO database every %d hours", C.GeoUpdateInterval)
go func() {
for range ticker.C {
updateGeoDatabases()
}
}()
}
defer executor.Shutdown()
termSign := make(chan os.Signal, 1)
@ -126,3 +141,39 @@ func main() {
}
}
}
func updateGeoDatabases() {
log.Infoln("[GEO] Start updating GEO database")
updateGeoMux.Lock()
if updatingGeo {
updateGeoMux.Unlock()
log.Infoln("[GEO] GEO database is updating, skip")
return
}
updatingGeo = true
updateGeoMux.Unlock()
go func() {
defer func() {
updatingGeo = false
}()
log.Infoln("[GEO] Updating GEO database")
if err := config.UpdateGeoDatabases(); err != nil {
log.Errorln("[GEO] update GEO database error: %s", err.Error())
return
}
cfg, err := executor.ParseWithPath(C.Path.Config())
if err != nil {
log.Errorln("[GEO] update GEO database failed: %s", err.Error())
return
}
log.Infoln("[GEO] Update GEO database success, apply new config")
executor.ApplyConfig(cfg, false)
}()
}