if (type (Require) ~= 'function') then loadstring(exports['nc_libraries']:extend('Extend'), 'Require')() end Require('File') Require('String') Require('Hash') Require('Thread') ZLibPackage = {} --------------------------------------------------------------------- -- Empacotar múltiplos arquivos em um único pacote .ncz --------------------------------------------------------------------- function ZLibPackage.pack(outputPath, inputFiles, chunkSize) chunkSize = chunkSize or (512 * 1024) local outFile = fileCreate(outputPath) if not outFile then outputDebugString("[ZLibPackage] Falha ao criar: " .. tostring(outputPath), 1) return false end local manifest = {} local totalBytes = 0 local function processFile(index) local path = inputFiles[index] if not path then -- terminou todos os arquivos, escreve o manifesto local json = toJSON(manifest, true) local header = encodeString('zlib', json, { compression = 6, format = 'zlib' }) fileSetPos(outFile, 0) fileWrite(outFile, header) fileWrite(outFile, "\0NCZ\0") -- delimitador fileClose(outFile) outputDebugString(string.format("[ZLibPackage] Pacote concluído: %s (%d arquivos, %d bytes)", outputPath, #manifest, totalBytes)) return end local fileHandle = fileOpen(path) if not fileHandle then outputDebugString("[ZLibPackage] Não foi possível abrir: " .. tostring(path), 1) return processFile(index + 1) end local fileSize = fileGetSize(fileHandle) local chunks = {} local success = true fileInChunks(fileHandle, chunkSize, function(chunk) local encoded = encodeString("zlib", chunk, { compression = 6, format = 'zlib' }) fileWrite(outFile, encoded) table.insert(chunks, #encoded) totalBytes = totalBytes + #encoded end, function(_success) success = _success fileClose(fileHandle) if success then table.insert(manifest, { name = path, size_original = fileSize, chunks = chunks, }) outputDebugString(string.format("[ZLibPackage] Arquivo empacotado: %s (%d chunks)", path, #chunks)) else outputDebugString("[ZLibPackage] Falha ao empacotar " .. tostring(path), 1) end processFile(index + 1) end) end processFile(1) return true end --------------------------------------------------------------------- -- Desempacotar arquivo .ncz (usando fileInEncodedChunks) --------------------------------------------------------------------- function ZLibPackage.unpack(inputPath, outputDir) local file = fileOpen(inputPath) if not file then outputDebugString("[ZLibPackage] Falha ao abrir pacote: " .. tostring(inputPath), 1) return false end local size = fileGetSize(file) local data = fileRead(file, size) fileClose(file) local headerEnd = string.find(data, "\0NCZ\0", 1, true) if not headerEnd then outputDebugString("[ZLibPackage] Pacote inválido (sem delimitador)", 1) return false end local headerData = string.sub(data, 1, headerEnd - 1) local compressedData = string.sub(data, headerEnd + 5) local headerJson = decodeString('zlib', headerData, { compression = 6, format = 'zlib' }) local manifest = fromJSON(headerJson) if not manifest then outputDebugString("[ZLibPackage] Manifesto inválido", 1) return false end local offset = 0 for i, info in ipairs(manifest) do local outPath = outputDir .. "/" .. string.gsub(info.name, ".-([^/\\]+)$", "%1") local out = fileCreate(outPath) if not out then outputDebugString("[ZLibPackage] Falha ao criar arquivo: " .. tostring(outPath), 1) else for _, chunkLen in ipairs(info.chunks) do local chunk = string.sub(compressedData, offset + 1, offset + chunkLen) offset = offset + chunkLen local decoded = decodeString('zlib', chunk, { compression = 6, format = 'zlib' }) if decoded then fileWrite(out, decoded) else outputDebugString("[ZLibPackage] Erro ao descompactar chunk de " .. tostring(info.name), 1) end end fileClose(out) outputDebugString(string.format("[ZLibPackage] Arquivo extraído: %s (%d chunks)", outPath, #info.chunks)) end end outputDebugString("[ZLibPackage] Desempacotamento concluído") return true end return ZLibPackage