diff --git a/ChunkManager.cpp b/ChunkManager.cpp new file mode 100644 index 0000000..aa7780c --- /dev/null +++ b/ChunkManager.cpp @@ -0,0 +1,137 @@ +/* + * This file is part of VoidArchiveTool. + * + * Copyright (C) 2025 Yanczi + * + * Void Archive Toolis free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "ChunkManager.h" + +ChunkManager::ChunkManager(EncryptionManager& em) + :eman(em) +{ } + +ChunkManager::~ChunkManager() +{ } + +//----------------------------------------------------------------------------- +// Kompresja blokowa +// +// Dzielenie vectora na chunki dokładnie po 128KB +// Kompresowanie chunków bez nagłówka +//----------------------------------------------------------------------------- +std::vector ChunkManager::chunked(const std::vector& raw, const bool& compress, const bool& encrypt) +{ + //std::vector blockSizes; + + // Maksymalny rozmiar chunka + const size_t maxBlockSize = BLOCK_SIZE; + const size_t rawSize = raw.size(); + + uint32_t blockLen = 0; + uint32_t lastChunkRawSize; + std::vector compressedBlocks; + for (size_t offset = 0; offset < rawSize; offset += maxBlockSize) + { + // Rozmiar chunka + const size_t chunkSize = std::min(maxBlockSize, rawSize - offset); + + auto begin = raw.begin() + offset; + auto end = begin + chunkSize; + + // Skopiuj fragment danych do chunka + std::vector chunk(begin, end); + + std::vector outChunk; + + // Przetwórz chunki i przetwórz + if (compress) + { + // Zaszyfruj i skompresuj lub tylko skompresuj + outChunk = encrypt ? eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); + } + else + { + // Zaszyfruj lub skopiuj + outChunk = encrypt ? eman.encrypt(chunk) : std::move(chunk); + } + + uint32_t chs = static_cast(chunk.size()); + uint32_t zch = static_cast(outChunk.size()); + + //addIntToVector(compressedBlocks, chs); + lastChunkRawSize = chs; + addIntToVector(compressedBlocks, zch); + compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end()); + + blockLen++; + } + + std::vector zip; + // Wstaw liczbę o ilości bloków do vectora; + // Przekonpwertuj usigned int32 na ciąg znkaów + // uint16_t blockLen = blockSizes .size(); + addIntToVector(zip, blockLen); + addIntToVector(zip, maxBlockSize); + addIntToVector(zip, lastChunkRawSize); + + // Dodaj skompresowane dane + zip.insert(zip.end(), compressedBlocks.begin(), compressedBlocks.end()); + + return zip; +} + +////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// Dekompresja blokowa +//----------------------------------------------------------------------------- +std::vector ChunkManager::dechunked(const std::vector& zip, const bool& compress, const bool& encrypt) +{ + size_t offset = 0; + const uint32_t chunkLen = getIntFromVector(zip, offset); + const uint32_t chunkBeforeSize = getIntFromVector(zip, offset); + const uint32_t chunkLastSize = getIntFromVector(zip, offset); + + std::cout << "Q: " << chunkLen << std::endl; + std::cout << "C: " << chunkBeforeSize << std::endl; + std::cout << "L: " << chunkBeforeSize << std::endl; + + std::vector chunksString; + + // Dekompresja bloków + for (size_t i = 0; i < chunkLen; ++i) + { + // Pobierz rozmiar chunków przed i po skompresowaniem + uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize; + uint32_t chunkZipSize = getIntFromVector(zip, offset); + + // Pobierz blok chunka + std::vector inChunk(chunkZipSize); + std::memcpy(inChunk.data(), zip.data() + offset, chunkZipSize); + offset += chunkZipSize; + + // Jeśli flaga encrypt jest aktywna najpierw zdeszyfruj blok + std::vector zipChunk = encrypt ? eman.decrypt(inChunk) : std::move(inChunk); + + // Zdeklarój pusty chunk + std::vector chunk = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk); + + // Scal chunki + chunksString.insert(chunksString.end(), chunk.begin(), chunk.end()); + } + + return chunksString; +} \ No newline at end of file diff --git a/ChunkManager.h b/ChunkManager.h new file mode 100644 index 0000000..006155d --- /dev/null +++ b/ChunkManager.h @@ -0,0 +1,70 @@ +/* + * This file is part of VoidArchiveTool. + * + * Copyright (C) 2025 Yanczi + * + * Void Archive Toolis free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "EncryptionManager.h" +#include "CompressionManager.h" + +#define BLOCK_SIZE 131072 // 128KB + +class ChunkManager +{ +public: + ChunkManager(EncryptionManager& em); + ~ChunkManager(); + + // Podział na chunki + std::vector chunked(const std::vector&, const bool&, const bool&); + + // Zcalanie chunków + std::vector dechunked(const std::vector&, const bool&, const bool&); + +private: + EncryptionManager eman; + CompressionManager cman; + + // Przekonwertuj zmienną na ciąg na vector + template + void addIntToVector(std::vector& vec, const T& val) + { + size_t tmpSize = vec.size(); + vec.resize(tmpSize + sizeof(val)); + std::memcpy(vec.data() + tmpSize, &val, sizeof(val)); + } + + // Pobierz zmienną z vectora + template + T getIntFromVector(const std::vector& vec, size_t& offset) + { + T tmp{}; + std::memcpy(&tmp, vec.data() + offset, sizeof(tmp)); + offset += sizeof(tmp); + + return tmp; + } +}; + diff --git a/CompressionManager.cpp b/CompressionManager.cpp index 0c934b8..27a2435 100644 --- a/CompressionManager.cpp +++ b/CompressionManager.cpp @@ -23,6 +23,9 @@ CompressionManager::CompressionManager() :cctx(ZSTD_createCCtx()) ,dctx(ZSTD_createDCtx()) { + // Tu ustawienia pod kompresję + const int level = COMPRESSION_LEVEL; + // Ustawienia frameless size_t rc = 0; @@ -39,7 +42,7 @@ CompressionManager::CompressionManager() rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); // Ustawia poziom kompresji - rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd::compression_level); + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level); if (ZSTD_isError(rc)) { std::cerr << "ZSTD_CCtx_setParameter error" << std::endl; diff --git a/CompressionManager.h b/CompressionManager.h index 5f747fb..83eef36 100644 --- a/CompressionManager.h +++ b/CompressionManager.h @@ -30,10 +30,7 @@ #error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless" #endif -namespace zstd -{ - inline constexpr short compression_level = 3; -} +#define COMPRESSION_LEVEL 3 class CompressionManager { diff --git a/CreateCargo.cpp b/CreateCargo.cpp index fe6f7aa..b1b97a9 100644 --- a/CreateCargo.cpp +++ b/CreateCargo.cpp @@ -20,8 +20,9 @@ #include "CreateCargo.h" CreateCargo::CreateCargo() - : signature(fl::sigpak) - , extension(fl::extpak) + : signature(SIGNATURE) + , extension(EXTENSION) + , version(VERSION) , methodFlags(0) , xxhState(XXH64_createState()) , offset(0) @@ -89,7 +90,7 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) } // Zapisywanie klucza szyfrującego - if (flag == flag::enc || flag == flag::ezd || encList.size() > 0) + if (flag == FILE_FLAG_ENCRYPT || flag == FILE_FLAG_ZIPENC || encList.size() > 0) { eman.saveKey(catalogPath, hppKey); } @@ -132,11 +133,11 @@ bool CreateCargo::GetFileList(const std::string& path) { if (FindOnTheList(zipList, fileRef) || CheckFileExtension(fileRef, zipList)) { - pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::ezd : flag::zip; + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ZIPENC : FILE_FLAG_COMPRESS; } else { - pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::enc : flag::raw; + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? FILE_FLAG_ENCRYPT : FILE_FLAG_RAW; } pc.path = PathToUnixLike(tmpPath); std::cout << pc.path << " - " << pc.parameter << std::endl; @@ -184,13 +185,42 @@ CargoHead CreateCargo::CreateCargoHead(const uint32_t& filesLen, const uint64_t& { CargoHead ch; - ch.signature = fl::sigpak; + ch.signature = signature; ch.table = table; ch.files = filesLen; return ch; } +//----------------------------------------------------------------------------- +// Sprawdza czy plik znajduje się na liście +//----------------------------------------------------------------------------- +void CreateCargo::computingBytes(const uint8_t& flag, std::vector& input, std::vector& output) +{ + //Flaga aktywna sprawdza czy plik jest na liście. Jeśli jest to zwraca surowedane + //Przeciwnie kompresuje dane + ChunkManager cm(eman); + + switch (flag) + { + case FILE_FLAG_COMPRESS: + output = cm.chunked(input, true, false); + break; + + case FILE_FLAG_ENCRYPT: + output = cm.chunked(input, false, true); + break; + + case FILE_FLAG_ZIPENC: + output = cm.chunked(input, true, true); + break; + + default: + output = std::move(input); + break; + } +} + //----------------------------------------------------------------------------- // Przygotowanie nagłówków i plików //----------------------------------------------------------------------------- @@ -219,27 +249,28 @@ std::vector CreateCargo::ComputingHeadFiles() size_t size = f.tellg(); f.seekg(0, std::ios::beg); - if (size > ds::maxFileSize) + if (size > MAX_FILE_SIZE) { - std::cerr << path << " is too large. It exceeds " << ds::maxFileSize / 1024 / 1024 / 1024 << "GB!" << std::endl; + std::cerr << path << " is too large. It exceeds " << MAX_FILE_SIZE / 1024 / 1024 / 1024 << "GB!" << std::endl; } else { XXH64_reset(xxhState, 0); //Wczytanie pliku do pamięci - std::vector buffer(ds::chunk_stream); + std::vector buffer(CHUNK_STREAM_256MB); uint64_t sizeFile = 0; - const uint32_t chunkBlockSize = ds::block_size; + const uint32_t chunkBlockSize = CHUNK_BLOCK_SIZE; const uint32_t quantity = (size + chunkBlockSize) / chunkBlockSize; const uint32_t lastChunkSize = size - (chunkBlockSize * (quantity - 1)); // Jeśli jest ustawiona flaga inna niż RAW // Dodaj do kontenera konfigurację chunków - if (file.parameter != flag::raw) + if (file.parameter != FILE_FLAG_RAW) { + std::cout << "CHUNK PARAM" << std::endl; cargo.write(reinterpret_cast(&quantity), sizeof(quantity)); cargo.write(reinterpret_cast(&chunkBlockSize), sizeof(chunkBlockSize)); cargo.write(reinterpret_cast(&lastChunkSize), sizeof(lastChunkSize)); @@ -247,7 +278,7 @@ std::vector CreateCargo::ComputingHeadFiles() } // Strumieniowanie danych - while (f.read(buffer.data(), ds::chunk_stream) || f.gcount() > 0) + while (f.read(buffer.data(), CHUNK_STREAM_256MB) || f.gcount() > 0) { const int bufferSize = f.gcount(); buffer.resize(bufferSize); @@ -255,7 +286,7 @@ std::vector CreateCargo::ComputingHeadFiles() // Aktualizacja XXH64 XXH64_update(xxhState, buffer.data(), buffer.size()); - if (file.parameter == flag::raw) + if (file.parameter == FILE_FLAG_RAW) { // Zapisywanie strumienia do kontenera cargo.write(reinterpret_cast(buffer.data()), buffer.size()); @@ -277,16 +308,17 @@ std::vector CreateCargo::ComputingHeadFiles() std::vector outChunk; // Przetwórz chunki i przetwórz - if ((file.parameter & flag::zip) == flag::zip) + if ((file.parameter & FILE_FLAG_COMPRESS) == FILE_FLAG_COMPRESS) { // Zaszyfruj i skompresuj lub tylko skompresuj - outChunk = (file.parameter & flag::enc) == flag::enc ? + outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ? eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); } else { // Zaszyfruj lub skopiuj - outChunk = eman.encrypt(chunk); + outChunk = (file.parameter & FILE_FLAG_ENCRYPT) == FILE_FLAG_ENCRYPT ? + eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); } const uint32_t outSize = outChunk.size(); @@ -297,11 +329,19 @@ std::vector CreateCargo::ComputingHeadFiles() cargo.write(reinterpret_cast(outChunk.data()), outChunk.size()); sizeFile += outSize; } + std::cout << "SIZE: " << sizeFile << std::endl; } } f.close(); + //Tworzenie hashu CRC + //const uint64_t crc = XXH64(buffer.data(), buffer.size(), 0); + + //Kompresjia + //std::vector pakBuffer; + //computingBytes(file.parameter, buffer, pakBuffer); + FilesTable ft; ft.nameFile = path; ft.nameLen = path.length(); @@ -310,6 +350,8 @@ std::vector CreateCargo::ComputingHeadFiles() ft.flag = file.parameter; ft.crc = XXH64_digest(xxhState); + //cargo.write(reinterpret_cast(pakBuffer.data()), pakBuffer.size()); + filesTable.push_back(ft); offset += sizeFile; } @@ -331,25 +373,24 @@ void CreateCargo::GetFilters(const std::string& filterFile) file.close(); // Lista plików do skompresowania - if (jslist.contains(key::zip)) + if (jslist.contains(KEY_ZIP)) { - zipList = jslist[key::zip].get>(); + zipList = jslist[KEY_ZIP].get>(); } // Lista plików do zaszyfrowania - if (jslist.contains(key::enc)) + if (jslist.contains(KEY_ENCRYPT)) { - encList = jslist[key::enc].get>(); + encList = jslist[KEY_ENCRYPT].get>(); } // Lista plików do pominięcia - if (jslist.contains(key::ignore)) + if (jslist.contains(KEY_IGNORE)) { - ignoreList = jslist[key::ignore].get>(); + ignoreList = jslist[KEY_IGNORE].get>(); } - // Flaga tworzenia klucza jako plik nagłówka c++ - hppKey = jslist.value(key::hpp, false); + hppKey = jslist.value("keyhpp", false); } //----------------------------------------------------------------------------- diff --git a/CreateCargo.h b/CreateCargo.h index 279930f..e31b3e6 100644 --- a/CreateCargo.h +++ b/CreateCargo.h @@ -33,6 +33,7 @@ #include #include "DataStruct.h" +#include "ChunkManager.h" #include "EncryptionManager.h" #include "CompressionManager.h" @@ -44,17 +45,6 @@ #define ALL_FILE ".*" // Wszystkie pliki -namespace key -{ - inline constexpr std::string_view zip = "compress"; - inline constexpr std::string_view raw = "raw"; - inline constexpr std::string_view enc = "encrypt"; - inline constexpr std::string_view ignore = "ignore"; - inline constexpr std::string_view all = ".*"; - - inline constexpr std::string_view hpp = "keyhpp"; -} - struct PathConf { std::string path; @@ -72,6 +62,7 @@ public: private: const std::string signature; const std::string extension; + const signed char version; uint8_t methodFlags; @@ -122,6 +113,9 @@ private: // Wczytanie filtrów wyjątków void GetFilters(const std::string&); + // Sprawdza czy plik znajduje się na liście + void computingBytes(const uint8_t&, std::vector&, std::vector&); + // Sprawdzanie rozszeżeń plików bool CheckFileExtension(const std::string&, const std::vector&); diff --git a/DataStruct.h b/DataStruct.h index 91bf253..5a17980 100644 --- a/DataStruct.h +++ b/DataStruct.h @@ -22,46 +22,39 @@ #include #include -namespace ui -{ - inline constexpr std::string_view title = "exPak"; - inline constexpr std::string_view ver = "0.5"; -} +#define EXTENSION "pak" +#define SIGNATURE "XPAK" -// Pliki -namespace fl -{ - inline constexpr std::string_view sigpak = "XPAK"; - inline constexpr std::string_view sigkey = "XKEY"; +#define SIGNATURE_KEY_FILE "XKEY" - inline constexpr std::string_view extpak = "pak"; - inline constexpr std::string_view extkey = "key"; -} +#define VERSION 0x03 -// Size -namespace ds -{ - // Chunki streamowania - inline constexpr uint32_t chunk_stream = 268435456; // 256MB +// Wielkość pojedynczego bloku strumienia +#define CHUNK_STREAM_512KB 524288 // 512KB +#define CHUNK_STREAM_16MB 16777216 // 16MB +#define CHUNK_STREAM_256MB 268435456 // 256MB - // Blok chunków - inline constexpr uint32_t block_size = 131072; // 128KB +// Rozmiar pojedynczego bloku +#define CHUNK_BLOCK_SIZE 131072 // 128KB - // Maksymalny rozmiar pliku do spakowania - inline constexpr uint64_t maxFileSize = 8589934592; // 8GB -} +#define FILE_FLAG_RAW 0x00 +#define FILE_FLAG_COMPRESS 0x0F +#define FILE_FLAG_ENCRYPT 0xF0 +#define FILE_FLAG_ZIPENC 0xFF -// Flagi -namespace flag -{ - inline constexpr uint8_t raw = 0x00; // Surowy plik - inline constexpr uint8_t zip = 0x0F; // Kompresja - inline constexpr uint8_t enc = 0xF0; // Szyfrowanie - inline constexpr uint8_t ezd = 0xFF; // Kompresja z szyfrowaniem +#define FILE_FLAG_FILTERING 0xAB - // Flaga do aktywacji filtra zdefiniowanego w json - inline constexpr uint8_t filter = 0xAB; -} + +//Prgoram title +#define PROGRAM_TITLE "eXtendet PAK" +#define PROGRAM_VERSION "v0.5" +#define PROGRAM_AUTHOR "Yanczi" +#define PROGRAM_COMPILING "19 December 2025" +#define PROGRAM_LICENSE "GNU LGPL v3" + +//Limity +#define MAX_FILE_SIZE 8589934592 // 8GB +#define MAX_PAK_SIZE 8796093022208 // 8TB struct CargoHead { diff --git a/EncryptionManager.cpp b/EncryptionManager.cpp index a44085e..832d6e5 100644 --- a/EncryptionManager.cpp +++ b/EncryptionManager.cpp @@ -67,6 +67,9 @@ void EncryptionManager::generateKeys() void EncryptionManager::saveKey(const std::string& path, bool hpp) { + const std::string sig = SIGNATURE_KEY_FILE; + const int8_t ver = VERSION; + // Wygeneruj time stamp std::time_t now = std::time(nullptr); const int time = static_cast(now); @@ -75,13 +78,14 @@ void EncryptionManager::saveKey(const std::string& path, bool hpp) std::vector keyVec(reinterpret_cast(key.data()), reinterpret_cast(key.data()) + key.size()); - const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), 0); + const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION); // Zapisz ten śmietnik do pliku KEY std::ofstream file(path + ".key", std::ios::binary); if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; } - file.write(fl::sigkey.data(), fl::sigkey.length()); + file.write(sig.data(), sig.length()); + file.write(reinterpret_cast(&ver), sizeof(ver)); file.write(reinterpret_cast(&time), sizeof(time)); file.write(reinterpret_cast(keyVec.data()), keyVec.size()); file.write(reinterpret_cast(&crcKey), sizeof(crcKey)); @@ -98,7 +102,7 @@ void EncryptionManager::saveCppHeadFile(const std::string& path) std::ofstream file(path + ".hpp"); - file << "// Plik wygenerowany przez " << ui::title << " " << ui::ver << std::endl; + file << "// Plik wygenerowany przez " << PROGRAM_TITLE << " " << PROGRAM_VERSION << std::endl; file << std::endl; file << std::endl; file << "#pragma once" << std::endl; @@ -133,15 +137,18 @@ std::string EncryptionManager::toHex(const unsigned char* data, size_t len) void EncryptionManager::loadKey(const std::string& path) { std::ifstream file(path + ".key", std::ios::binary); - std::vector sig(fl::sigkey.size()); + + const std::string signature = SIGNATURE_KEY_FILE; + std::vector sig(signature.size()); int8_t ver; int time; // Wczytaj file.read(sig.data(), sig.size()); + file.read(reinterpret_cast(&ver), sizeof(ver)); // Sprawdź czy plik klucza jest poprawny - if (std::string(sig.begin(), sig.end()) != fl::sigkey) + if (std::string(sig.begin(), sig.end()) != signature || ver != VERSION) { throw std::runtime_error("Invalid key file!"); } @@ -154,7 +161,7 @@ void EncryptionManager::loadKey(const std::string& path) file.read(reinterpret_cast(&crcKey), sizeof(crcKey)); // Sprawdź integralność klucza - if (XXH64(keyVec.data(), keyVec.size(), 0) != crcKey) + if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey) { throw std::runtime_error("Key integrity error!"); } diff --git a/ExtractCargo.cpp b/ExtractCargo.cpp index c944347..c59d8d8 100644 --- a/ExtractCargo.cpp +++ b/ExtractCargo.cpp @@ -22,11 +22,11 @@ ExtractCargo::ExtractCargo() :filesLen(0) , tablePosition(0) - , xxhState(XXH64_createState()) - , signature(fl::sigpak) + , version(VERSION) + , signature(SIGNATURE) { // TODO Auto-generated constructor stub - XXH64_reset(xxhState, 0); + } ExtractCargo::~ExtractCargo() @@ -110,6 +110,51 @@ bool ExtractCargo::CheckCargoFile() return true; } +//----------------------------------------------------------------------------- +// Sprawdzanie sumy kontrolnej +//----------------------------------------------------------------------------- +bool ExtractCargo::HashValid(const std::vector& data, const uint64_t& crc) +{ + uint64_t actualCrc = XXH64(data.data(), data.size(), 0); + + if (actualCrc != crc) + { + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Magiczna funkcja do dekompresji i deszyfracji danych +//----------------------------------------------------------------------------- +void ExtractCargo::computingBytes(const std::vector& input, std::vector& output, const uint8_t& flag) +{ + ChunkManager cm(eman); + + std::cout << static_cast(flag) << std::endl; + + switch (flag) + { + case FILE_FLAG_COMPRESS: + output = cm.dechunked(input, true, false); + break; + + case FILE_FLAG_ENCRYPT: + output = cm.dechunked(input, false, true); + break; + + case FILE_FLAG_ZIPENC: + output = cm.dechunked(input, true, true); + std::cout << "DENC" << std::endl; + break; + + default: + output = input; + break; + } +} + //----------------------------------------------------------------------------- // Pobieranie nagłówków plików //----------------------------------------------------------------------------- @@ -130,6 +175,9 @@ void ExtractCargo::LoadFilesTable() cargoFile.read(reinterpret_cast(&fhTmp.crc), sizeof(fhTmp.crc)); cargoFile.read(reinterpret_cast(&fhTmp.flag), sizeof(fhTmp.flag)); + std::cout << tablePosition << std::endl; + std::cout << "Size: " << fhTmp.size << std::endl; + filesHeads.push_back(fhTmp); } } @@ -143,76 +191,25 @@ void ExtractCargo::ExtractingFilesFromCargo() { std::filesystem::path dir = cargoFileName.stem() / fh.nameFile; CreateDirections(dir); - - std::cout << dir.string() << std::endl; - std::ofstream file(dir, std::ios::binary); + + std::cout << fh.size << std::endl; cargoFile.seekg(fh.offset); + std::vector buffor(fh.size); - XXH64_reset(xxhState, 0); + cargoFile.read(buffor.data(), fh.size); - // Strumień wyciągający - if (fh.flag == flag::raw) + std::vector rawBuffor; + computingBytes(buffor, rawBuffor, fh.flag); + + if (!HashValid(rawBuffor, fh.crc)) { - for (uint64_t sc = 0; sc < fh.size; sc += ds::chunk_stream) - { - const uint32_t streamChunk = std::min(ds::chunk_stream, static_cast(fh.size - sc)); - - std::vector buffer(streamChunk); - cargoFile.read(buffer.data(), streamChunk); - XXH64_update(xxhState, buffer.data(), buffer.size()); - file.write(reinterpret_cast(buffer.data()), streamChunk); - } + std::cerr << fh.nameFile << " Error: Corrupted data integration CRC" << std::endl; } - else - { - uint32_t chunkLen; - uint32_t chunkBeforeSize; - uint32_t chunkLastSize; - cargoFile.read(reinterpret_cast(&chunkLen), sizeof(chunkLen)); - cargoFile.read(reinterpret_cast(&chunkBeforeSize), sizeof(chunkBeforeSize)); - cargoFile.read(reinterpret_cast(&chunkLastSize), sizeof(chunkLastSize)); - - std::vector chunksString; - - // Dekompresja bloków - for (size_t i = 0; i < chunkLen; ++i) - { - // Pobierz rozmiar chunków przed i po skompresowaniem - uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize; - - uint32_t chunkZipSize; - cargoFile.read(reinterpret_cast(&chunkZipSize), sizeof(chunkZipSize)); - - // Pobierz blok chunka - std::vector buffer(chunkZipSize); - cargoFile.read(buffer.data(), chunkZipSize); - - std::vector rawBuffer(chunkSize); - if ((fh.flag & flag::zip) == flag::zip) - { - rawBuffer = (fh.flag & flag::enc) == flag::enc ? - cman.decompress(eman.decrypt(buffer), chunkSize) : - cman.decompress(buffer, chunkSize); - } - else - { - rawBuffer = eman.decrypt(buffer); - } - - XXH64_update(xxhState, rawBuffer.data(), rawBuffer.size()); - file.write(reinterpret_cast(rawBuffer.data()), chunkSize); - } - } + file.write(reinterpret_cast(rawBuffor.data()), rawBuffor.size()); file.close(); - - if (XXH64_digest(xxhState) != fh.crc) - { - std::cerr << dir.string() << " Error: Corrupted data integration CRC" << std::endl; - - } } std::cout << "Unpacking complete!" << std::endl; diff --git a/ExtractCargo.h b/ExtractCargo.h index 9fce5f5..9ee7e1f 100644 --- a/ExtractCargo.h +++ b/ExtractCargo.h @@ -28,12 +28,11 @@ #include #include #include -#include #include #include "DataStruct.h" +#include "ChunkManager.h" #include "EncryptionManager.h" -#include "CompressionManager.h" class ExtractCargo { public: @@ -48,8 +47,8 @@ private: uint32_t filesLen; uint64_t tablePosition; - XXH64_state_t* xxhState; + const int8_t version; const std::string signature; std::vector filesHeads; @@ -58,7 +57,7 @@ private: std::ifstream cargoFile; EncryptionManager eman; - CompressionManager cman; + // Sprawdzenie poprawności archiwum bool CheckCargoFile(); @@ -69,7 +68,13 @@ private: // Pobieranie nagłówków plików void LoadFilesTable(); + // Sprawdzanie sumy kontrolnej + bool HashValid(const std::vector&, const uint64_t&); + // Utwórz katalog void CreateDirections(std::filesystem::path); + // Magiczna funkcja do dekompresji i deszyfracji danych + void computingBytes(const std::vector&, std::vector&, const uint8_t&); + }; diff --git a/ViewCargo.cpp b/ViewCargo.cpp index 9b95d12..ed04866 100644 --- a/ViewCargo.cpp +++ b/ViewCargo.cpp @@ -59,7 +59,8 @@ bool ViewCargo::ViewFiles(const std::string& path) uint64_t tabPos = 0; uint32_t tabSize = 0; - std::vector magic(fl::sigpak.length()); + const std::string signature = SIGNATURE; + std::vector magic(signature.length()); int8_t cargoVer = 0; std::ifstream cargo(path, std::ios::binary); @@ -81,7 +82,7 @@ bool ViewCargo::ViewFiles(const std::string& path) cargo.read(reinterpret_cast(&tabSize), sizeof(tabSize)); //Sprawdź czy kontener ma poprawną sygnature - if (std::string(magic.begin(), magic.end()) != fl::sigpak) + if (std::string(magic.begin(), magic.end()) != signature) { std::cerr << "Error: Corrupted Cargo" << std::endl; cargo.close(); @@ -128,15 +129,15 @@ void ViewCargo::ShowFile(const std::string& file, const uint8_t& flag) // Ustawianie checkboxów switch (flag) { - case flag::zip: + case FILE_FLAG_COMPRESS: compresedCheck = "[x]"; break; - case flag::enc: + case FILE_FLAG_ENCRYPT: encryptedCheck = "[x]"; break; - case flag::ezd: + case FILE_FLAG_ZIPENC: compresedCheck = "[x]"; encryptedCheck = "[x]"; break; diff --git a/voidcmd.cpp b/voidcmd.cpp index 22e1520..1ba9020 100644 --- a/voidcmd.cpp +++ b/voidcmd.cpp @@ -80,16 +80,26 @@ static bool EmptyPath(std::string path) } int main(int argc, char* argv[]) { - std::cout << ui::title << std::endl << "ver. " << ui::ver << std::endl; - std::cout << "Author: Yanczi" << std::endl; - std::cout << "License: GNU LGPL v3" << "\n" << std::endl; + std::string path = ""; + + std::cout << + " 8888888b. d8888 888 d8P \n" + " 888 Y88b d88888 888 d8P \n" + " 888 888 d88P888 888 d8P \n" + " .d88b. 888 888 888 d88P d88P 888 888d88K \n" + "d8P Y8b `Y8bd8P' 8888888P\" d88P 888 8888888b \n" + "88888888 X88K 888 d88P 888 888 Y88b \n" + "Y8b. .d8\"\"8b. 888 d8888888888 888 Y88b \n" + " \"Y8888 888 888 888 d88P 888 888 Y88b\n" + << std::endl; + std::cout << "\n" << PROGRAM_VERSION << " Release " << PROGRAM_COMPILING << std::endl; + std::cout << "Author: " << PROGRAM_AUTHOR << std::endl; + std::cout << "License: " << PROGRAM_LICENSE << "\n" << std::endl; CreateCargo cargo; ExtractCargo extract; ViewCargo viewCargo; - std::string path = ""; - for (int i = 0; i < argc; ++i) { std::string arg = argv[i]; diff --git a/voidcmd.vcxproj b/voidcmd.vcxproj index ee82946..49f706f 100644 --- a/voidcmd.vcxproj +++ b/voidcmd.vcxproj @@ -132,6 +132,7 @@ + @@ -140,6 +141,7 @@ + diff --git a/voidcmd.vcxproj.filters b/voidcmd.vcxproj.filters index 4dec7bb..563ca03 100644 --- a/voidcmd.vcxproj.filters +++ b/voidcmd.vcxproj.filters @@ -27,6 +27,9 @@ Pliki ĹşrĂłdĹ‚owe + + Pliki ĹşrĂłdĹ‚owe + Pliki ĹşrĂłdĹ‚owe @@ -47,6 +50,9 @@ Pliki nagłówkowe + + Pliki nagłówkowe + Pliki nagłówkowe