Files
chen08209 2fa2f7f816 feat(core): bind the Android Core with gomobile
Changelog: Share link import and mrs rule sets
2026-10-11 12:28:52 +08:00

107 lines
2.8 KiB
Go

package core
import (
"fmt"
"strings"
"github.com/metacubex/mihomo/component/geodata"
"github.com/metacubex/mihomo/component/updater"
"github.com/metacubex/mihomo/log"
)
type geoResource struct {
update func() error
url func() string
setUrl func(string)
}
var geoResources = map[string]geoResource{
"MMDB": {update: updater.UpdateMMDB, url: geodata.MmdbUrl, setUrl: geodata.SetMmdbUrl},
"ASN": {update: updater.UpdateASN, url: geodata.ASNUrl, setUrl: geodata.SetASNUrl},
"GEOIP": {update: updater.UpdateGeoIp, url: geodata.GeoIpUrl, setUrl: geodata.SetGeoIpUrl},
"GEOSITE": {update: updater.UpdateGeoSite, url: geodata.GeoSiteUrl, setUrl: geodata.SetGeoSiteUrl},
}
// mihomo's updaters read these links without a lock, so an unchanged one is never rewritten.
func setGeoResourceUrl(geoType string, link string) {
resource, exist := geoResources[strings.ToUpper(geoType)]
if !exist {
log.Warnln("geox-url: unknown geo resource %q", geoType)
return
}
if link != "" && link != resource.url() {
resource.setUrl(link)
}
}
func claimGeoUpdate(geoType string) bool {
return claimUpdate(geoUpdateScope + geoType)
}
func releaseGeoUpdate(geoType string) {
releaseUpdate(geoUpdateScope + geoType)
}
func handleUpdateGeoData(geoType string) error {
resource, exist := geoResources[geoType]
if !exist {
logError("updateGeoData: unknown geo resource %q", geoType)
return fmt.Errorf("unknown geo resource: %s", geoType)
}
if !claimGeoUpdate(geoType) {
return fmt.Errorf("geo update already in progress: %s", geoType)
}
safeGo("updateGeoData("+geoType+")", func() {
defer releaseGeoUpdate(geoType)
if err := resource.update(); err != nil {
logError("updateGeoData(%s) error: %v", geoType, err)
}
})
return nil
}
func onGeoUpdate(geoType string, updating bool, skipped bool, updateErr error) {
if updating {
claimUpdateAs(geoUpdateScope+geoType, true)
} else {
releaseHookUpdate(geoUpdateScope + geoType)
scheduleReclaimOwnership()
if !skipped && updateErr == nil {
bumpRouteEpoch()
}
}
status := GeoUpdateStatus{Type: geoType, Updating: updating, Skipped: skipped}
if updateErr != nil {
status.Error = updateErr.Error()
}
sendMessage(GeoUpdateMessage, status)
}
var (
registerGeoUpdater = updater.RegisterGeoUpdaterWithCancel
stopGeoUpdater = updater.StopGeoUpdater
)
func syncGeoUpdater(autoUpdate *bool, interval *int) {
changed := false
if autoUpdate != nil && *autoUpdate != updater.GeoAutoUpdate() {
updater.SetGeoAutoUpdate(*autoUpdate)
changed = true
}
if interval != nil && *interval != updater.GeoUpdateInterval() {
updater.SetGeoUpdateInterval(*interval)
changed = true
}
if changed {
reconcileGeoUpdater()
}
}
func reconcileGeoUpdater() {
if updater.GeoAutoUpdate() {
registerGeoUpdater()
return
}
stopGeoUpdater()
}