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 }