github.com/kelleygo/clashcore@v1.0.2/config/update_geo.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  
     7  	"github.com/kelleygo/clashcore/component/geodata"
     8  	_ "github.com/kelleygo/clashcore/component/geodata/standard"
     9  	"github.com/kelleygo/clashcore/component/mmdb"
    10  	C "github.com/kelleygo/clashcore/constant"
    11  
    12  	"github.com/oschwald/maxminddb-golang"
    13  )
    14  
    15  func UpdateGeoDatabases() error {
    16  	defer runtime.GC()
    17  	geoLoader, err := geodata.GetGeoDataLoader("standard")
    18  	if err != nil {
    19  		return err
    20  	}
    21  
    22  	if C.GeodataMode {
    23  		data, err := downloadForBytes(C.GeoIpUrl)
    24  		if err != nil {
    25  			return fmt.Errorf("can't download GeoIP database file: %w", err)
    26  		}
    27  
    28  		if _, err = geoLoader.LoadIPByBytes(data, "cn"); err != nil {
    29  			return fmt.Errorf("invalid GeoIP database file: %s", err)
    30  		}
    31  
    32  		if err = saveFile(data, C.Path.GeoIP()); err != nil {
    33  			return fmt.Errorf("can't save GeoIP database file: %w", err)
    34  		}
    35  
    36  	} else {
    37  		defer mmdb.ReloadIP()
    38  		data, err := downloadForBytes(C.MmdbUrl)
    39  		if err != nil {
    40  			return fmt.Errorf("can't download MMDB database file: %w", err)
    41  		}
    42  
    43  		instance, err := maxminddb.FromBytes(data)
    44  		if err != nil {
    45  			return fmt.Errorf("invalid MMDB database file: %s", err)
    46  		}
    47  		_ = instance.Close()
    48  
    49  		mmdb.IPInstance().Reader.Close() //  mmdb is loaded with mmap, so it needs to be closed before overwriting the file
    50  		if err = saveFile(data, C.Path.MMDB()); err != nil {
    51  			return fmt.Errorf("can't save MMDB database file: %w", err)
    52  		}
    53  	}
    54  
    55  	if C.ASNEnable {
    56  		defer mmdb.ReloadASN()
    57  		data, err := downloadForBytes(C.ASNUrl)
    58  		if err != nil {
    59  			return fmt.Errorf("can't download ASN database file: %w", err)
    60  		}
    61  
    62  		instance, err := maxminddb.FromBytes(data)
    63  		if err != nil {
    64  			return fmt.Errorf("invalid ASN database file: %s", err)
    65  		}
    66  		_ = instance.Close()
    67  
    68  		mmdb.ASNInstance().Reader.Close()
    69  		if err = saveFile(data, C.Path.ASN()); err != nil {
    70  			return fmt.Errorf("can't save ASN database file: %w", err)
    71  		}
    72  	}
    73  
    74  	data, err := downloadForBytes(C.GeoSiteUrl)
    75  	if err != nil {
    76  		return fmt.Errorf("can't download GeoSite database file: %w", err)
    77  	}
    78  
    79  	if _, err = geoLoader.LoadSiteByBytes(data, "cn"); err != nil {
    80  		return fmt.Errorf("invalid GeoSite database file: %s", err)
    81  	}
    82  
    83  	if err = saveFile(data, C.Path.GeoSite()); err != nil {
    84  		return fmt.Errorf("can't save GeoSite database file: %w", err)
    85  	}
    86  
    87  	geodata.ClearCache()
    88  
    89  	return nil
    90  }