standard.go 2.3 KB

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