plugin_impl.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. package core
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "regexp"
  9. "strings"
  10. "time"
  11. "github.com/cdle/sillyplus/core/common"
  12. "github.com/cdle/sillyplus/core/logs"
  13. "github.com/cdle/sillyplus/proto3/srpc"
  14. "github.com/cdle/sillyplus/utils"
  15. "github.com/dop251/goja"
  16. // "golang.org/x/image/webp"
  17. )
  18. var sleep = func(i int) {
  19. time.Sleep(time.Duration(i) * time.Millisecond)
  20. }
  21. func GetScriptNameByUUID(uuid string) string {
  22. for _, f := range Functions {
  23. if f.UUID == uuid {
  24. return fmt.Sprintf("%s%s", f.Title, f.Suffix)
  25. }
  26. }
  27. return "未知脚本"
  28. }
  29. type SenderJsIplm struct {
  30. Message common.Sender
  31. Private string
  32. Group string
  33. Routine string
  34. Persistent string
  35. Vm *goja.Runtime
  36. UUID string
  37. NewContent bool
  38. }
  39. type Console struct {
  40. UUID string
  41. }
  42. var console = &Console{}
  43. var Logs = &Console{}
  44. func (sg *SillyGirlService) Console(ctx context.Context, req *srpc.ConsoleRequest) (*srpc.Empty, error) {
  45. log := &Console{
  46. UUID: req.PluginId,
  47. }
  48. switch req.Type {
  49. case "info", "log":
  50. log.Info(req.Content)
  51. case "error":
  52. log.Error(req.Content)
  53. case "debug":
  54. log.Debug(req.Content)
  55. }
  56. return &srpc.Empty{}, nil
  57. }
  58. func pluginConsole(uuid string) *Console {
  59. return &Console{
  60. UUID: uuid,
  61. }
  62. }
  63. func Broadcast2WebUser(content, class string) {
  64. if (RegistFuncs["Broadcast2WebUser"]) == nil {
  65. return
  66. }
  67. RegistFuncs["Broadcast2WebUser"].(func(string, string))(content, class)
  68. }
  69. func (c *Console) Info(v ...interface{}) {
  70. if len(v) == 0 {
  71. return
  72. }
  73. log := utils.FormatLog(v[0], v[1:]...)
  74. logs.Info(log)
  75. Broadcast2WebUser(log, "info")
  76. }
  77. func (c *Console) Debug(v ...interface{}) {
  78. if len(v) == 0 {
  79. return
  80. }
  81. if c.UUID != "" {
  82. if plugin_debug.GetString(c.UUID) != "b:true" {
  83. return
  84. }
  85. }
  86. log := utils.FormatLog(v[0], v[1:]...)
  87. logs.Debug(log)
  88. Broadcast2WebUser(log, "debug")
  89. }
  90. func (c *Console) Warn(v ...interface{}) {
  91. if len(v) == 0 {
  92. return
  93. }
  94. log := utils.FormatLog(v[0], v[1:]...)
  95. logs.Warn(log)
  96. WritePluginMessage(c.UUID, "warn", log)
  97. Broadcast2WebUser(log, "warn")
  98. }
  99. func (c *Console) Error(v ...interface{}) {
  100. if len(v) == 0 {
  101. return
  102. }
  103. log := utils.FormatLog(v[0], v[1:]...)
  104. logs.Error(log)
  105. WritePluginMessage(c.UUID, "error", log)
  106. Broadcast2WebUser(log, "error")
  107. }
  108. func (c *Console) Log(v ...interface{}) {
  109. if len(v) == 0 {
  110. return
  111. }
  112. log := utils.FormatLog(v[0], v[1:]...)
  113. logs.Info(log)
  114. Broadcast2WebUser(log, "log")
  115. }
  116. func (sender *SenderJsIplm) Continue() {
  117. if sender.NewContent {
  118. go func() {
  119. Messages <- sender.Message
  120. }()
  121. return
  122. }
  123. sender.Message.Continue()
  124. }
  125. func (sender *SenderJsIplm) GetUserID() string {
  126. return sender.Message.GetUserID()
  127. }
  128. func (sender *SenderJsIplm) GetBotID() string {
  129. return sender.Message.GetBotID()
  130. }
  131. func (sender *SenderJsIplm) GetBotId() string {
  132. return sender.Message.GetBotID()
  133. }
  134. func (sender *SenderJsIplm) GetUserId() string {
  135. return sender.Message.GetUserID()
  136. }
  137. func (sender *SenderJsIplm) SetContent(s string) {
  138. if s != sender.GetContent() {
  139. sender.NewContent = true
  140. }
  141. sender.Message.SetContent(s)
  142. }
  143. func (sender *SenderJsIplm) GetContent() string {
  144. return sender.Message.GetContent()
  145. }
  146. func (sender *SenderJsIplm) GetImType() string {
  147. return sender.Message.GetImType()
  148. }
  149. func (sender *SenderJsIplm) GetPlatform() string {
  150. return sender.Message.GetImType()
  151. }
  152. func (sender *SenderJsIplm) RecallMessage(p ...interface{}) {
  153. sender.Message.RecallMessage(p...)
  154. }
  155. func (sender *SenderJsIplm) GetUserName() string {
  156. return sender.Message.GetUserName()
  157. }
  158. func (sender *SenderJsIplm) GetUsername() string {
  159. return sender.Message.GetUserName()
  160. }
  161. func (sender *SenderJsIplm) GetReplyUserID() int {
  162. return sender.Message.GetReplyUserID()
  163. }
  164. func (sender *SenderJsIplm) GetReplyUserId() int {
  165. return sender.Message.GetReplyUserID()
  166. }
  167. func (sender *SenderJsIplm) GetLevel() int {
  168. return sender.Message.GetLevel()
  169. }
  170. func (sender *SenderJsIplm) SetLevel(l int) {
  171. sender.Message.SetLevel(l)
  172. }
  173. func (sender *SenderJsIplm) GetChatName() string {
  174. return sender.Message.GetChatName()
  175. }
  176. func (sender *SenderJsIplm) GetMessageID() string {
  177. return sender.Message.GetMessageID()
  178. }
  179. func (sender *SenderJsIplm) GetMessageId() string {
  180. return sender.Message.GetMessageID()
  181. }
  182. func (sender *SenderJsIplm) GetGroupCode() string {
  183. return sender.Message.GetChatID()
  184. }
  185. func (sender *SenderJsIplm) GetChatID() string {
  186. return sender.Message.GetChatID()
  187. }
  188. func (sender *SenderJsIplm) GetChatId() string {
  189. return sender.Message.GetChatID()
  190. }
  191. func (sender *SenderJsIplm) Kick(uid string) interface{} {
  192. err := sender.Message.GroupKick(uid, false)
  193. if err != nil {
  194. return err.Error()
  195. }
  196. return nil
  197. }
  198. func (sender *SenderJsIplm) Unkick(uid string) interface{} {
  199. err := sender.Message.GroupUnkick(uid)
  200. if err != nil {
  201. return err.Error()
  202. }
  203. return nil
  204. }
  205. func (sender *SenderJsIplm) Ban(uid string, duration int) interface{} {
  206. err := sender.Message.GroupBan(uid, duration)
  207. if err != nil {
  208. return err.Error()
  209. }
  210. return nil
  211. }
  212. func (sender *SenderJsIplm) Param(i interface{}) string {
  213. switch i := i.(type) {
  214. case int:
  215. return sender.Message.Get(i - 1)
  216. case int64:
  217. return sender.Message.Get(int(i - 1))
  218. case string:
  219. return sender.Message.Get(i)
  220. }
  221. return ""
  222. }
  223. func (sender *SenderJsIplm) GetAllMatch() [][]string {
  224. return sender.Message.GetAllMatch()
  225. }
  226. func (sender *SenderJsIplm) Params(i int) []string {
  227. if i == 0 {
  228. i = 1
  229. }
  230. ss := []string{}
  231. for _, v := range sender.Message.GetAllMatch() {
  232. ss = append(ss, v[i-1])
  233. }
  234. return ss
  235. }
  236. // GetAllMatch
  237. func (Sender *SenderJsIplm) Get(i interface{}) string {
  238. return Sender.Param(i)
  239. }
  240. func (Sender *SenderJsIplm) GetVar(key string) interface{} {
  241. return Sender.Message.GetVar(key)
  242. }
  243. func (Sender *SenderJsIplm) SetVar(key string, value interface{}) {
  244. Sender.Message.SetVar(key, value)
  245. }
  246. func (Sender *SenderJsIplm) SetVars(kvs map[string]interface{}) {
  247. for k, v := range kvs {
  248. Sender.SetVar(k, v)
  249. }
  250. }
  251. func (Sender *SenderJsIplm) GetVars() map[string]interface{} {
  252. return Sender.Message.GetExpandMessageInfo()
  253. }
  254. func (sender *SenderJsIplm) IsAdmin() bool {
  255. return sender.Message.IsAdmin()
  256. }
  257. func (sender *SenderJsIplm) Action(options map[string]interface{}) interface{} {
  258. result, err := sender.Message.Action(options)
  259. return map[string]interface{}{
  260. "result": result,
  261. "error": err,
  262. }
  263. }
  264. func (sender *SenderJsIplm) DoAction(options map[string]interface{}) interface{} {
  265. return sender.Action(options)
  266. }
  267. func (sender *SenderJsIplm) Reply(texts ...interface{}) interface{} {
  268. i, err := sender.Message.Reply(texts...)
  269. var errstr interface{}
  270. if err != nil {
  271. // panic(Error(sender.Vm, err))
  272. errstr = err.Error()
  273. }
  274. return map[string]interface{}{
  275. "message_id": i,
  276. "error": errstr,
  277. }
  278. }
  279. func (sender *SenderJsIplm) HoldOn(str ...string) string {
  280. if len(str) != 0 {
  281. return "go_again_" + str[0]
  282. }
  283. return "go_again_"
  284. }
  285. func arrayss(i interface{}) []string {
  286. var ss = []string{}
  287. for _, v := range i.([]interface{}) {
  288. ss = append(ss, v.(string))
  289. }
  290. return ss
  291. }
  292. func (sender *SenderJsIplm) Listen(ps ...interface{}) interface{} {
  293. // promise, resolve, reject := vm.NewPromise()
  294. options := []interface{}{}
  295. var handle func(goja.FunctionCall) goja.Value
  296. var persistent = sender.Message.GetImType() == "*"
  297. var routine = persistent
  298. var carry = &Carry{}
  299. // var sustainable = false
  300. // rs := []string{}
  301. for _, p := range ps {
  302. switch p := p.(type) {
  303. case map[string]interface{}:
  304. props := p
  305. for i, p := range props {
  306. switch strings.ToLower(i) {
  307. case "rules":
  308. vs := p.([]interface{})
  309. for _, v := range vs {
  310. rule := v.(string)
  311. _rs := formatRule(rule)
  312. if len(_rs) != 0 {
  313. carry.Function.Rules = append(carry.Function.Rules, _rs...)
  314. } else {
  315. carry.Function.Rules = append(carry.Function.Rules, rule)
  316. }
  317. }
  318. case "timeout":
  319. options = append(options, time.Duration(utils.Int(p))*time.Millisecond)
  320. case "handle":
  321. handle = p.(func(goja.FunctionCall) goja.Value)
  322. case "listen_private", "private":
  323. carry.ListenPrivate = p.(bool)
  324. case "listen_group", "group":
  325. carry.ListenGroup = p.(bool)
  326. case "require_admin", "admin":
  327. carry.RequireAdmin = p.(bool)
  328. case "allow_platforms":
  329. carry.AllowPlatforms = arrayss(p)
  330. case "prohibit_platforms":
  331. carry.ProhibitPlatforms = arrayss(p)
  332. case "allow_groups":
  333. carry.AllowGroups = arrayss(p)
  334. case "allow_users":
  335. carry.AllowUsers = arrayss(p)
  336. case "prohibt_groups":
  337. carry.ProhibitGroups = arrayss(p)
  338. case "prohibt_users":
  339. carry.ProhibitUsers = arrayss(p)
  340. case "user_id":
  341. carry.UserID = p.(string)
  342. case "chat_id":
  343. carry.ChatID = p.(string)
  344. case "platform":
  345. carry.AllowPlatforms = []string{p.(string)}
  346. }
  347. }
  348. case bool:
  349. case []interface{}:
  350. for i := range p {
  351. rule := p[i].(string)
  352. _rs := formatRule(rule)
  353. if len(_rs) != 0 {
  354. carry.Function.Rules = append(carry.Function.Rules, _rs...)
  355. } else {
  356. carry.Function.Rules = append(carry.Function.Rules, rule)
  357. }
  358. }
  359. case string:
  360. if p == "private" {
  361. carry.ListenPrivate = true
  362. continue
  363. }
  364. if p == "group" {
  365. carry.ListenGroup = true
  366. continue
  367. }
  368. if p == "routine" {
  369. routine = true
  370. continue
  371. }
  372. if p == "persistent" {
  373. persistent = true
  374. continue
  375. }
  376. // if p == "sustainable" {
  377. // persistent = false
  378. // sustainable = true
  379. // continue
  380. // }
  381. carry.Function.Rules = append(carry.Function.Rules, p)
  382. case int, int64, int32:
  383. options = append(options, time.Duration(utils.Int(p))*time.Millisecond)
  384. case func(goja.FunctionCall) goja.Value:
  385. handle = p
  386. }
  387. }
  388. if persistent {
  389. options = append(options, "persistent")
  390. } else if len(carry.AllowPlatforms) == 0 {
  391. carry.AllowPlatforms = []string{sender.GetPlatform()}
  392. }
  393. if carry.UserID == "" {
  394. carry.UserID = sender.GetUserID()
  395. }
  396. if carry.ChatID == "" {
  397. carry.ChatID = sender.GetChatID()
  398. }
  399. carry.UUID = sender.UUID
  400. options = append(options, carry)
  401. var newJsSender *SenderJsIplm
  402. var await = func() {
  403. sender.Message.Await(sender.Message, func(newSender common.Sender) interface{} {
  404. newSender.SetLevel(sender.Message.GetLevel() + 1)
  405. newJsSender = &SenderJsIplm{
  406. UUID: sender.UUID,
  407. Vm: sender.Vm,
  408. }
  409. newJsSender.Message = newSender
  410. if handle != nil {
  411. if persistent {
  412. func() {
  413. defer func() {
  414. err := recover()
  415. if err != nil {
  416. pluginConsole(sender.UUID).Error("%v at %v", err, GetScriptNameByUUID(sender.UUID))
  417. }
  418. }()
  419. // fmt.Println(newJsSender)
  420. rt := handle(goja.FunctionCall{
  421. Arguments: []goja.Value{
  422. sender.Vm.ToValue(newJsSender),
  423. },
  424. })
  425. reply := ""
  426. if rt != goja.Undefined() {
  427. reply = rt.ToString().String()
  428. } else {
  429. reply = ""
  430. }
  431. newSender.Reply(reply)
  432. }()
  433. // return GoAgain("")
  434. } else {
  435. var rt = handle(goja.FunctionCall{
  436. Arguments: []goja.Value{
  437. sender.Vm.ToValue(newJsSender),
  438. },
  439. })
  440. reply := ""
  441. if rt != goja.Undefined() {
  442. reply = rt.ToString().String()
  443. } else {
  444. reply = ""
  445. }
  446. if strings.HasPrefix(reply, "go_again_") {
  447. reply = strings.Replace(reply, "go_again_", "", 1)
  448. return GoAgain(reply)
  449. } else {
  450. // if sustainable {
  451. // return GoAgain(reply)
  452. // }
  453. if reply == "" {
  454. return nil
  455. }
  456. return reply
  457. }
  458. }
  459. }
  460. return nil
  461. }, options...)
  462. }
  463. if !routine {
  464. await()
  465. } else {
  466. go await()
  467. }
  468. return newJsSender
  469. }
  470. type TimeJsImpl struct {
  471. Second time.Duration
  472. Minute time.Duration
  473. Hour time.Duration
  474. Day time.Duration
  475. Month int
  476. }
  477. func (t *TimeJsImpl) Now() time.Time {
  478. return time.Now()
  479. }
  480. func (t *TimeJsImpl) Date(year int, month int, day int, hour int, min int, sec int, nsec int) time.Time {
  481. return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc)
  482. }
  483. func (t *TimeJsImpl) Sleep(i int) {
  484. time.Sleep(time.Duration(i) * time.Millisecond)
  485. }
  486. func (t *TimeJsImpl) Unix(sec int64) time.Time {
  487. return time.Unix(sec, 0)
  488. }
  489. func (t *TimeJsImpl) UnixMilli(sec int64) time.Time {
  490. return time.UnixMilli(sec)
  491. }
  492. func (t *TimeJsImpl) Parse(timeStr, layout, locale string) (tt time.Time, err error) {
  493. if locale == "" {
  494. locale = "Asia/Shanghai"
  495. }
  496. local, err := time.LoadLocation(locale) //设置时区
  497. if err != nil {
  498. return tt, err
  499. }
  500. tt, err = time.ParseInLocation(layout, timeStr, local)
  501. if err != nil {
  502. return tt, err
  503. }
  504. return tt, nil
  505. }
  506. type Fmt struct {
  507. }
  508. func (sender *Fmt) Sprintf(format string, a ...interface{}) string {
  509. return fmt.Sprintf(format, a...)
  510. }
  511. func (sender *Fmt) Printf(format string, a ...interface{}) {
  512. fmt.Printf(format, a...)
  513. }
  514. func (sender *Fmt) Println(a ...interface{}) (int, error) {
  515. return fmt.Println(a...)
  516. }
  517. func (sender *Fmt) Print(a ...interface{}) (int, error) {
  518. return fmt.Print(a...)
  519. }
  520. func Url2Base64(imageUrl string) map[string]interface{} {
  521. response, err := http.Get(imageUrl)
  522. if err != nil {
  523. return map[string]interface{}{"error": err.Error()}
  524. }
  525. defer response.Body.Close()
  526. data, err := ioutil.ReadAll(response.Body)
  527. if err != nil {
  528. return map[string]interface{}{"error": err.Error()}
  529. }
  530. imageBase64 := base64.StdEncoding.EncodeToString(data)
  531. return map[string]interface{}{"result": imageBase64}
  532. }
  533. func stringToBase64(str string) string {
  534. return base64.StdEncoding.EncodeToString([]byte(str))
  535. }
  536. func base64ToString(b64 string) string {
  537. data, err := base64.StdEncoding.DecodeString(b64)
  538. if err != nil {
  539. return ""
  540. }
  541. return string(data)
  542. }
  543. func formatRule(rule string) []string {
  544. _rs := []string{}
  545. FR:
  546. ress := regexp.MustCompile(`\[([^\s\[\]]+)\]`).FindAllStringSubmatch(rule, -1)
  547. if len(ress) != 0 {
  548. res := ress[len(ress)-1]
  549. var inner = res[1]
  550. slice := strings.SplitN(inner, ":", 2)
  551. name := slice[0]
  552. ps := ""
  553. if len(slice) == 2 {
  554. ps = slice[1]
  555. }
  556. if strings.HasSuffix(name, "?") {
  557. name = strings.TrimRight(name, "?")
  558. rep := ""
  559. if ps == "" {
  560. rep = fmt.Sprintf("[%s]", name)
  561. } else {
  562. rep = fmt.Sprintf("[%s:%s]", name, ps)
  563. }
  564. for l := range _rs {
  565. _rs[l] = strings.Replace(_rs[l], res[0], rep, 1)
  566. }
  567. rule1 := strings.Replace(rule, res[0], rep, 1)
  568. if len(_rs) == 0 {
  569. _rs = append(_rs, rule1)
  570. }
  571. rule = strings.Replace(rule, res[0], "", 1)
  572. rule = regexp.MustCompile("\x20{2,}").ReplaceAllString(rule, " ")
  573. rule = strings.TrimSpace(rule)
  574. _rs = append(_rs, rule)
  575. goto FR
  576. }
  577. }
  578. return _rs
  579. }