script.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /**
  2. 脚本加载+调用 封装,
  3. 前期走文件系统加载
  4. 后期走数据库配置,
  5. LUA中公共的方法需要抽出来,主脚本文件加载LUA公共文件
  6. */
  7. package spider
  8. import (
  9. "bytes"
  10. "compress/gzip"
  11. "crypto/aes"
  12. "encoding/base64"
  13. "encoding/json"
  14. "github.com/shopspring/decimal"
  15. "io/ioutil"
  16. mu "mfw/util"
  17. "net/http"
  18. "net/url"
  19. "path"
  20. qu "qfw/util"
  21. "regexp"
  22. util "spiderutil"
  23. "strconv"
  24. "strings"
  25. "time"
  26. "golang.org/x/text/encoding/simplifiedchinese"
  27. "golang.org/x/text/transform"
  28. "github.com/cjoudrey/gluahttp"
  29. lujson "github.com/yuin/gopher-json"
  30. "github.com/yuin/gopher-lua"
  31. )
  32. //脚本
  33. type Script struct {
  34. SCode, ScriptFile string
  35. Encoding string
  36. Downloader string //下载器
  37. Timeout int64 //超时时间秒
  38. L *lua.LState
  39. Test_luareqcount int //脚本请求次数
  40. Test_goreqtime int //go发起次数(时间)
  41. Test_goreqlist int //go发起次数(列表)
  42. Test_goreqcon int //go发起次数(正文)
  43. }
  44. //加载文件
  45. func (s *Script) LoadScript(downloadnode, script string, isfile ...string) {
  46. s.ScriptFile = script
  47. options := lua.Options{
  48. RegistrySize: 256 * 20,
  49. CallStackSize: 256,
  50. IncludeGoStackTrace: false,
  51. }
  52. s.L = lua.NewState(options)
  53. //s.L.ScriptFileName = s.SCode
  54. s.L.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader)
  55. s.L.PreloadModule("json", lujson.Loader)
  56. if len(isfile) > 0 {
  57. if err := s.L.DoFile(script); err != nil {
  58. panic("加载lua脚本错误" + err.Error())
  59. }
  60. } else {
  61. if err := s.L.DoString(script); err != nil {
  62. panic("加载lua脚本错误" + err.Error())
  63. }
  64. }
  65. s.Encoding = s.GetVar("spiderPageEncoding")
  66. //暴露go方法
  67. //download(url,head) 普通下载
  68. s.L.SetGlobal("download", s.L.NewFunction(func(S *lua.LState) int {
  69. head := S.ToTable(-1)
  70. url := S.ToString(-2)
  71. ishttps := S.ToBool(-3)
  72. charset := S.ToString(-4)
  73. if charset == "" {
  74. charset = s.Encoding
  75. }
  76. ret := Download(downloadnode, s.Downloader, url, "get", util.GetTable(head), charset, false, ishttps, "", s.Timeout)
  77. S.Push(lua.LString(ret))
  78. s.Test_luareqcount++
  79. return 1
  80. }))
  81. s.L.SetGlobal("findContentText", s.L.NewFunction(func(S *lua.LState) int {
  82. gpath := S.ToString(-2)
  83. content := S.ToString(-1)
  84. ret := util.FindContentText(gpath, content)
  85. S.Push(ret)
  86. return 1
  87. }))
  88. //高级下载download(url,method,param,head,cookie)
  89. s.L.SetGlobal("downloadAdv", s.L.NewFunction(func(S *lua.LState) int {
  90. cookie := S.ToString(-1)
  91. head := S.ToTable(-2)
  92. param := S.ToTable(-3)
  93. method := S.ToString(-4)
  94. url := S.ToString(-5)
  95. ishttps := S.ToBool(-6)
  96. charset := S.ToString(-7)
  97. if charset == "" {
  98. charset = s.Encoding
  99. }
  100. var mycookie []*http.Cookie
  101. json.Unmarshal([]byte(cookie), &mycookie)
  102. var ret string
  103. var retcookie []*http.Cookie
  104. if param == nil {
  105. ptext := map[string]interface{}{"text": S.ToString(-3)}
  106. ret, retcookie = DownloadAdv(downloadnode, s.Downloader, url, method, ptext, util.GetTable(head), mycookie, charset, false, ishttps, "", s.Timeout)
  107. } else {
  108. ret, retcookie = DownloadAdv(downloadnode, s.Downloader, url, method, util.GetTable(param), util.GetTable(head), mycookie, charset, false, ishttps, "", s.Timeout)
  109. }
  110. S.Push(lua.LString(ret))
  111. scookie, _ := json.Marshal(retcookie)
  112. S.Push(lua.LString(scookie))
  113. s.Test_luareqcount++
  114. return 2
  115. }))
  116. s.L.SetGlobal("findOneText", s.L.NewFunction(func(S *lua.LState) int {
  117. nodetype := S.ToString(-3)
  118. gpath := S.ToString(-2)
  119. content := S.ToString(-1)
  120. ret := util.FindOneText(gpath, content, nodetype)
  121. S.Push(ret)
  122. return 1
  123. }))
  124. s.L.SetGlobal("findOneHtml", s.L.NewFunction(func(S *lua.LState) int {
  125. nodetype := S.ToString(-3)
  126. gpath := S.ToString(-2)
  127. content := S.ToString(-1)
  128. ret := util.FindOneHtml(gpath, content, nodetype)
  129. S.Push(ret)
  130. return 1
  131. }))
  132. s.L.SetGlobal("findListText", s.L.NewFunction(func(S *lua.LState) int {
  133. gpath := S.ToString(-2)
  134. content := S.ToString(-1)
  135. ret := s.L.NewTable()
  136. util.FindListText(gpath, content, ret)
  137. S.Push(ret)
  138. return 1
  139. }))
  140. s.L.SetGlobal("findListHtml", s.L.NewFunction(func(S *lua.LState) int {
  141. gpath := S.ToString(-2)
  142. content := S.ToString(-1)
  143. ret := s.L.NewTable()
  144. util.FindListHtml(gpath, content, ret)
  145. S.Push(ret)
  146. return 1
  147. }))
  148. s.L.SetGlobal("findMap", s.L.NewFunction(func(S *lua.LState) int {
  149. qmap := S.ToTable(-2)
  150. content := S.ToString(-1)
  151. ret := s.L.NewTable()
  152. util.FindMap(qmap, content, ret)
  153. S.Push(ret)
  154. return 1
  155. }))
  156. //调用jsvm
  157. s.L.SetGlobal("jsvm", s.L.NewFunction(func(S *lua.LState) int {
  158. js := S.ToString(-1)
  159. ret := s.L.NewTable()
  160. if js == "" {
  161. ret.RawSet(lua.LString("val"), lua.LString(""))
  162. ret.RawSet(lua.LString("err"), lua.LString("js is null"))
  163. } else {
  164. rep := util.JsVmPost(util.Config.JsVmUrl, js)
  165. ret.RawSet(lua.LString("val"), lua.LString(qu.ObjToString(rep["val"])))
  166. ret.RawSet(lua.LString("err"), lua.LString(qu.ObjToString(rep["err"])))
  167. }
  168. S.Push(ret)
  169. return 1
  170. }))
  171. //指定下载器
  172. s.L.SetGlobal("changeDownloader", s.L.NewFunction(func(S *lua.LState) int {
  173. s.Downloader = GetOneDownloader()
  174. S.Push(lua.LString(s.Downloader))
  175. return 1
  176. }))
  177. //手工延时
  178. s.L.SetGlobal("timeSleep", s.L.NewFunction(func(S *lua.LState) int {
  179. time.Sleep(1 * time.Second)
  180. return 0
  181. }))
  182. //编码解码
  183. s.L.SetGlobal("transCode", s.L.NewFunction(func(S *lua.LState) int {
  184. codeType := strings.ToLower(S.ToString(-2))
  185. str := S.CheckString(-1)
  186. switch codeType {
  187. case "unicode":
  188. str = strings.Replace(str, "%u", "\\u", -1)
  189. str = transUnic(str)
  190. case "urlencode_gbk":
  191. data, _ := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(str)), simplifiedchinese.GBK.NewEncoder()))
  192. l, _ := url.Parse("http://a.com/?" + string(data))
  193. tmpstr := l.Query().Encode()
  194. if len(tmpstr) > 1 {
  195. str = tmpstr[0 : len(tmpstr)-1]
  196. } else {
  197. str = ""
  198. }
  199. case "urlencode_utf8":
  200. l, _ := url.Parse("http://a.com/?" + str)
  201. tmpstr := l.Query().Encode()
  202. if len(tmpstr) > 1 {
  203. str = tmpstr[0 : len(tmpstr)-1]
  204. } else {
  205. str = ""
  206. }
  207. case "urldecode_utf8":
  208. str, _ = url.QueryUnescape(str)
  209. case "decode64":
  210. str = util.DecodeB64(str)
  211. case "encodemd5":
  212. str = qu.GetMd5String(str)
  213. case "htmldecode": //html实体码
  214. //txt := `<div align="left" style="margin-left: 0pt;"><span style='font-family:; font-size:13px; color:#000000'>&#22826;&#38451;&#23707;&#29305;&#21220;&#28040;&#38450;&#31449;&#12289;&#26494;&#28006;&#29305;&#21220;&#28040;&#38450;&#31449;&#24314;&#35774;&#39033;&#30446;&#35774;&#35745;&#20013;&#26631;&#20844;&#31034;</span></div>`
  215. str = S.ToString(-1)
  216. reg, _ := regexp.Compile("&#\\d+;")
  217. str = reg.ReplaceAllStringFunc(str, func(src string) string {
  218. v, _ := strconv.Atoi(src[2 : len(src)-1])
  219. return string(rune(v))
  220. })
  221. }
  222. S.Push(lua.LString(str))
  223. return 1
  224. }))
  225. //保存错误日志
  226. s.L.SetGlobal("saveErrLog", s.L.NewFunction(func(S *lua.LState) int {
  227. return 0
  228. }))
  229. //添加改版日志
  230. s.L.SetGlobal("saveRevisionLog", s.L.NewFunction(func(S *lua.LState) int {
  231. return 0
  232. }))
  233. //如果服务端返回的html是gzip压缩过格式的 这里需要转一下
  234. s.L.SetGlobal("unGzip", s.L.NewFunction(func(S *lua.LState) int {
  235. html := S.ToString(-1)
  236. bs := []byte(html)
  237. gzipreader, _ := gzip.NewReader(bytes.NewReader(bs))
  238. bs, _ = ioutil.ReadAll(gzipreader)
  239. S.Push(lua.LString(bs))
  240. return 1
  241. }))
  242. s.L.SetGlobal("titleRepeatJudgement", s.L.NewFunction(func(S *lua.LState) int {
  243. bResult := false
  244. S.Push(lua.LBool(bResult))
  245. return 1
  246. }))
  247. //解析附件中的word、pdf
  248. s.L.SetGlobal("officeAnalysis", s.L.NewFunction(func(S *lua.LState) int {
  249. ext := map[string]byte{"pdf": byte(0), "doc": byte(1), "docx": byte(2)}
  250. str := S.ToString(-2)
  251. extension := S.ToString(-1)
  252. bs, _ := base64.StdEncoding.DecodeString(str)
  253. bs = append([]byte{ext[extension]}, bs...)
  254. msgid := mu.UUID(8)
  255. Msclient.Call("", msgid, mu.SERVICE_OFFICE_ANALYSIS, mu.SENDTO_TYPE_ALL_RECIVER, bs, 60)
  256. return 1
  257. }))
  258. //下载附件download(url,method,param,head,cookie,fileName)
  259. s.L.SetGlobal("downloadFile", s.L.NewFunction(func(S *lua.LState) int {
  260. cookie := S.ToString(-1)
  261. head := S.ToTable(-2)
  262. param := S.ToTable(-3)
  263. method := S.ToString(-4)
  264. url := S.ToString(-5)
  265. fileName := S.ToString(-6)
  266. ishttps := strings.Contains(url, "https")
  267. var mycookie []*http.Cookie
  268. if cookie != "{}" {
  269. json.Unmarshal([]byte(cookie), &mycookie)
  270. } else {
  271. mycookie = make([]*http.Cookie, 0)
  272. }
  273. fileName = strings.TrimSpace(fileName)
  274. url = strings.TrimSpace(url)
  275. ret := DownloadFile(s.Downloader, url, method, util.GetTable(param), util.GetTable(head), mycookie, s.Encoding, false, ishttps, "", s.Timeout)
  276. name, size, ftype, fid := "", "", "", ""
  277. qu.Debug(GarbledCodeReg.FindAllString(string(ret), -1), len(ret))
  278. if ret == nil || len(ret) < 1024*5 {
  279. qu.Debug("下载文件出错!")
  280. } else {
  281. ftype = qu.GetFileType(ret)
  282. if (ftype == "docx" || ftype == "doc") && len(GarbledCodeReg.FindAllString(string(ret), -1)) > 10 {
  283. url, name, size, ftype, fid = "附件中含有乱码", "附件中含有乱码", "", "", ""
  284. } else {
  285. url, name, size, ftype, fid = util.UploadFile(s.SCode, fileName, url, ret)
  286. }
  287. }
  288. if strings.TrimSpace(ftype) == "" {
  289. if len(path.Ext(name)) > 0 {
  290. ftype = path.Ext(name)[1:]
  291. }
  292. }
  293. S.Push(lua.LString(url))
  294. S.Push(lua.LString(name))
  295. S.Push(lua.LString(size))
  296. S.Push(lua.LString(ftype))
  297. S.Push(lua.LString(fid))
  298. return 5
  299. }))
  300. //支持正则
  301. s.L.SetGlobal("regexp", s.L.NewFunction(func(S *lua.LState) int {
  302. index := int(S.ToNumber(-1))
  303. regstr := S.ToString(-2)
  304. text := S.ToString(-3)
  305. reg := regexp.MustCompile(regstr)
  306. reps := reg.FindAllStringSubmatchIndex(text, -1)
  307. ret := s.L.NewTable()
  308. number := 0
  309. for _, v := range reps {
  310. number++
  311. ret.Insert(number, lua.LString(text[v[index]:v[index+1]]))
  312. }
  313. S.Push(ret)
  314. return 1
  315. }))
  316. //支持替换
  317. s.L.SetGlobal("replace", s.L.NewFunction(func(S *lua.LState) int {
  318. text := S.ToString(-3)
  319. old := S.ToString(-2)
  320. repl := S.ToString(-1)
  321. text = strings.Replace(text, old, repl, -1)
  322. S.Push(lua.LString(text))
  323. return 1
  324. }))
  325. //标题的关键词、排除词过滤
  326. s.L.SetGlobal("pagefilterword", s.L.NewFunction(func(S *lua.LState) int {
  327. keyWordReg := regexp.MustCompile(util.Config.Word["keyword"])
  328. notKeyWordReg := regexp.MustCompile(util.Config.Word["notkeyword"])
  329. data := S.ToTable(-1)
  330. dataMap := util.TableToMap(data)
  331. ret := s.L.NewTable()
  332. num := 1
  333. for _, v := range dataMap {
  334. tmp := v.(map[string]interface{})
  335. isOk := false
  336. if title := qu.ObjToString(tmp["title"]); title != "" {
  337. if keyWordReg.MatchString(title) && !notKeyWordReg.MatchString(title) {
  338. isOk = true
  339. }
  340. }
  341. if isOk {
  342. ret.Insert(num, util.MapToLuaTable(S, tmp))
  343. num++
  344. }
  345. }
  346. S.Push(ret)
  347. return 1
  348. }))
  349. //标题的关键词、排除词过滤
  350. s.L.SetGlobal("detailfilterword", s.L.NewFunction(func(S *lua.LState) int {
  351. keyWordReg := regexp.MustCompile(util.Config.Word["keyword"])
  352. notKeyWordReg := regexp.MustCompile(util.Config.Word["notkeyword"])
  353. data := S.ToTable(-1)
  354. dataMap := util.TableToMap(data)
  355. if title := qu.ObjToString(dataMap["title"]); title != "" {
  356. if keyWordReg.MatchString(title) && !notKeyWordReg.MatchString(title) {
  357. S.Push(lua.LBool(true))
  358. return 1
  359. } else {
  360. qu.Debug(s.SCode, dataMap["href"], " title error")
  361. }
  362. } else {
  363. qu.Debug(s.SCode, dataMap["href"], " title error")
  364. }
  365. S.Push(lua.LBool(false))
  366. return 1
  367. }))
  368. //detail过滤
  369. s.L.SetGlobal("filterdetail", s.L.NewFunction(func(S *lua.LState) int {
  370. /*
  371. 1.长度判断 (特殊处理:详情请访问原网页!;详见原网页;见原网页;无;无相关内容;无正文内容)
  372. 2.是否含汉字
  373. */
  374. reg1 := regexp.MustCompile("(原网页|无|无相关内容|无正文内容|详见附件|见附件)")
  375. reg2 := regexp.MustCompile("[\u4e00-\u9fa5]")
  376. detail := S.ToString(-1)
  377. if reg1.MatchString(detail) {
  378. S.Push(lua.LBool(true))
  379. return 1
  380. }
  381. if len([]rune(detail)) < 50 || !reg2.MatchString(detail) {
  382. S.Push(lua.LBool(false))
  383. return 1
  384. }
  385. S.Push(lua.LBool(false))
  386. return 1
  387. }))
  388. //匹配汉字
  389. s.L.SetGlobal("matchan", s.L.NewFunction(func(S *lua.LState) int {
  390. reg1 := regexp.MustCompile("(见附件|详见附件)")
  391. reg2 := regexp.MustCompile("[\u4e00-\u9fa5]")
  392. detail := S.ToString(-1)
  393. detail = reg1.ReplaceAllString(detail, "")
  394. ok := reg2.MatchString(detail)
  395. S.Push(lua.LBool(ok))
  396. return 1
  397. }))
  398. //base64加密
  399. s.L.SetGlobal("encodeBase64", s.L.NewFunction(func(S *lua.LState) int {
  400. text := S.ToString(-1)
  401. base64Text := base64.StdEncoding.EncodeToString([]byte(text))
  402. S.Push(lua.LString(base64Text))
  403. return 1
  404. }))
  405. //base64解密
  406. s.L.SetGlobal("decodeBase64", s.L.NewFunction(func(S *lua.LState) int {
  407. text := S.ToString(-1)
  408. result := ""
  409. byteText, err := base64.StdEncoding.DecodeString(text)
  410. if err == nil {
  411. result = string(byteText)
  412. }
  413. S.Push(lua.LString(result))
  414. return 1
  415. }))
  416. //aes ecb模式加密
  417. s.L.SetGlobal("aesEncryptECB", s.L.NewFunction(func(S *lua.LState) int {
  418. origData := S.ToString(-2)
  419. key := S.ToString(-1)
  420. bytekey := []byte(key)
  421. byteorigData := []byte(origData)
  422. cipher, _ := aes.NewCipher(generateKey([]byte(bytekey)))
  423. length := (len(byteorigData) + aes.BlockSize) / aes.BlockSize
  424. plain := make([]byte, length*aes.BlockSize)
  425. copy(plain, byteorigData)
  426. pad := byte(len(plain) - len(byteorigData))
  427. for i := len(byteorigData); i < len(plain); i++ {
  428. plain[i] = pad
  429. }
  430. encrypted := make([]byte, len(plain))
  431. // 分组分块加密
  432. for bs, be := 0, cipher.BlockSize(); bs <= len(byteorigData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
  433. cipher.Encrypt(encrypted[bs:be], plain[bs:be])
  434. }
  435. result := base64.StdEncoding.EncodeToString(encrypted)
  436. S.Push(lua.LString(result))
  437. return 1
  438. }))
  439. //根据正文获取发布时间
  440. s.L.SetGlobal("getPublishtime", s.L.NewFunction(func(S *lua.LState) int {
  441. detail := S.ToString(-2)
  442. contenthtml := S.ToString(-1)
  443. publishtime := util.GetPublishtime([]string{contenthtml, detail})
  444. S.Push(lua.LString(publishtime))
  445. return 1
  446. }))
  447. //匹配
  448. s.L.SetGlobal("stringFind", s.L.NewFunction(func(S *lua.LState) int {
  449. regstr := S.ToString(-1)
  450. text := S.ToString(-2)
  451. reg := regexp.MustCompile(regstr)
  452. result := reg.FindString(text)
  453. isMatch := false
  454. if result != "" {
  455. isMatch = true
  456. }
  457. S.Push(lua.LString(result))
  458. S.Push(lua.LBool(isMatch))
  459. return 2
  460. }))
  461. //截取
  462. s.L.SetGlobal("stringSub", s.L.NewFunction(func(S *lua.LState) int {
  463. text := S.ToString(-3)
  464. start := S.ToInt(-2)
  465. end := S.ToInt(-1)
  466. result := ""
  467. if len(text) > 0 {
  468. textRune := []rune(text)
  469. textLen := len(textRune)
  470. if end < 0 {
  471. if start > 0 { //正向截取到倒数第end位
  472. result = string(textRune[start-1 : textLen+1+end])
  473. } else if start < 0 { //反向截取 从倒数第start位截取到倒数第end位
  474. result = string(textRune[textLen+start : textLen+1+end])
  475. }
  476. } else if start > 0 && end >= start && end <= textLen { //从第start个截取到第end个
  477. result = string(textRune[start-1 : end])
  478. }
  479. // if end == -1 {
  480. // if start >= 1 { //正向截取到结尾
  481. // result = string(textRune[start-1:])
  482. // } else if start < 0 && textLen+start >= 0 { //反向截取后缀
  483. // result = string(textRune[textLen+start:])
  484. // }
  485. // } else if start >= 1 && end <= textLen { //从第start个截取到第end个
  486. // result = string(textRune[start-1 : end])
  487. // }
  488. }
  489. S.Push(lua.LString(result))
  490. return 1
  491. }))
  492. //长度
  493. s.L.SetGlobal("stringLen", s.L.NewFunction(func(S *lua.LState) int {
  494. text := S.ToString(-1)
  495. textLen := len([]rune(text))
  496. S.Push(lua.LNumber(textLen))
  497. return 1
  498. }))
  499. //去除特殊标签中间内容
  500. s.L.SetGlobal("getPureContent", s.L.NewFunction(func(S *lua.LState) int {
  501. con := S.ToString(-1)
  502. reg := regexp.MustCompile("(?s)<(!%-%-|!--|style).*?(%-%-|--|style)>") //注释 css
  503. con = reg.ReplaceAllString(con, "")
  504. // indexArr := reg.FindAllStringIndex(con, -1)
  505. // for i := len(indexArr) - 1; i >= 0; i-- {
  506. // if index := indexArr[i]; len(index) == 2 {
  507. // con = con[:index[0]] + con[index[1]:]
  508. // }
  509. // }
  510. S.Push(lua.LString(con))
  511. return 1
  512. }))
  513. //interface转string
  514. s.L.SetGlobal("formatToString", s.L.NewFunction(func(S *lua.LState) int {
  515. strNum := S.ToString(-1)
  516. decimalNum, _ := decimal.NewFromString(strNum)
  517. S.Push(lua.LString(decimalNum.String()))
  518. return 1
  519. }))
  520. }
  521. //
  522. func (s *Script) Reload() {
  523. s.L.Close()
  524. s.LoadScript("", s.ScriptFile)
  525. }
  526. //unicode转码
  527. func transUnic(str string) string {
  528. buf := bytes.NewBuffer(nil)
  529. i, j := 0, len(str)
  530. for i < j {
  531. x := i + 6
  532. if x > j {
  533. buf.WriteString(str[i:])
  534. break
  535. }
  536. if str[i] == '\\' && str[i+1] == 'u' {
  537. hex := str[i+2 : x]
  538. r, err := strconv.ParseUint(hex, 16, 64)
  539. if err == nil {
  540. buf.WriteRune(rune(r))
  541. } else {
  542. buf.WriteString(str[i:x])
  543. }
  544. i = x
  545. } else {
  546. buf.WriteByte(str[i])
  547. i++
  548. }
  549. }
  550. return buf.String()
  551. }
  552. //取得变量
  553. func (s *Script) GetVar(key string) string {
  554. return s.L.GetGlobal(key).String()
  555. }
  556. //
  557. func (s *Script) GetIntVar(key string) int {
  558. lv := s.L.GetGlobal(key)
  559. if v, ok := lv.(lua.LNumber); ok {
  560. return int(v)
  561. }
  562. return -1
  563. }
  564. //
  565. func (s *Script) GetBoolVar(key string) bool {
  566. lv := s.L.GetGlobal(key)
  567. if v, ok := lv.(lua.LBool); ok {
  568. return bool(v)
  569. }
  570. return false
  571. }
  572. func generateKey(key []byte) (genKey []byte) {
  573. genKey = make([]byte, 16)
  574. copy(genKey, key)
  575. for i := 16; i < len(key); {
  576. for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
  577. genKey[j] ^= key[i]
  578. }
  579. }
  580. return genKey
  581. }