function.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. package core
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strings"
  6. "sync"
  7. "sync/atomic"
  8. "time"
  9. "github.com/cdle/sillyplus/core/common"
  10. "github.com/cdle/sillyplus/core/logs"
  11. "github.com/cdle/sillyplus/core/storage"
  12. "github.com/cdle/sillyplus/utils"
  13. "github.com/goccy/go-json"
  14. )
  15. // var replyRe = regexp.MustCompile(`\$\{\s*([^\s{}]+)\s*\}`)
  16. var total uint64 = 0
  17. var finished uint64 = 0
  18. var contents sync.Map
  19. var Functions = []*common.Function{}
  20. var Messages chan common.Sender
  21. var ListenOnGroups sync.Map
  22. var NoListenUsers sync.Map
  23. var NoReplyGroups sync.Map
  24. var StaticListenOnGroups sync.Map
  25. var StaticNoReplyGroups sync.Map
  26. var noListenUsers = MakeBucket("noListenUsers")
  27. var listenOnGroups = MakeBucket("listenOnGroups")
  28. var noReplyGroups = MakeBucket("noReplyGroups")
  29. type GroupInfo struct {
  30. Platform string `json:"platform"`
  31. Desc string `json:"desc"`
  32. Enable bool `json:"enable"`
  33. }
  34. var AddNoReplyGroups = func(code string, desc string, plt string) {
  35. _, loaded := NoReplyGroups.LoadOrStore(code, plt)
  36. if !loaded {
  37. // logs.Info(desc)
  38. }
  39. }
  40. var AddListenOnGroup = func(code string, desc string, plt string) {
  41. _, loaded := ListenOnGroups.LoadOrStore(code, plt)
  42. if !loaded {
  43. // logs.Info(desc)
  44. }
  45. }
  46. var RemNoReplyGroups = func(code string, desc string) {
  47. _, loaded := NoReplyGroups.Load(code)
  48. if loaded {
  49. NoReplyGroups.Delete(code)
  50. // logs.Info(desc)
  51. }
  52. }
  53. var RemListenOnGroup = func(code string, desc string) {
  54. _, loaded := ListenOnGroups.Load(code)
  55. if loaded {
  56. ListenOnGroups.Delete(code)
  57. // logs.Info(desc)
  58. }
  59. }
  60. var IsNoReplyGroup = func(s common.Sender) bool {
  61. cid := s.GetChatID()
  62. if utils.IsZeroOrEmpty(cid) {
  63. return false
  64. }
  65. _, ok1 := NoReplyGroups.Load(cid)
  66. _, ok2 := StaticNoReplyGroups.Load(cid)
  67. res := ok1 || ok2
  68. if res {
  69. logs.Info("禁言的群组 %v/%v@%v", s.GetImType(), s.GetUserID(), cid)
  70. }
  71. return res
  72. }
  73. func initListenReply() {
  74. listenOnGroups.Foreach(func(b1, data []byte) error {
  75. groupCode := string(b1)
  76. info := &GroupInfo{}
  77. err := json.Unmarshal(data, info)
  78. if err != nil {
  79. listenOnGroups.Set(groupCode, "")
  80. } else {
  81. if info.Enable {
  82. StaticListenOnGroups.Store(string(b1), info.Platform)
  83. }
  84. }
  85. return nil
  86. })
  87. storage.Watch(listenOnGroups, nil, func(old, new, key string) (fin *storage.Final) {
  88. if new == "" {
  89. logs.Info("已删除监听群组%s", key)
  90. StaticListenOnGroups.Delete(key)
  91. return
  92. }
  93. info := &GroupInfo{}
  94. json.Unmarshal([]byte(new), info)
  95. if info.Enable {
  96. StaticListenOnGroups.Store(key, info.Platform)
  97. logs.Info("已设置监听群组%s/%s", info.Platform, key)
  98. } else {
  99. StaticListenOnGroups.Delete(key)
  100. logs.Info("已取消监听群组%s/%s", info.Platform, key)
  101. }
  102. return
  103. })
  104. noReplyGroups.Foreach(func(b1, data []byte) error {
  105. groupCode := string(b1)
  106. info := &GroupInfo{}
  107. err := json.Unmarshal(data, info)
  108. if err != nil {
  109. noReplyGroups.Set(groupCode, "")
  110. } else {
  111. info := &GroupInfo{}
  112. json.Unmarshal(data, info)
  113. if info.Enable {
  114. StaticNoReplyGroups.Store(string(b1), info.Platform)
  115. }
  116. }
  117. return nil
  118. })
  119. storage.Watch(noReplyGroups, nil, func(old, new, key string) (fin *storage.Final) {
  120. if new == "" {
  121. logs.Info("已删除禁言群组%s", key)
  122. StaticNoReplyGroups.Delete(key)
  123. return
  124. }
  125. info := &GroupInfo{}
  126. json.Unmarshal([]byte(new), info)
  127. if info.Enable {
  128. logs.Info("已设置禁言群组%s/%s", info.Platform, key)
  129. StaticNoReplyGroups.Store(key, info.Platform)
  130. } else {
  131. logs.Info("已取消禁言群组%s%s", info.Platform, key)
  132. StaticNoReplyGroups.Delete(key)
  133. }
  134. return
  135. })
  136. noListenUsers.Foreach(func(b1, data []byte) error {
  137. groupCode := string(b1)
  138. info := &GroupInfo{}
  139. err := json.Unmarshal(data, info)
  140. if err != nil {
  141. noListenUsers.Set(groupCode, "")
  142. } else {
  143. info := &GroupInfo{}
  144. json.Unmarshal(data, info)
  145. // fmt.Println(string(b1), string(utils.JsonMarshal(info)))
  146. if info.Enable {
  147. NoListenUsers.Store(string(b1), info.Platform)
  148. }
  149. }
  150. return nil
  151. })
  152. storage.Watch(noListenUsers, nil, func(old, new, key string) (fin *storage.Final) {
  153. if new == "" {
  154. logs.Info("已取消屏蔽用户%s", key)
  155. NoListenUsers.Delete(key)
  156. return
  157. }
  158. info := &GroupInfo{}
  159. json.Unmarshal([]byte(new), info)
  160. if info.Enable {
  161. logs.Info("已屏蔽用户%s/%s", info.Platform, key)
  162. NoListenUsers.Store(key, info.Platform)
  163. } else {
  164. logs.Info("已取消屏蔽用户%s%s", info.Platform, key)
  165. NoListenUsers.Delete(key)
  166. }
  167. return
  168. })
  169. }
  170. func initToHandleMessage() {
  171. listen_admin := sillyGirl.GetBool("listen_admin", true)
  172. storage.Watch(sillyGirl, "listen_admin", func(old, new, key string) *storage.Final {
  173. if new == "false" {
  174. listen_admin = false
  175. }
  176. return nil
  177. })
  178. Messages = make(chan common.Sender)
  179. go func() {
  180. for {
  181. s := <-Messages
  182. ignore := false
  183. cid := s.GetChatID()
  184. uid := s.GetUserID()
  185. imType := s.GetImType()
  186. isAdmin := s.IsAdmin()
  187. uname := s.GetUserName()
  188. ctt := s.GetContent()
  189. if !utils.IsZeroOrEmpty(cid) {
  190. cname := s.GetChatName()
  191. if cname != "" {
  192. CreateNickName(&Nickname{
  193. ID: cid,
  194. Group: true,
  195. Value: cname,
  196. Platform: imType,
  197. BotsID: []string{s.GetBotID()},
  198. })
  199. }
  200. if isAdmin {
  201. switch ctt {
  202. case "listen":
  203. if data := listenOnGroups.GetBytes(cid); len(data) == 0 {
  204. listenOnGroups.Set(cid, utils.JsonMarshal(&GroupInfo{
  205. Platform: imType,
  206. Enable: true,
  207. Desc: s.GetChatName(),
  208. }))
  209. } else {
  210. info := &GroupInfo{}
  211. json.Unmarshal(data, info)
  212. if !info.Enable {
  213. info.Enable = !info.Enable
  214. listenOnGroups.Set(cid, utils.JsonMarshal(info))
  215. }
  216. }
  217. s.Reply("ok")
  218. case "unlisten", "nolisten":
  219. if data := listenOnGroups.GetBytes(cid); len(data) != 0 {
  220. info := &GroupInfo{}
  221. json.Unmarshal(data, info)
  222. if info.Enable {
  223. info.Enable = !info.Enable
  224. listenOnGroups.Set(cid, utils.JsonMarshal(info))
  225. }
  226. }
  227. s.Reply("ok")
  228. case "reply":
  229. // if data := noReplyGroups.GetBytes(cid); len(data) != 0 {
  230. info := &GroupInfo{}
  231. // if info.Enable {
  232. // info.Enable = !info.Enable
  233. noReplyGroups.Set(cid, utils.JsonMarshal(info))
  234. // }
  235. // }
  236. s.Reply("ok")
  237. case "noreply", "unreply":
  238. if data := noReplyGroups.GetBytes(cid); len(data) == 0 {
  239. noReplyGroups.Set(cid, utils.JsonMarshal(&GroupInfo{
  240. Platform: imType,
  241. Enable: true,
  242. Desc: s.GetChatName(),
  243. }))
  244. } else {
  245. info := &GroupInfo{}
  246. json.Unmarshal(data, info)
  247. if !info.Enable {
  248. info.Enable = !info.Enable
  249. noReplyGroups.Set(cid, utils.JsonMarshal(info))
  250. }
  251. }
  252. s.Reply("ok")
  253. }
  254. }
  255. _, ok1 := ListenOnGroups.Load(cid)
  256. if !ok1 {
  257. if !listen_admin || !isAdmin {
  258. _, ok2 := StaticListenOnGroups.Load(cid)
  259. if !ok2 {
  260. ignore = true
  261. }
  262. }
  263. }
  264. } else {
  265. if isAdmin {
  266. switch ctt {
  267. case "unlisten", "nolisten":
  268. if data := noListenUsers.GetBytes(uid); len(data) == 0 {
  269. noListenUsers.Set(uid, utils.JsonMarshal(&GroupInfo{
  270. Platform: imType,
  271. Enable: true,
  272. Desc: s.GetChatName(),
  273. }))
  274. } else {
  275. info := &GroupInfo{}
  276. json.Unmarshal(data, info)
  277. if !info.Enable {
  278. info.Enable = !info.Enable
  279. noListenUsers.Set(uid, utils.JsonMarshal(info))
  280. }
  281. }
  282. s.Reply("ok")
  283. case "listen":
  284. if data := noListenUsers.GetBytes(uid); len(data) != 0 {
  285. info := &GroupInfo{}
  286. json.Unmarshal(data, info)
  287. if info.Enable {
  288. info.Enable = !info.Enable
  289. noListenUsers.Set(uid, utils.JsonMarshal(info))
  290. }
  291. }
  292. s.Reply("ok")
  293. }
  294. }
  295. }
  296. _, ok2 := NoListenUsers.Load(uid)
  297. if ok2 {
  298. ignore = true
  299. }
  300. if uname != "" {
  301. CreateNickName(&Nickname{
  302. ID: uid,
  303. Group: false,
  304. Value: uname,
  305. Platform: imType,
  306. BotsID: []string{s.GetBotID()},
  307. })
  308. }
  309. if imType != "terminal" {
  310. if !ignore {
  311. logs.Info("接收到消息 %v/%v@%v:%s", imType, uid, cid, ctt)
  312. } else {
  313. logs.Info("屏蔽的消息 %v/%v@%v:%s", imType, uid, cid, ctt)
  314. }
  315. }
  316. if ignore {
  317. continue
  318. }
  319. go HandleMessage(s)
  320. }
  321. }()
  322. }
  323. func fmtRule(cmd *common.Function) {
  324. for i := range cmd.Rules {
  325. cmd.Rules[i] = strings.Trim(cmd.Rules[i], "")
  326. cmd.Params = append(cmd.Params, []string{})
  327. if strings.HasPrefix(cmd.Rules[i], "raw") {
  328. cmd.Rules[i] = strings.Replace(cmd.Rules[i], "raw ", "", -1)
  329. continue
  330. }
  331. if strings.HasPrefix(cmd.Rules[i], "^") {
  332. continue
  333. }
  334. if strings.HasSuffix(cmd.Rules[i], "$") {
  335. continue
  336. }
  337. cmd.Rules[i] = strings.ReplaceAll(cmd.Rules[i], `\r\a\w`, "raw")
  338. cmd.Rules[i] = strings.Replace(cmd.Rules[i], "(", `[(]`, -1)
  339. cmd.Rules[i] = strings.Replace(cmd.Rules[i], ")", `[)]`, -1)
  340. ress := regexp.MustCompile(`\[([^\s\[\]]+)\]`).FindAllStringSubmatch(cmd.Rules[i], -1)
  341. for _, res := range ress {
  342. var inner = res[1]
  343. vv := strings.SplitN(inner, ":", 2)
  344. name := vv[0]
  345. if len(vv) == 1 {
  346. cmd.Rules[i] = strings.ReplaceAll(cmd.Rules[i], res[0], "?")
  347. } else {
  348. cmd.Rules[i] = strings.ReplaceAll(cmd.Rules[i], res[0], fmt.Sprintf("(%s)", strings.ReplaceAll(vv[1], ",", "|")))
  349. }
  350. cmd.Params[i] = append(cmd.Params[i], name)
  351. }
  352. cmd.Rules[i] = regexp.MustCompile(`\?$`).ReplaceAllString(cmd.Rules[i], `([\s\S]+)`)
  353. cmd.Rules[i] = strings.Replace(cmd.Rules[i], " ", `\s+`, -1)
  354. cmd.Rules[i] = strings.Replace(cmd.Rules[i], "?", `(\S+)`, -1)
  355. cmd.Rules[i] = "^" + cmd.Rules[i] + "$"
  356. }
  357. }
  358. func AddCommand(cmds []*common.Function) {
  359. for j := range cmds {
  360. if cmds[j].OnStart && !cmds[j].Disable {
  361. go func(f *common.Function) {
  362. time.Sleep(time.Second)
  363. // console.Log("初始化%v服务", f.Title)
  364. f.Handle(&CustomSender{
  365. F: &Factory{
  366. botplt: "*",
  367. },
  368. }, nil)
  369. }(cmds[j])
  370. }
  371. fmtRule(cmds[j])
  372. {
  373. if !cmds[j].Disable && !cmds[j].Module {
  374. for plt, Cron := range cmds[j].Cron {
  375. plt := plt
  376. cron := strings.TrimSpace(Cron)
  377. if len(regexp.MustCompile(`\S+`).FindAllString(cron, -1)) == 5 {
  378. Cron = "0 " + Cron
  379. }
  380. cronId, err := CRON.AddFunc(Cron, func() {
  381. cmds[j].Handle(&CustomSender{
  382. F: &Factory{
  383. botplt: plt,
  384. },
  385. }, nil)
  386. })
  387. if err == nil {
  388. cmds[j].CronIds = append(cmds[j].CronIds, int(cronId))
  389. // console["log"]("脚本%s添加定时器", cmds[j].Title)
  390. } else {
  391. console.Error("脚本%s定时器错误,%v", cmds[j].Title, err)
  392. }
  393. }
  394. }
  395. // if cmds[j].Cron != "" && !cmds[j].Disable && !cmds[j].Module && !cmds[j].OnStart {
  396. // }
  397. }
  398. {
  399. lf := len(Functions)
  400. for i := range Functions {
  401. f := lf - i - 1
  402. if Functions[f].Priority > cmds[j].Priority {
  403. Functions = append(Functions[:f+1], append([]*common.Function{cmds[j]}, Functions[f+1:]...)...)
  404. break
  405. }
  406. }
  407. if len(Functions) == lf {
  408. if lf > 0 {
  409. apd := false
  410. for i := range Functions {
  411. if cmds[j].Priority >= Functions[i].Priority {
  412. apd = true
  413. Functions = append(Functions[:i], append([]*common.Function{cmds[j]}, Functions[i:]...)...)
  414. break
  415. }
  416. }
  417. if !apd {
  418. Functions = append(Functions, cmds[j])
  419. }
  420. } else {
  421. Functions = append(Functions, cmds[j])
  422. }
  423. }
  424. }
  425. }
  426. }
  427. func HandleMessage(sender common.Sender) {
  428. if !debug {
  429. defer func() {
  430. err := recover()
  431. if err != nil {
  432. console.Error("HandleMessage error: %v", err)
  433. }
  434. }()
  435. }
  436. num := atomic.AddUint64(&total, 1)
  437. defer atomic.AddUint64(&finished, 1)
  438. ct := sender.GetContent()
  439. contents.Store(num, ct)
  440. defer func() {
  441. contents.Delete(num)
  442. }()
  443. content := utils.TrimHiddenCharacter(ct)
  444. defer func() {
  445. sender.Finish()
  446. if sender.IsAtLast() {
  447. s := sender.MessagesToSend()
  448. if s != "" {
  449. sender.Reply(s)
  450. }
  451. }
  452. }()
  453. u, g, i, a := sender.GetUserID(), sender.GetChatID(), sender.GetImType(), sender.IsAdmin()
  454. con := true
  455. mtd := false
  456. for _, wait := range waits {
  457. wait.Foreach(func(k int64, c *Carry) bool {
  458. // userID := vs.Get("u")
  459. // chatID := vs.Get("c")
  460. // imType := vs.Get("i")
  461. // forGroup := vs.Get("f")
  462. // if chatID != g && (forGroup != "me" || g != "0") {
  463. // return true
  464. // }
  465. // if userID != u && (forGroup == "" || forGroup == "me") {
  466. // return true
  467. // }
  468. if c.RequireAdmin && !a {
  469. return true
  470. }
  471. // fmt.Println(c.Function.Rules, "==", c.AllowPlatforms, len(c.AllowPlatforms))
  472. if len(c.AllowPlatforms) != 0 && !Contains(c.AllowPlatforms, i) {
  473. return true
  474. }
  475. // fmt.Println(c.Function.Rules)
  476. if len(c.ProhibitPlatforms) != 0 && Contains(c.ProhibitPlatforms, i) {
  477. return true
  478. }
  479. if len(c.AllowUsers) != 0 && !Contains(c.AllowUsers, u) {
  480. return true
  481. }
  482. if len(c.ProhibitUsers) != 0 && Contains(c.ProhibitUsers, u) {
  483. return true
  484. }
  485. if len(c.AllowGroups) != 0 && !Contains(c.AllowGroups, g) {
  486. return true
  487. }
  488. if len(c.ProhibitGroups) != 0 && Contains(c.ProhibitGroups, g) {
  489. return true
  490. }
  491. // if c.ChatID != g && (!c.AllowPrivate || g != "") {
  492. // return true
  493. // }
  494. // if c.UserID != u && (c.AllowGroupUsers || c.AllowPrivate) {
  495. // return true
  496. // }
  497. if c.ChatID != "" { //群聊监听
  498. if g == "" { //私聊时
  499. if !c.ListenPrivate { //如果未设置允许私聊则拒绝
  500. return true
  501. }
  502. } else { //群聊时
  503. if c.UserID != "" && u != c.UserID { //群员发言
  504. if !c.ListenGroup { //未设置允许群员加入拒绝
  505. return true
  506. }
  507. }
  508. }
  509. } else { //私聊监听
  510. if c.UserID != "" && u != c.UserID { //其他用户
  511. return true
  512. }
  513. }
  514. for i := range c.Function.Rules {
  515. reg, err := regexp.Compile(c.Function.Rules[i])
  516. if err != nil {
  517. console.Error("监听器正则错误,%v", err)
  518. continue
  519. }
  520. // logs.Info("%s规则:%s", c.Function.Title, c.Function.Rules[i])
  521. if res := reg.FindStringSubmatch(content); len(res) > 0 {
  522. logs.Info("匹配到%s规则:%s", c.Function.Title, c.Function.Rules[i])
  523. sender.SetMatch(res[1:])
  524. sender.SetParams(c.Function.Params[i])
  525. mtd = true
  526. c.Chan <- sender
  527. sender.Reply(<-c.Result)
  528. if !sender.IsContinue() {
  529. con = false
  530. return false
  531. }
  532. sender.ClearContinue()
  533. break
  534. }
  535. }
  536. return true
  537. })
  538. }
  539. if mtd && !con {
  540. return
  541. }
  542. for _, reply := range replies {
  543. if reply.Keyword == "" || reply.Value == "" {
  544. continue
  545. }
  546. if reply.Number != "" && reply.Number != u && reply.Number != g {
  547. continue
  548. }
  549. if len(reply.Platforms) != 0 && !Contains(reply.Platforms, i) {
  550. continue
  551. }
  552. // if reply.Class == 1 && g != "" {
  553. // continue
  554. // } else if reply.Class == 2 && g == "" {
  555. // continue
  556. // }
  557. reg, err := regexp.Compile(reply.Keyword)
  558. if err == nil {
  559. if reg.FindString(content) != "" {
  560. //todo 支持JS语法
  561. output := parseReply2(reply.Value)
  562. sender.Reply(output)
  563. }
  564. }
  565. }
  566. for _, function := range Functions {
  567. if function.Disable || function.Module {
  568. continue
  569. }
  570. imType := sender.GetImType()
  571. if (imType != "cron" && imType != "carry" && black(function.ImType, imType)) || black(function.UserId, sender.GetUserID()) || black(function.GroupId, fmt.Sprint(sender.GetChatID())) {
  572. continue
  573. }
  574. for i := range function.Rules {
  575. var matched bool
  576. if function.FindAll {
  577. reg, err := regexp.Compile(function.Rules[i])
  578. if err != nil {
  579. console.Error("脚本%s正则错误,%v", function.Title, err)
  580. continue
  581. }
  582. if res := reg.FindAllStringSubmatch(content, -1); len(res) > 0 {
  583. tmp := [][]string{}
  584. for i := range res {
  585. tmp = append(tmp, res[i][1:])
  586. }
  587. if !function.Hidden {
  588. logs.Info("匹配到规则:%s", function.Rules[i])
  589. }
  590. sender.SetAllMatch(tmp)
  591. matched = true
  592. }
  593. } else {
  594. reg, err := regexp.Compile(function.Rules[i])
  595. if err != nil {
  596. console.Error("脚本%s正则错误,%v", function.Title, err)
  597. continue
  598. }
  599. if res := reg.FindStringSubmatch(content); len(res) > 0 {
  600. if !function.Hidden {
  601. logs.Info("匹配到规则:%s", function.Rules[i])
  602. }
  603. sender.SetMatch(res[1:])
  604. sender.SetParams(function.Params[i])
  605. matched = true
  606. }
  607. }
  608. if matched {
  609. if function.Admin && !a {
  610. return
  611. }
  612. rt := function.Handle(sender, nil)
  613. if rt != nil {
  614. sender.Reply(rt)
  615. }
  616. if sender.IsContinue() {
  617. sender.ClearContinue()
  618. content = utils.TrimHiddenCharacter(sender.GetContent())
  619. if !function.Hidden {
  620. logs.Info("继续去处理:%s", content)
  621. }
  622. goto next
  623. }
  624. return
  625. }
  626. }
  627. next:
  628. }
  629. recall := sillyGirl.GetString("recall")
  630. if recall != "" {
  631. recalled := false
  632. for _, v := range strings.Split(recall, "&") {
  633. reg, err := regexp.Compile(v)
  634. if err == nil {
  635. if reg.FindString(content) != "" {
  636. if !a && sender.GetImType() != "wx" {
  637. sender.Delete()
  638. recalled = true
  639. break
  640. }
  641. }
  642. }
  643. }
  644. if recalled {
  645. return
  646. }
  647. }
  648. }
  649. func black(filter *common.Filter, str string) bool {
  650. if filter != nil {
  651. if filter.BlackMode {
  652. if utils.Contains(filter.Items, str) {
  653. return true
  654. }
  655. } else {
  656. if !utils.Contains(filter.Items, str) {
  657. return true
  658. }
  659. }
  660. }
  661. return false
  662. }