version.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package version
  2. import (
  3. "context"
  4. "github.com/xtls/xray-core/common"
  5. "github.com/xtls/xray-core/common/errors"
  6. "strconv"
  7. "strings"
  8. )
  9. type Version struct {
  10. config *Config
  11. ctx context.Context
  12. }
  13. func New(ctx context.Context, config *Config) (*Version, error) {
  14. if config.MinVersion != "" {
  15. result, err := compareVersions(config.MinVersion, config.CoreVersion)
  16. if err != nil {
  17. return nil, err
  18. }
  19. if result > 0 {
  20. return nil, errors.New("this config must be run on version ", config.MinVersion, " or higher")
  21. }
  22. }
  23. if config.MaxVersion != "" {
  24. result, err := compareVersions(config.MaxVersion, config.CoreVersion)
  25. if err != nil {
  26. return nil, err
  27. }
  28. if result < 0 {
  29. return nil, errors.New("this config should be run on version ", config.MaxVersion, " or lower")
  30. }
  31. }
  32. return &Version{config: config, ctx: ctx}, nil
  33. }
  34. func compareVersions(v1, v2 string) (int, error) {
  35. // Split version strings into components
  36. v1Parts := strings.Split(v1, ".")
  37. v2Parts := strings.Split(v2, ".")
  38. // Pad shorter versions with zeros
  39. for len(v1Parts) < len(v2Parts) {
  40. v1Parts = append(v1Parts, "0")
  41. }
  42. for len(v2Parts) < len(v1Parts) {
  43. v2Parts = append(v2Parts, "0")
  44. }
  45. // Compare each part
  46. for i := 0; i < len(v1Parts); i++ {
  47. // Convert parts to integers
  48. n1, err := strconv.Atoi(v1Parts[i])
  49. if err != nil {
  50. return 0, errors.New("invalid version component ", v1Parts[i], " in ", v1)
  51. }
  52. n2, err := strconv.Atoi(v2Parts[i])
  53. if err != nil {
  54. return 0, errors.New("invalid version component ", v2Parts[i], " in ", v2)
  55. }
  56. if n1 < n2 {
  57. return -1, nil // v1 < v2
  58. }
  59. if n1 > n2 {
  60. return 1, nil // v1 > v2
  61. }
  62. }
  63. return 0, nil // v1 == v2
  64. }
  65. func init() {
  66. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  67. return New(ctx, config.(*Config))
  68. }))
  69. }