local CLIENT = isElement(localPlayer) local math = math local table = table local string = string local getElementMatrix = getElementMatrix local getPlayerAccount = getPlayerAccount local getPlayerName = getPlayerName local getElementData = getElementData local getElementType = getElementType function math.clamp(value, min, max) return math.max(min, math.min(value, max)) end function math.round(number) return (math.floor((number * (10 ^ 0)) + 0.5)) / (10 ^ 0) end function table.copy(t) local new = {}; if not t or type(t) ~= 'table' then return new end for k, v in next, t, nil do if type(v) == 'table' then new[k] = table.copy(v) else new[k] = v end end return new; end function table.size(t, iterate) if not t then return 0 end if type(t) ~= 'table' then return 0 end if next(t) == nil then return 0 end if iterate then return #t end local q = 0 for _ in next, t, nil do q = q + 1 end return q end function table.find(tbl, value) if not tbl or type(tbl) ~= 'table' then return nil end if next(tbl) == nil then return nil end for key, val in next, tbl, nil do if val == value then return key, val end end return nil end function table.ifind(tbl, value) if not tbl or type(tbl) ~= 'table' then return nil end if next(tbl) == nil then return nil end for key, val in next, tbl, nil do if key == value then return val end end return nil end function string.change(s, t) if not s or type (s) ~= 'string' then return 'N/A', error ('O modulo '..t.reason..' não existe no arquivo de configuração!') end for w in s:gmatch ('${(%w+)}') do s = s:gsub ('${'..w..'}', tostring ((t and t[w]) or 'undefined')) end return s end function isPlayer(element) if (not element) then return false end if (isElement(element) and getElementType(element) == 'player') then return true end return false end getAccountName_ = getAccountName function getAccountName(player) if isPlayer(player) then return getAccountName_(getPlayerAccount(player)) end return false end function getElementName(element) if not element or not isElement(element) then return 'N/A'; end if getElementType(element) == 'player' then return getPlayerName(element):gsub('_', ' ') or getPlayerName(element); end return 'N/A'; end function isElementInACL(player, acls) if (not isElement(player) or not getElementType(player) == 'player') then return false, error('Defina um jogador válido para a verificação.', 2) end if (not acls or not type(acls) == 'table') then return false, error('Defina uma tabela de ACL\'s para a verificação', 2) end local account = getAccountName(player) if not account then return false end if (account ~= 'guest') then for _, v in next, acls, nil do if (aclGetGroup(v) and isObjectInACLGroup('user.'..account, aclGetGroup(v))) then return true, v end end end return false end function isElementInData(player, datas) if (not isElement(player) or not getElementType(player) == 'player') then return false, error('Defina um jogador válido para a verificação.', 2) end if (not datas or not type(datas) == 'table') then return false, error('Defina uma tabela de ACL\'s para a verificação', 2) end for _, v in next, datas, nil do if getElementData(player, v) then return true, v end end return false end function getDistance2D(x1, y1, x2, y2) local dx = x1 - x2 local dy = y1 - y2 return math.sqrt(dx * dx + dy * dy) end function getDistance3D(x1, y1, z1, x2, y2, z2) local half2 = 1 / 2 local vectorX, vectorY, vectorZ = x2 - x1, y2 - y1, z2 - z1 return ((vectorX * vectorX) + (vectorY * vectorY) + (vectorZ * vectorZ)) ^ half2 end function getPositionFromElementOffset(element, offX, offY, offZ) local m = getElementMatrix ( element ) -- Get the matrix local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1] -- Apply transform local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2] local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3] return x, y, z -- Return the transformed point end function RgbToShader(r, g, b, a) return r / 255, g / 255, b / 255, (a or 255) / 255 end local _md5 = md5 local _sha256 = sha256 _G['md5Save'] = _md5; _G['sha256Save'] = _sha256; function md5(str) if not str or type(str) ~= 'string' then return false, error('Defina uma string para o hash MD5', 2) end return _md5(str):lower() end function sha256(str) if not str or type(str) ~= 'string' then return false, error('Defina uma string para o hash SHA256', 2) end return _sha256(str):lower() end function fileInChunks(file, chunkSize, onChunk, onFinish) local co = coroutine.running() local count = 0; chunkSize = chunkSize or (512 * 1024) -- 512KB padrão while not fileIsEOF(file) do count = count + 1; if count >= 10 and type (co) == 'thread' then if CLIENT then WaitTick(1) else Wait(1) end count = 0; end local chunk = fileRead(file, chunkSize); if not chunk then break end local success, err = pcall(onChunk, chunk) if not success then outputDebugString("Erro no callback do chunk: " .. tostring(err), 1) break end end if type (onFinish) == 'function' then onFinish() end end function fileInEncodedChunks(file, chunkSizes, onChunk, onFinish) local co = coroutine.running() local count = 0 local offset = 0 for i = 1, #chunkSizes do local chunkLen = chunkSizes[i] count = count + 1 if count >= 50 and type(co) == 'thread' then if CLIENT then WaitTick(20) else Wait(1) end count = 0 end fileSetPos(file, offset) local chunk = fileRead(file, chunkLen) offset = offset + chunkLen if not chunk or #chunk < chunkLen then outputDebugString("Erro: chunk incompleto ou inválido", 1) break end local success, err = pcall(onChunk, chunk) if not success then outputDebugString("Erro no callback do chunk: " .. tostring(err), 1) break end collectgarbage("collect") end if type(onFinish) == "function" then onFinish() end end