config.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package config
  2. import (
  3. "github.com/cnlh/nps/lib/common"
  4. "github.com/cnlh/nps/lib/file"
  5. "regexp"
  6. "strings"
  7. )
  8. type CommonConfig struct {
  9. Server string
  10. VKey string
  11. Tp string //bridgeType kcp or tcp
  12. AutoReconnection bool
  13. Cnf *file.Config
  14. ProxyUrl string
  15. }
  16. type Config struct {
  17. content string
  18. title []string
  19. CommonConfig *CommonConfig
  20. Hosts []*file.Host
  21. Tasks []*file.Tunnel
  22. }
  23. func NewConfig(path string) (c *Config, err error) {
  24. c = new(Config)
  25. var b []byte
  26. if b, err = common.ReadAllFromFile(path); err != nil {
  27. return
  28. } else {
  29. c.content = string(b)
  30. if c.title, err = getAllTitle(c.content); err != nil {
  31. return
  32. }
  33. var nowIndex int
  34. var nextIndex int
  35. var nowContent string
  36. for i := 0; i < len(c.title); i++ {
  37. nowIndex = strings.Index(c.content, c.title[i]) + len(c.title[i])
  38. if i < len(c.title)-1 {
  39. nextIndex = strings.Index(c.content, c.title[i+1])
  40. } else {
  41. nextIndex = len(c.content)
  42. }
  43. nowContent = c.content[nowIndex:nextIndex]
  44. switch c.title[i] {
  45. case "[common]":
  46. c.CommonConfig = dealCommon(nowContent)
  47. default:
  48. if strings.Index(nowContent, "host") > -1 {
  49. h := dealHost(nowContent)
  50. h.Remark = getTitleContent(c.title[i])
  51. c.Hosts = append(c.Hosts, h)
  52. } else {
  53. t := dealTunnel(nowContent)
  54. t.Remark = getTitleContent(c.title[i])
  55. c.Tasks = append(c.Tasks, t)
  56. }
  57. }
  58. }
  59. }
  60. return
  61. }
  62. func getTitleContent(s string) string {
  63. re, _ := regexp.Compile(`[\[\]]`)
  64. return re.ReplaceAllString(s, "")
  65. }
  66. func dealCommon(s string) *CommonConfig {
  67. c := &CommonConfig{}
  68. c.Cnf = new(file.Config)
  69. for _, v := range strings.Split(s, "\n") {
  70. item := strings.Split(v, "=")
  71. if len(item) == 0 {
  72. continue
  73. } else if len(item) == 1 {
  74. item = append(item, "")
  75. }
  76. switch item[0] {
  77. case "server":
  78. c.Server = item[1]
  79. case "vkey":
  80. c.VKey = item[1]
  81. case "tp":
  82. c.Tp = item[1]
  83. case "auto_reconnection":
  84. c.AutoReconnection = common.GetBoolByStr(item[1])
  85. case "username":
  86. c.Cnf.U = item[1]
  87. case "password":
  88. c.Cnf.P = item[1]
  89. case "compress":
  90. c.Cnf.Compress = item[1]
  91. case "crypt":
  92. c.Cnf.Crypt = common.GetBoolByStr(item[1])
  93. case "proxy_socks5_url":
  94. c.ProxyUrl = item[1]
  95. }
  96. }
  97. return c
  98. }
  99. func dealHost(s string) *file.Host {
  100. h := &file.Host{}
  101. var headerChange string
  102. for _, v := range strings.Split(s, "\n") {
  103. item := strings.Split(v, "=")
  104. if len(item) == 0 {
  105. continue
  106. } else if len(item) == 1 {
  107. item = append(item, "")
  108. }
  109. switch item[0] {
  110. case "host":
  111. h.Host = item[1]
  112. case "target":
  113. h.Target = strings.Replace(item[1], ",", "\n", -1)
  114. case "host_change":
  115. h.HostChange = item[1]
  116. case "location":
  117. h.Location = item[1]
  118. default:
  119. if strings.Contains(item[0], "header") {
  120. headerChange += strings.Replace(item[0], "header_", "", -1) + ":" + item[1] + "\n"
  121. }
  122. h.HeaderChange = headerChange
  123. }
  124. }
  125. return h
  126. }
  127. func dealTunnel(s string) *file.Tunnel {
  128. t := &file.Tunnel{}
  129. for _, v := range strings.Split(s, "\n") {
  130. item := strings.Split(v, "=")
  131. if len(item) == 0 {
  132. continue
  133. } else if len(item) == 1 {
  134. item = append(item, "")
  135. }
  136. switch item[0] {
  137. case "port":
  138. t.Ports = item[1]
  139. case "mode":
  140. t.Mode = item[1]
  141. case "target":
  142. t.Target = item[1]
  143. }
  144. }
  145. return t
  146. }
  147. func getAllTitle(content string) (arr []string, err error) {
  148. var re *regexp.Regexp
  149. re, err = regexp.Compile(`\[.+?\]`)
  150. if err != nil {
  151. return
  152. }
  153. arr = re.FindAllString(content, -1)
  154. return
  155. }