local CRs = {} local _resume = coroutine.resume function coroutine.resume(cr, ...) local ret = { _resume(cr, ...) } if coroutine.status(cr) == 'dead' then CRs[CRs[cr]] = nil CRs[cr] = nil end if not ret[1] then outputDebugString(ret[2], 1) return false end table.remove(ret, 1) return unpack(ret) end local serverMT = {} function serverMT:__index(fnName) return function(...) triggerServerEvent('onServerCallback', getLocalPlayer(), CRs[coroutine.running()], fnName, ...) return coroutine.yield() end end server = setmetatable({}, serverMT) addEvent('onServerCallbackReply', true) addEventHandler('onServerCallbackReply', getResourceRootElement(getThisResource()), function(crID, ...) coroutine.resume(CRs[crID], ...) end, false ) local function wrapHandler(fn) return function(...) local cr = coroutine.create(fn) local id = #CRs + 1 CRs[id] = cr CRs[cr] = id coroutine.resume(cr, ...) end end local _addEventHandler = addEventHandler function addEventHandler(event, elem, fn, getPropagated) return _addEventHandler( event, elem, (event == 'onClientRender' or event == 'onClientPreRender') and fn or wrapHandler(fn), getPropagated ) end local _addCommandHandler = addCommandHandler function addCommandHandler(command, fn) return _addCommandHandler(command, wrapHandler(fn)) end function table.each(t, callback, ...) for k,v in pairs(t) do callback(v, ...) end return t end function table.merge ( ... ) local ret = { } for index, tbl in ipairs ( {...} ) do for index, val in ipairs ( tbl ) do table.insert ( ret, val ) end end return ret end function table.find ( tbl, val ) for index, value in ipairs ( tbl ) do if value == val then return index end end return false end