github.com/yaling888/clash@v1.53.0/component/geodata/standard/standard.go (about) 1 package standard 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 9 "google.golang.org/protobuf/proto" 10 11 "github.com/yaling888/clash/component/geodata" 12 "github.com/yaling888/clash/component/geodata/router" 13 C "github.com/yaling888/clash/constant" 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.Resolve(file)) 30 } 31 32 func loadIP(filename, country string) ([]*router.CIDR, error) { 33 geoipBytes, err := ReadAsset(filename) 34 if err != nil { 35 return nil, fmt.Errorf("failed to open file: %s, base error: %w", filename, err) 36 } 37 var geoipList router.GeoIPList 38 if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil { 39 return nil, err 40 } 41 42 for _, geoip := range geoipList.Entry { 43 if strings.EqualFold(geoip.CountryCode, country) { 44 return geoip.Cidr, nil 45 } 46 } 47 48 return nil, fmt.Errorf("country not found in %s%s%s", filename, ": ", country) 49 } 50 51 func loadSite(filename, list string) ([]*router.Domain, error) { 52 geositeBytes, err := ReadAsset(filename) 53 if err != nil { 54 return nil, fmt.Errorf("failed to open file: %s, base error: %w", filename, err) 55 } 56 var geositeList router.GeoSiteList 57 if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil { 58 return nil, err 59 } 60 61 for _, site := range geositeList.Entry { 62 if strings.EqualFold(site.CountryCode, list) { 63 return site.Domain, nil 64 } 65 } 66 67 return nil, fmt.Errorf("list not found in %s%s%s", filename, ": ", list) 68 } 69 70 type standardLoader struct{} 71 72 func (d standardLoader) LoadSite(filename, list string) ([]*router.Domain, error) { 73 return loadSite(filename, list) 74 } 75 76 func (d standardLoader) LoadIP(filename, country string) ([]*router.CIDR, error) { 77 return loadIP(filename, country) 78 } 79 80 func init() { 81 geodata.RegisterGeoDataLoaderImplementationCreator("standard", func() geodata.LoaderImplementation { 82 return standardLoader{} 83 }) 84 }