-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathscript.lua
148 lines (126 loc) · 3.81 KB
/
script.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Script = {}
Script.__index = Script
local function getTs()
if (IsDuplicityVersion()) then
local date = os.date('*t')
return string.format('%02d:%02d:%02d', date.hour, date.min, date.sec)
else
local year, month, day, hour, minute, second = GetLocalTime()
return string.format('%02d:%02d:%02d', hour, minute, second)
end
end
local function patchConsole(script)
local function createLogger(method)
return function(...)
local messages = {}
for i = 1, select('#', ...) do
local value = select(i, ...)
if type(value) == 'vector3' then
value = string.format('vector3(%f, %f, %f)', value.x, value.y, value.z)
end
table.insert(messages, value)
end
print(...)
for _, handler in ipairs(script._events.out) do
handler({ id = script.id, method = method, data = messages, timestamp = getTs() })
end
end
end
script._globals.print = createLogger('log')
script._globals.printError = createLogger('error')
end
local function patchGlobals(disposables)
local globals = {}
globals.AddEventHandler = function(eventName, handler)
local cookie = _G.AddEventHandler(eventName, handler)
table.insert(disposables, function()
_G.RemoveEventHandler(cookie)
end)
end
globals.RegisterNetEvent = function(eventName, handler)
_G.RegisterNetEvent(eventName)
local cookie = _G.AddEventHandler(eventName, handler)
table.insert(disposables, function()
_G.RemoveEventHandler(cookie)
end)
end
globals.RegisterCommand = function(commandName, handler)
local active = true
_G.RegisterCommand(commandName, function(...)
if active then
handler(...)
end
end)
table.insert(disposables, function()
active = false
end)
end
local ticks = {}
globals.clearTick = function(tickId)
local hadTick = ticks[tickId]
ticks[tickId] = nil
return hadTick
end
globals.setTick = function(handler)
local tickId = {}
ticks[tickId] = true
Citizen.CreateThread(function()
while ticks[tickId] do
handler()
Citizen.Wait(0)
end
end)
table.insert(disposables, function()
globals.clearTick(tickId)
end)
return tickId
end
return globals
end
function Script.new(id, context)
local self = setmetatable({}, Script)
self.id = id
self._context = context or function()
return {}
end
self._disposables = {}
self._globals = patchGlobals(self._disposables)
patchConsole(self)
self._events = {
out = {},
error = {}
}
return self
end
function Script:execute(code)
local context = self._context()
local env = setmetatable({}, { __index = function(_, key)
return context[key] or self._globals[key] or _G[key]
end })
local func, err = load(code, 'script', 't', env)
if not func then
self._globals.printError(err)
for _, handler in ipairs(self._events.error) do
handler(err)
end
return
end
local success, res = pcall(func)
if not success then
self._globals.printError('Result:', res)
for _, handler in ipairs(self._events.error) do
handler(res)
end
return
end
self._globals.print('Result:', res or "nil")
end
function Script:cleanup()
for _, disposable in ipairs(self._disposables) do
disposable()
end
self._disposables = {}
end
function Script:on(eventName, handler)
table.insert(self._events[eventName], handler)
end