function.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package core
  2. import (
  3. "fmt"
  4. "net/url"
  5. "os"
  6. "regexp"
  7. "runtime"
  8. "strings"
  9. "time"
  10. "github.com/beego/beego/v2/core/logs"
  11. cron "github.com/robfig/cron/v3"
  12. )
  13. var c *cron.Cron
  14. func init() {
  15. if runtime.GOOS != "windows" {
  16. pname = regexp.MustCompile(`/([^/\s]+)$`).FindStringSubmatch(os.Args[0])[1]
  17. }
  18. c = cron.New()
  19. c.Start()
  20. }
  21. type Function struct {
  22. Rules []string
  23. FindAll bool
  24. Admin bool
  25. Handle func(s Sender) interface{}
  26. Cron string
  27. }
  28. var pname = ""
  29. var name = func() string {
  30. return sillyGirl.Get("name", "傻妞")
  31. }
  32. var functions = []Function{}
  33. var Senders chan Sender
  34. func initToHandleMessage() {
  35. Senders = make(chan Sender)
  36. go func() {
  37. for {
  38. go handleMessage(<-Senders)
  39. }
  40. }()
  41. }
  42. func AddCommand(prefix string, cmds []Function) {
  43. for j := range cmds {
  44. for i := range cmds[j].Rules {
  45. if strings.Contains(cmds[j].Rules[i], "raw ") {
  46. cmds[j].Rules[i] = strings.Replace(cmds[j].Rules[i], "raw ", "", -1)
  47. continue
  48. }
  49. cmds[j].Rules[i] = strings.ReplaceAll(cmds[j].Rules[i], `\r\a\w`, "raw")
  50. if strings.Contains(cmds[j].Rules[i], "$") {
  51. continue
  52. }
  53. if prefix != "" {
  54. cmds[j].Rules[i] = prefix + `\s+` + cmds[j].Rules[i]
  55. }
  56. cmds[j].Rules[i] = strings.Replace(cmds[j].Rules[i], "(", `[(]`, -1)
  57. cmds[j].Rules[i] = strings.Replace(cmds[j].Rules[i], ")", `[)]`, -1)
  58. cmds[j].Rules[i] = regexp.MustCompile(`\?$`).ReplaceAllString(cmds[j].Rules[i], `(.+)`)
  59. cmds[j].Rules[i] = strings.Replace(cmds[j].Rules[i], " ", `\s+`, -1)
  60. cmds[j].Rules[i] = strings.Replace(cmds[j].Rules[i], "?", `(\S+)`, -1)
  61. cmds[j].Rules[i] = "^" + cmds[j].Rules[i] + "$"
  62. }
  63. functions = append(functions, cmds[j])
  64. if cmds[j].Cron != "" {
  65. cmd := cmds[j]
  66. if _, err := c.AddFunc(cmds[j].Cron, func() {
  67. cmd.Handle(&Faker{})
  68. }); err != nil {
  69. // logs.Warn("任务%v添加失败%v", cmds[j].Rules[0], err)
  70. } else {
  71. // logs.Warn("任务%v添加成功", cmds[j].Rules[0])
  72. }
  73. }
  74. }
  75. }
  76. func handleMessage(sender Sender) {
  77. defer sender.Finish()
  78. recall := sillyGirl.Get("recall")
  79. if recall != "" {
  80. recalled := false
  81. for _, v := range strings.Split(recall, "&") {
  82. reg, err := regexp.Compile(v)
  83. if err == nil {
  84. if reg.FindString(sender.GetContent()) != "" {
  85. if !sender.IsAdmin() && sender.GetImType() != "wx" {
  86. sender.Delete()
  87. sender.Reply("本妞清除了不好的消息~", time.Duration(time.Second))
  88. recalled = true
  89. break
  90. }
  91. }
  92. }
  93. }
  94. if recalled == true {
  95. return
  96. }
  97. }
  98. defer func() {
  99. logs.Info("%v ==> %v", sender.GetContent(), "finished")
  100. }()
  101. u, g, i := fmt.Sprint(sender.GetUserID()), fmt.Sprint(sender.GetChatID()), fmt.Sprint(sender.GetImType())
  102. con := true
  103. mtd := false
  104. waits.Range(func(k, v interface{}) bool {
  105. c := v.(*Carry)
  106. vs, _ := url.ParseQuery(k.(string))
  107. userID := vs.Get("u")
  108. chatID := vs.Get("c")
  109. imType := vs.Get("i")
  110. forGroup := vs.Get("f")
  111. if imType != i {
  112. return true
  113. }
  114. if chatID != g {
  115. return true
  116. }
  117. if userID != u && forGroup == "" {
  118. return true
  119. }
  120. if m := regexp.MustCompile(c.Pattern).FindString(sender.GetContent()); m != "" {
  121. mtd = true
  122. c.Chan <- sender
  123. sender.Reply(<-c.Result)
  124. if !sender.IsContinue() {
  125. con = false
  126. return false
  127. }
  128. }
  129. return true
  130. })
  131. if mtd && !con {
  132. return
  133. }
  134. // if v, ok := waits.Load(key); ok {
  135. // c := v.(*Carry)
  136. // if m := regexp.MustCompile(c.Pattern).FindString(sender.GetContent()); m != "" {
  137. // c.Chan <- sender
  138. // sender.Reply(<-c.Result)
  139. // return
  140. // }
  141. // }
  142. for _, function := range functions {
  143. for _, rule := range function.Rules {
  144. var matched bool
  145. if function.FindAll {
  146. if res := regexp.MustCompile(rule).FindAllStringSubmatch(sender.GetContent(), -1); len(res) > 0 {
  147. tmp := [][]string{}
  148. for i := range res {
  149. tmp = append(tmp, res[i][1:])
  150. }
  151. sender.SetAllMatch(tmp)
  152. matched = true
  153. }
  154. } else {
  155. if res := regexp.MustCompile(rule).FindStringSubmatch(sender.GetContent()); len(res) > 0 {
  156. sender.SetMatch(res[1:])
  157. matched = true
  158. }
  159. }
  160. if matched {
  161. logs.Info("%v ==> %v", sender.GetContent(), rule)
  162. if function.Admin && !sender.IsAdmin() {
  163. sender.Delete()
  164. sender.Disappear()
  165. // if sender.GetImType() != "wx" && sender.GetImType() != "qq" {
  166. sender.Reply("再捣乱我就报警啦~")
  167. // }
  168. return
  169. }
  170. rt := function.Handle(sender)
  171. if rt != nil {
  172. sender.Reply(rt)
  173. }
  174. if sender.IsContinue() {
  175. goto goon
  176. }
  177. return
  178. }
  179. }
  180. goon:
  181. }
  182. reply.Foreach(func(k, v []byte) error {
  183. if string(v) == "" {
  184. return nil
  185. }
  186. reg, err := regexp.Compile(string(k))
  187. if err == nil {
  188. if reg.FindString(sender.GetContent()) != "" {
  189. sender.Reply(string(v))
  190. }
  191. }
  192. return nil
  193. })
  194. }
  195. func FetchCookieValue(ps ...string) string {
  196. var key, cookies string
  197. if len(ps) == 2 {
  198. if len(ps[0]) > len(ps[1]) {
  199. key, cookies = ps[1], ps[0]
  200. } else {
  201. key, cookies = ps[0], ps[1]
  202. }
  203. }
  204. match := regexp.MustCompile(key + `=([^;]*);{0,1}`).FindStringSubmatch(cookies)
  205. if len(match) == 2 {
  206. return match[1]
  207. } else {
  208. return ""
  209. }
  210. }