script.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // script
  2. package util
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. ljson "github.com/yuin/gopher-json"
  7. "github.com/yuin/gopher-lua"
  8. )
  9. type LuaScript struct {
  10. Code, Name, Script string
  11. Doc map[string]interface{}
  12. L *lua.LState
  13. }
  14. func (s *LuaScript) RunScript() map[string]interface{} {
  15. data := map[string]interface{}{}
  16. s.L = lua.NewState()
  17. s.L.PreloadModule("json", ljson.Loader)
  18. defer s.L.Close()
  19. if err := s.L.DoString(s.Script); err != nil {
  20. data["err"] = err.Error()
  21. } else {
  22. tab := MapToLuaTable(s.L, s.Doc)
  23. if err := s.L.CallByParam(lua.P{
  24. Fn: s.L.GetGlobal("main"),
  25. NRet: 1,
  26. Protect: true,
  27. }, tab); err != nil {
  28. data["err"] = err.Error()
  29. }
  30. ret := s.L.Get(-1)
  31. s.L.Pop(1)
  32. if tmp, ok := ret.(*lua.LTable); ok {
  33. data = LuaTableToMap(tmp)
  34. } else {
  35. data["rep"] = ret
  36. }
  37. }
  38. return data
  39. }
  40. func Logic(str string, doc map[string]interface{}) bool {
  41. L := lua.NewState()
  42. L.PreloadModule("json", ljson.Loader)
  43. defer L.Close()
  44. b := false
  45. if err := L.DoString(str); err != nil {
  46. panic(err)
  47. } else {
  48. tab := MapToLuaTable(L, doc)
  49. if err := L.CallByParam(lua.P{
  50. Fn: L.GetGlobal("logic"),
  51. NRet: 1,
  52. Protect: true,
  53. }, tab); err != nil {
  54. panic(err)
  55. }
  56. ret := L.Get(-1)
  57. L.Pop(1)
  58. if ret.String() == "true" {
  59. b = true
  60. }
  61. }
  62. return b
  63. }
  64. func MapToLuaTable(l *lua.LState, obj map[string]interface{}) *lua.LTable {
  65. tab := l.NewTable()
  66. for k, v := range obj {
  67. if val, ok := v.(string); ok {
  68. tab.RawSet(lua.LString(k), lua.LString(val))
  69. } else if val, ok := v.(int64); ok {
  70. tab.RawSet(lua.LString(k), lua.LNumber(val))
  71. } else if val, ok := v.(int32); ok {
  72. tab.RawSet(lua.LString(k), lua.LNumber(val))
  73. } else if val, ok := v.(float64); ok {
  74. tab.RawSet(lua.LString(k), lua.LNumber(val))
  75. } else if val, ok := v.(float32); ok {
  76. tab.RawSet(lua.LString(k), lua.LNumber(val))
  77. } else if val, ok := v.(bool); ok {
  78. tab.RawSet(lua.LString(k), lua.LBool(val))
  79. } else if val, ok := v.(map[string]interface{}); ok {
  80. tab.RawSet(lua.LString(k), MapToLuaTable(l, val))
  81. } else if val, ok := v.([]interface{}); ok {
  82. bs, _ := json.Marshal(val)
  83. tab.RawSet(lua.LString(k), lua.LString(string(bs)))
  84. }
  85. }
  86. return tab
  87. }
  88. func LuaTableToMap(param *lua.LTable) map[string]interface{} {
  89. tmp := map[string]interface{}{}
  90. param.ForEach(func(key, val lua.LValue) {
  91. k := fmt.Sprint(key)
  92. if v, ok := val.(lua.LString); ok {
  93. tmp[k] = string(v)
  94. } else if v, ok := val.(*lua.LTable); ok {
  95. tmp[k] = LuaTableToMap(v)
  96. } else if v, ok := val.(*lua.LBool); ok {
  97. if v.String() == "true" {
  98. tmp[k] = true
  99. } else {
  100. tmp[k] = false
  101. }
  102. } else {
  103. tmp[k] = v
  104. }
  105. })
  106. return tmp
  107. }