github.com/kelleygo/clashcore@v1.0.2/component/geodata/standard/standard.go (about)

     1  package standard
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/kelleygo/clashcore/component/geodata"
    10  	"github.com/kelleygo/clashcore/component/geodata/router"
    11  	C "github.com/kelleygo/clashcore/constant"
    12  
    13  	"google.golang.org/protobuf/proto"
    14  )
    15  
    16  func ReadFile(path string) ([]byte, error) {
    17  	reader, err := os.Open(path)
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  	defer func(reader *os.File) {
    22  		_ = reader.Close()
    23  	}(reader)
    24  
    25  	return io.ReadAll(reader)
    26  }
    27  
    28  func ReadAsset(file string) ([]byte, error) {
    29  	return ReadFile(C.Path.GetAssetLocation(file))
    30  }
    31  
    32  func loadIP(geoipBytes []byte, country string) ([]*router.CIDR, error) {
    33  	var geoipList router.GeoIPList
    34  	if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	for _, geoip := range geoipList.Entry {
    39  		if strings.EqualFold(geoip.CountryCode, country) {
    40  			return geoip.Cidr, nil
    41  		}
    42  	}
    43  
    44  	return nil, fmt.Errorf("country %s not found", country)
    45  }
    46  
    47  func loadSite(geositeBytes []byte, list string) ([]*router.Domain, error) {
    48  	var geositeList router.GeoSiteList
    49  	if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	for _, site := range geositeList.Entry {
    54  		if strings.EqualFold(site.CountryCode, list) {
    55  			return site.Domain, nil
    56  		}
    57  	}
    58  
    59  	return nil, fmt.Errorf("list %s not found", list)
    60  }
    61  
    62  type standardLoader struct{}
    63  
    64  func (d standardLoader) LoadSiteByPath(filename, list string) ([]*router.Domain, error) {
    65  	geositeBytes, err := ReadAsset(filename)
    66  	if err != nil {
    67  		return nil, fmt.Errorf("failed to open file: %s, base error: %s", filename, err.Error())
    68  	}
    69  	return loadSite(geositeBytes, list)
    70  }
    71  
    72  func (d standardLoader) LoadSiteByBytes(geositeBytes []byte, list string) ([]*router.Domain, error) {
    73  	return loadSite(geositeBytes, list)
    74  }
    75  
    76  func (d standardLoader) LoadIPByPath(filename, country string) ([]*router.CIDR, error) {
    77  	geoipBytes, err := ReadAsset(filename)
    78  	if err != nil {
    79  		return nil, fmt.Errorf("failed to open file: %s, base error: %s", filename, err.Error())
    80  	}
    81  	return loadIP(geoipBytes, country)
    82  }
    83  
    84  func (d standardLoader) LoadIPByBytes(geoipBytes []byte, country string) ([]*router.CIDR, error) {
    85  	return loadIP(geoipBytes, country)
    86  }
    87  
    88  func init() {
    89  	geodata.RegisterGeoDataLoaderImplementationCreator("standard", func() geodata.LoaderImplementation {
    90  		return standardLoader{}
    91  	})
    92  }