diff --git a/.gitignore b/.gitignore index 92b3625..47fe4dc 100644 --- a/.gitignore +++ b/.gitignore @@ -367,4 +367,18 @@ test/ test2/ *.pak expak/ -x64/ \ No newline at end of file +x64/ +test.* +pest2.* +*.hh +*.key +test3/ +test4/ +test5/ +test6/ +test7/ +test8/ +test9/ +test10/ +testx/ +testv/ \ No newline at end of file diff --git a/CompressingManager.cpp b/ChunkManager.cpp similarity index 66% rename from CompressingManager.cpp rename to ChunkManager.cpp index 74d0b93..1579fb3 100644 --- a/CompressingManager.cpp +++ b/ChunkManager.cpp @@ -1,9 +1,10 @@ -#include "CompressingManager.h" +#include "ChunkManager.h" -CompressingManager::CompressingManager() +ChunkManager::ChunkManager(EncryptionManager& em) + :eman(em) { } -CompressingManager::~CompressingManager() +ChunkManager::~ChunkManager() { } //----------------------------------------------------------------------------- @@ -12,7 +13,7 @@ CompressingManager::~CompressingManager() // Dzielenie vectora na chunki dokładnie po 128KB // Kompresowanie chunków bez nagłówka //----------------------------------------------------------------------------- -std::vector CompressingManager::compress(const std::vector& raw) +std::vector ChunkManager::chunked(const std::vector& raw, const bool& compress, const bool& encrypt) { //std::vector blockSizes; @@ -34,25 +35,27 @@ std::vector CompressingManager::compress(const std::vector& raw) // Skopiuj fragment danych do chunka std::vector chunk(begin, end); - // Obliczanie rozmiaru skompresowanego bloku - int maxZipChunkSize = LZ4_compressBound(chunkSize); + std::vector outChunk; - // Buffor wyjściowy nadpisany skompresowanymi danymi - std::vector zipChunk(maxZipChunkSize); - - // Kompresja - int zipSize = LZ4_compress_default(chunk.data(), zipChunk.data(), chunkSize, maxZipChunkSize); - - // Zmiana rozmiaru do faktycznego rozmiaru po kompresji - zipChunk.resize(zipSize); + // 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 = chunk.size(); - uint32_t zch = zipChunk.size(); + uint32_t zch = outChunk.size(); //addIntToVector(compressedBlocks, chs); lastChunkRawSize = chs; addIntToVector(compressedBlocks, zch); - compressedBlocks.insert(compressedBlocks.end(), zipChunk.begin(), zipChunk.end()); + compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end()); blockLen++; } @@ -60,7 +63,7 @@ std::vector CompressingManager::compress(const std::vector& raw) 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(); + // uint16_t blockLen = blockSizes .size(); addIntToVector(zip, blockLen); addIntToVector(zip, maxBlockSize); addIntToVector(zip, lastChunkRawSize); @@ -76,7 +79,7 @@ std::vector CompressingManager::compress(const std::vector& raw) //----------------------------------------------------------------------------- // Dekompresja blokowa //----------------------------------------------------------------------------- -std::vector CompressingManager::decompress(const std::vector& zip) +std::vector ChunkManager::dechunked(const std::vector& zip, const bool& compress, const bool& encrypt) { size_t offset = 0; const uint16_t chunkLen = getIntFromVector(zip, offset); @@ -93,23 +96,15 @@ std::vector CompressingManager::decompress(const std::vector& zip) uint32_t chunkZipSize = getIntFromVector(zip, offset); // Pobierz blok chunka - std::vector zipChunk(chunkZipSize); - std::memcpy(zipChunk.data(), zip.data() + offset, chunkZipSize); + 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(chunkSize); - - // Dekompresja chunka - int sizeData = LZ4_decompress_safe(zipChunk.data(), chunk.data(), static_cast(chunkZipSize), static_cast(chunkSize)); - - if (sizeData < 0) - { - throw std::runtime_error("LZ4 Decompressing Error"); - } - - // Dostosowanie rozmiaru vectora po skompresowaniu - chunk.resize(sizeData); + std::vector chunk = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk); // Scal chunki chunksString.insert(chunksString.end(), chunk.begin(), chunk.end()); diff --git a/CompressingManager.h b/ChunkManager.h similarity index 67% rename from CompressingManager.h rename to ChunkManager.h index e3fd839..f7f662e 100644 --- a/CompressingManager.h +++ b/ChunkManager.h @@ -3,33 +3,30 @@ #include #include #include -#include #include #include #include +#include "EncryptionManager.h" +#include "CompressionManager.h" + #define BLOCK_SIZE 131072 // 128KB -struct BlockSize -{ - uint32_t raw; - uint32_t zip; -}; - -class CompressingManager +class ChunkManager { public: - CompressingManager(); - ~CompressingManager(); + ChunkManager(EncryptionManager& em); + ~ChunkManager(); // Kompresja danych - std::vector compress(const std::vector&); + std::vector chunked(const std::vector&, const bool&, const bool&); // Dekompresja - std::vector decompress(const std::vector&); + std::vector dechunked(const std::vector&, const bool&, const bool&); private: - std::vector blockSizes; + EncryptionManager eman; + CompressionManager cman; // Przekonwertuj zmienną na ciąg na vector template diff --git a/CompressionManager.cpp b/CompressionManager.cpp new file mode 100644 index 0000000..56825a4 --- /dev/null +++ b/CompressionManager.cpp @@ -0,0 +1,95 @@ +#include "CompressionManager.h" + +CompressionManager::CompressionManager() + :cctx(ZSTD_createCCtx()) + ,dctx(ZSTD_createDCtx()) +{ + // Tu ustawienia pod kompresję + const int level = COMPRESSION_LEVEL; + + // Ustawienia frameless + size_t rc = 0; + + // Wyłącza ramkę i przestawia strumień na czyste bloki + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless); + + // Wyłącza sumę kontrolną na poziomie ramki + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0); + + // Wyłącza zapisywanie „content size” w nagłówku ramki + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0); + + // Wyłącza zapisywanie identyfikatora słownika + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); + + // Ustawia poziom kompresji + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level); + + if (ZSTD_isError(rc)) { + std::cerr << "ZSTD_CCtx_setParameter error" << std::endl; + ZSTD_freeCCtx(cctx); + } + + /*====Tutaj Dekompresja=============================================================*/ + + size_t r = 0; + + // Przestawia dekompresję na czyste bloki bez nagłówka + r |= ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless); + if (ZSTD_isError(r)) + { + std::cerr << "ZSTD_DCtx_setParameter error" << std::endl; + ZSTD_freeDCtx(dctx); + } +} + +CompressionManager::~CompressionManager() +{ + ZSTD_freeCCtx(cctx); + ZSTD_freeDCtx(dctx); +} + +//----------------------------------------------------------------------------- +// Kompresja ZSTD frameless +//----------------------------------------------------------------------------- +std::vector CompressionManager::compress(const std::vector& input) +{ + // Obsługa pustego chunku: zwracamy pusty wynik (0 bajtów). + if (input.empty()) return {}; + + const size_t srcSize = input.size(); + + // Szacowanie rozmiaru skompresowanego vectoru + const size_t maxDst = ZSTD_compressBound(srcSize); + + std::vector out(maxDst); + + // Faktyczna kompresja + size_t written = ZSTD_compress2(cctx, out.data(), maxDst, + input.data(), srcSize); + + if (ZSTD_isError(written)) { + std::cerr << "ZSTD_compress error: " << ZSTD_getErrorName(written) << std::endl; + return {}; + } + + out.resize(written); + return out; +} + +//----------------------------------------------------------------------------- +// Dekompresja ZSTD +//----------------------------------------------------------------------------- +std::vector CompressionManager::decompress(const std::vector& input, const size_t& expected) +{ + std::vector output(expected); + + size_t dsize = ZSTD_decompressDCtx(dctx, output.data(), expected, input.data(), input.size()); + + if (ZSTD_isError(dsize)) { + std::cerr << "ZSTD_decompressDCtx error: " << ZSTD_getErrorName(dsize) << "\n"; + return {}; + } + + return output; +} \ No newline at end of file diff --git a/CompressionManager.h b/CompressionManager.h new file mode 100644 index 0000000..e49956a --- /dev/null +++ b/CompressionManager.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include +#define ZSTD_STATIC_LINKING_ONLY +#include + +#if ZSTD_VERSION_NUMBER < 10400 +#error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless" +#endif + +#define COMPRESSION_LEVEL 3 + +class CompressionManager +{ +public: + CompressionManager(); + ~CompressionManager(); + + std::vector compress(const std::vector&); + std::vector decompress(const std::vector&, const size_t&); + +private: + ZSTD_CCtx* cctx; + ZSTD_DCtx* dctx; +}; + diff --git a/CreateCargo.cpp b/CreateCargo.cpp index 40cfbe6..845a915 100644 --- a/CreateCargo.cpp +++ b/CreateCargo.cpp @@ -20,12 +20,12 @@ #include "CreateCargo.h" CreateCargo::CreateCargo() - :compressingFlag(false) - , filteringFlag(false) - , signature(SIGNATURE) + : signature(SIGNATURE) , extension(EXTENSION) , version(VERSION) + , methodFlags(0) , offset(0) + , hppKey(false) { // TODO Auto-generated constructor stub } @@ -38,12 +38,11 @@ CreateCargo::~CreateCargo() { //----------------------------------------------------------------------------- // Punk wejścia do tworzenia archivum //----------------------------------------------------------------------------- -bool CreateCargo::Create(const std::string& path, bool compress, bool filters) +bool CreateCargo::Create(const std::string& path, const int16_t& flag) { cargoFile = path + "." + extension; catalogPath = path; - compressingFlag = compress; - filteringFlag = filters; + methodFlags = flag; //Sprawdzanie pakowanego kontentu if (!std::filesystem::is_directory(path)) @@ -59,9 +58,9 @@ bool CreateCargo::Create(const std::string& path, bool compress, bool filters) } // Pobieranie listy plików wyjątków - if (filters) + if (flag == -1) { - std::string filterFile = path + ".txt"; + std::string filterFile = path + ".json"; if (!std::filesystem::exists(filterFile)) { std::cerr << "Error: Missing " << filterFile << " file!" << std::endl; @@ -88,6 +87,12 @@ bool CreateCargo::Create(const std::string& path, bool compress, bool filters) return false; } + // Zapisywanie klucza szyfrującego + if (flag == 2 || flag == 3 || encList.size() > 0) + { + crypt.saveKey(catalogPath, hppKey); + } + return true; } @@ -105,14 +110,35 @@ bool CreateCargo::GetFileList(const std::string& path) } else { - if (CheckIgnorePath(tmpPath)) + std::string fileRef = RemoveStartPath(PathToUnixLike(tmpPath)); + PathConf pc; + if (methodFlags > -1) { - filesList.push_back(PathToUnixLike(tmpPath)); + pc.path = PathToUnixLike(tmpPath); + pc.parameter = methodFlags; + filesPaths.push_back(pc); + } + else + { + if (!FindOnTheList(ignoreList, fileRef) || !CheckFileExtension(fileRef, ignoreList)) + { + if (FindOnTheList(zipList, fileRef) || CheckFileExtension(fileRef, zipList)) + { + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? 3 : 1; + } + else + { + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? 2 : 0; + } + pc.path = PathToUnixLike(tmpPath); + std::cout << pc.path << " - " << pc.parameter << std::endl; + filesPaths.push_back(pc); + } } } } - return filesList.size() > 0 ? true : false; + return filesPaths.size() > 0 ? true : false; } //----------------------------------------------------------------------------- @@ -160,35 +186,34 @@ CargoHead CreateCargo::CreateCargoHead(const uint32_t& filesLen, const uint64_t& //----------------------------------------------------------------------------- // Sprawdza czy plik znajduje się na liście //----------------------------------------------------------------------------- -uint8_t CreateCargo::CheckFileOnTheList(const std::string& path, std::vector& input, std::vector& output) +void CreateCargo::computingBytes(const int16_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 - CompressingManager cm; + ChunkManager cm(crypt); - if (filteringFlag) { - if (FilteringData(path)) - { - output = cm.compress(input); - return ZIP_FILE; - } - else - { - output = std::move(input); - return RAW_FILE; - } - } - - //Flaga aktywna kompresuje dane - if (compressingFlag) + switch (flag) { + case 1: + output = cm.chunked(input, true, false); + break; - output = cm.compress(input); - return ZIP_FILE; + case 2: + output = cm.chunked(input, false, true); + break; + + case 3: + output = cm.chunked(input, true, true); + break; + + case 4: + output = cm.chunked(input, false, false); + break; + + default: + output = std::move(input); + break; } - - output = std::move(input); - return RAW_FILE; } //----------------------------------------------------------------------------- @@ -200,7 +225,7 @@ std::vector CreateCargo::ComputingHeadFiles() CargoHead cargoHead = CreateCargoHead(0, 0); offset += cargoHead.signature.length() + sizeof(cargoHead.version) + sizeof(cargoHead.files) + sizeof(cargoHead.table); - //Zapisanie TMP nagłowka do pliku + //Zapisanie tymczasowego nagłowka jako rezerwacja miejsca cargo.write(cargoHead.signature.data(), cargoHead.signature.length()); cargo.write(reinterpret_cast(&cargoHead.version), sizeof(cargoHead.version)); cargo.write(reinterpret_cast(&cargoHead.files), sizeof(cargoHead.files)); @@ -208,41 +233,41 @@ std::vector CreateCargo::ComputingHeadFiles() std::vector filesTable; - //Tworzenie nagłówków plików - for (const auto& file : filesList) + //Tworzenie nagłówków plików jednocześnie zapisywanie plików + for (const auto& file : filesPaths) { - std::string path = PathToUnixLike(RemoveStartPath(file)); - std::ifstream f(file, std::ios::binary | std::ios::ate); + std::string path = PathToUnixLike(RemoveStartPath(file.path)); + std::ifstream f(file.path, std::ios::binary | std::ios::ate); //Obliczanie rozmiaru pliku size_t size = f.tellg(); f.seekg(0, std::ios::beg); //Wczytanie pliku do pamięci - std::vector buffor(size); - f.read(buffor.data(), size); + std::vector buffer(size); + f.read(buffer.data(), size); f.close(); //Tworzenie hashu CRC - uint64_t crc = XXH64(buffor.data(), buffor.size(), VERSION); + const uint64_t crc = XXH64(buffer.data(), buffer.size(), VERSION); //Kompresjia - std::vector zip; - uint8_t method = CheckFileOnTheList(path, buffor, zip); + std::vector pakBuffer; + computingBytes(file.parameter, buffer, pakBuffer); FilesTable ft; ft.nameFile = path; ft.nameLen = path.length(); ft.hashName = fnv64(path); ft.offset = offset; - ft.size = zip.size(); - ft.isZip = method; + ft.size = pakBuffer.size(); + ft.flag = file.parameter; ft.crc = crc; - cargo.write(reinterpret_cast(zip.data()), zip.size()); + cargo.write(reinterpret_cast(pakBuffer.data()), pakBuffer.size()); filesTable.push_back(ft); - offset += zip.size(); + offset += pakBuffer.size(); } return filesTable; } @@ -254,18 +279,32 @@ void CreateCargo::GetFilters(const std::string& filterFile) { std::cout << "Downloading the exception list" << std::endl; - Txtpp ff(filterFile); + std::ifstream file(filterFile); + nlohmann::json jslist; + file >> jslist; + file.close(); // Lista plików do skompresowania - zipList = ff.Get(KEY_ZIP); + if (jslist.contains(KEY_ZIP)) + { + zipList = jslist[KEY_ZIP].get>(); + } + + // Lista plików do zaszyfrowania + if (jslist.contains(KEY_ENCRYPT)) + { + encList = jslist[KEY_ENCRYPT].get>(); + } // Lista plików do pominięcia - ignoreList = ff.Get(KEY_IGNORE); + if (jslist.contains(KEY_IGNORE)) + { + ignoreList = jslist[KEY_IGNORE].get>(); + } - ff.Close(); + hppKey = jslist.value("keyhpp", false); } - //----------------------------------------------------------------------------- // Znajdź wskazany element na liście //----------------------------------------------------------------------------- @@ -275,33 +314,23 @@ bool CreateCargo::FindOnTheList(const std::vector& list, const std: return it == list.end() ? false : true; } -//----------------------------------------------------------------------------- -// Rozdzielanie paternu od ścieżki -//----------------------------------------------------------------------------- -void CreateCargo::ExtPatternAndPathDetection(const std::vector& data, std::vector& pattern, std::vector& path) -{ - for (const auto& d : data) - { - if (d.front() == '*') - { - std::string tmpPattern = d; - tmpPattern.erase(tmpPattern.begin()); - pattern.push_back(UpperString(tmpPattern)); - } - else - { - path.push_back(d); - } - } -} - //----------------------------------------------------------------------------- // Sprawdzanie rozszeżeń plików //----------------------------------------------------------------------------- -bool CreateCargo::CheckFileExtension(const std::filesystem::path& p, const std::vector& patterns) { - std::string ext = UpperString(p.extension().string()); +bool CreateCargo::CheckFileExtension(const std::string& p, const std::vector& patterns) { + std::filesystem::path _p = p; + std::string ext = "*" + UpperString(_p.extension().string()); - return FindOnTheList(patterns, ext); + for (const auto& e : patterns) + { + std::string element = UpperString(e); + if (element == ext) + { + return true; + } + } + + return false; } //----------------------------------------------------------------------------- @@ -331,69 +360,6 @@ uint64_t CreateCargo::fnv64(const std::string& data) return hash; } -//----------------------------------------------------------------------------- -// Sprawdzanie czy plik znajduje się na liście -//----------------------------------------------------------------------------- -bool CreateCargo::FilteringData(const std::string& path) -{ - std::vector cmPatterns; - std::vector cmPaths; - - // Rozdziel ścieżki i patterny na osobne listy - ExtPatternAndPathDetection(zipList, cmPatterns, cmPaths); - - if (FindOnTheList(cmPatterns, ALL_FILE)) - { - return true; - } - - // Sprawdż czy istnieje plik o danym rozszeżeniu - if (CheckFileExtension(path, cmPatterns)) - { - return true; - } - - // Sprawdź czy instnieje dany plik w danej lokalizacji - if (FindOnTheList(cmPaths, path)) - { - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// Kasowanie z listy plików ignorow -//----------------------------------------------------------------------------- -bool CreateCargo::CheckIgnorePath(const std::string& path) -{ - std::vector igPatterns; - std::vector igPaths; - - ExtPatternAndPathDetection(ignoreList, igPatterns, igPaths); - - // Sprawdż czy istnieje plik o danym rozszeżeniu - if (CheckFileExtension(path, igPatterns)) - { - return false; - } - - // Obrubka ścierzki - // Usuwanie katalogu root - std::string cleanPath = RemoveStartPath(path); - - // Przekształcenie ścierzki na format unixowy - std::string unixPath = PathToUnixLike(cleanPath); - - // Sprawdź czy instnieje dany plik w danej lokalizacji - if (FindOnTheList(igPaths, unixPath)) - { - return false; - } - - return true; -} - //----------------------------------------------------------------------------- // Trworzenie archiwum //----------------------------------------------------------------------------- @@ -401,7 +367,7 @@ bool CreateCargo::WriteCargo() { std::cout << "Packing files..." << std::endl; - uint32_t filesLen = filesList.size(); + uint32_t filesLen = filesPaths.size(); //Przygotowanie nagłówków plików i przetworzenie danych std::vector filesHead = ComputingHeadFiles(); @@ -424,7 +390,7 @@ bool CreateCargo::WriteCargo() cargo.write(reinterpret_cast(&head.offset), sizeof(head.offset)); cargo.write(reinterpret_cast(&head.size), sizeof(head.size)); cargo.write(reinterpret_cast(&head.crc), sizeof(head.crc)); - cargo.write(reinterpret_cast(&head.isZip), sizeof(head.isZip)); + cargo.write(reinterpret_cast(&head.flag), sizeof(head.flag)); } //Cofnij się na początek pliku diff --git a/CreateCargo.h b/CreateCargo.h index 3f020f4..e11d253 100644 --- a/CreateCargo.h +++ b/CreateCargo.h @@ -25,29 +25,30 @@ #include #include #include -#include #include #include #include #include #include +#include #include "DataStruct.h" -#include "Txtpp.h" -#include "CompressingManager.h" +#include "ChunkManager.h" +#include "EncryptionManager.h" +#define KEY_ZIP "compress" // Pliki do skompresowania +#define KEY_RAW "raw" // Pliki które mają pozostać w oryginalnej formie +#define KEY_IGNORE "ignore" // Pliki pominięte przy pakowaniu +#define KEY_ENCRYPT "encrypt" // Plili które mają być zaszyfrowane +#define ALL_FILE ".*" // Wszystkie pliki -#define COMPRESSION_LEVEL 12 // Poziom kompresji plików (3 < 12) - -#define KEY_ZIP "COMPRESS" // Pliki do skompresowania -#define KEY_RAW "RAW" // Pliki które mają pozostać w oryginalnej formie -#define KEY_IGNORE "IGNORE" // Pliki pominięte przy pakowaniu -#define KEY_CRYPT "CRYPT" // Plili które mają być zaszyfrowane - -#define ALL_FILE ".*" // Wszystkie pliki - +struct PathConf +{ + std::string path; + int16_t parameter; +}; class CreateCargo { public: @@ -55,14 +56,14 @@ public: virtual ~CreateCargo(); // Punk wejścia do tworzenia archivum - bool Create(const std::string&, bool, bool); + bool Create(const std::string&, const int16_t&); private: - bool compressingFlag; - bool filteringFlag; const std::string signature; const std::string extension; - const uint8_t version; + const short version; + + short methodFlags; std::string catalogPath; @@ -71,11 +72,16 @@ private: std::vector filesList; - + EncryptionManager crypt; + bool hppKey; // listy wyjątków std::vector ignoreList; std::vector zipList; + std::vector encList; + + // Główna lista plików z parametrami + std::vector filesPaths; std::ofstream cargo; @@ -101,20 +107,14 @@ private: // Przygotowanie nagłówków i plików std::vector ComputingHeadFiles(); - // Sprawdzanie czy plik znajduje się na liście - bool FilteringData(const std::string&); - // Wczytanie filtrów wyjątków void GetFilters(const std::string&); // Sprawdza czy plik znajduje się na liście - uint8_t CheckFileOnTheList(const std::string&, std::vector&, std::vector&); - - // Kasowanie z listy plików ignorow - bool CheckIgnorePath(const std::string&); + void computingBytes(const int16_t&, std::vector&, std::vector&); // Sprawdzanie rozszeżeń plików - bool CheckFileExtension(const std::filesystem::path&, const std::vector&); + bool CheckFileExtension(const std::string&, const std::vector&); // Zamień cały ciąg na duże litery std::string UpperString(std::string); @@ -122,12 +122,6 @@ private: // Wygenerój FNV-1a HASH uint64_t fnv64(const std::string& data); - // CRC - uint32_t crc32(const std::vector&); - - // Rozdzielanie paternu od ścieżki - void ExtPatternAndPathDetection(const std::vector&, std::vector&, std::vector&); - // Znajdź wskazany element na liście bool FindOnTheList(const std::vector&, const std::string&); }; diff --git a/DataStruct.h b/DataStruct.h index 2579c79..d941faf 100644 --- a/DataStruct.h +++ b/DataStruct.h @@ -21,20 +21,29 @@ #include #include -#include - #define EXTENSION "pak" #define SIGNATURE "XPAK" -#define VERSION 100 +#define SIGNATURE_KEY_FILE 1497713496 // XKEY + +#define VERSION 300 + +enum StoreMethod +{ + FILTERING = -1, + RAW = 0, + COMPRESS = 1, + ENCRYPT = 2, + COMPRESSxENCRYPT = 3 +}; //Prgoram title #define PROGRAM_TITLE "eXtendet PAK" -#define PROGRAM_VERSION "v1.1" +#define PROGRAM_VERSION "v1.3" #define PROGRAM_AUTHOR "Yanczi" -#define PROGRAM_COMPILING "24 October 2025" +#define PROGRAM_COMPILING "16 November 2025" #define PROGRAM_LICENSE "GNU LGPL v3" //Limity @@ -50,18 +59,18 @@ struct CargoHead { std::string signature; - uint16_t version; + int16_t version; uint32_t files; uint64_t table; }; struct FilesTable { - uint8_t nameLen; + int16_t nameLen; std::string nameFile; uint64_t hashName; uint64_t offset; uint32_t size; uint64_t crc; - uint8_t isZip; + int16_t flag; }; \ No newline at end of file diff --git a/EncryptionManager.cpp b/EncryptionManager.cpp new file mode 100644 index 0000000..aa49bd8 --- /dev/null +++ b/EncryptionManager.cpp @@ -0,0 +1,181 @@ +#include "EncryptionManager.h" + +EncryptionManager::EncryptionManager() + :keyReady(false) +{ + if (sodium_init() < 0) { + throw std::runtime_error("libsodium init failed"); + } + + keyReady = false; + generateKeys(); +} + +std::vector EncryptionManager::encrypt(const std::vector& raw) +{ + std::array nonce_local; + randombytes_buf(nonce_local.data(), nonce_local.size()); + + std::vector tmp(raw.size()); + if (crypto_stream_chacha20_ietf_xor_ic( + reinterpret_cast(tmp.data()), + reinterpret_cast(raw.data()), + static_cast(raw.size()), + nonce_local.data(), 0, key.data()) != 0) + { + throw std::runtime_error("crypto_stream_chacha20_ietf_xor_ic failed"); + } + + std::vector output; + output.insert(output.end(), + reinterpret_cast(nonce_local.data()), + reinterpret_cast(nonce_local.data()) + nonce_local.size()); + + output.insert(output.end(), tmp.begin(), tmp.end()); + + return output; +} + +void EncryptionManager::generateKeys() +{ + if (keyReady) return; + + //randombytes_buf(key.data(), key.size()); + crypto_stream_chacha20_ietf_keygen(key.data()); + + keyReady = true; +} + +void EncryptionManager::saveKey(const std::string& path, bool hpp) +{ + const int sig = SIGNATURE_KEY_FILE; + const short ver = VERSION; + + // Wygeneruj time stamp + std::time_t now = std::time(nullptr); + const int time = static_cast(now); + + // Wygeneruj crc kluczy + std::vector keyVec(reinterpret_cast(key.data()), + reinterpret_cast(key.data()) + key.size()); + + 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(reinterpret_cast(&sig), sizeof(sig)); + 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)); + + file.close(); + + if (hpp) {saveCppHeadFile(path);} +} + +// Generowanie pliku nagłówkowego CPP z kluczem i nonce +void EncryptionManager::saveCppHeadFile(const std::string& path) +{ + const uint32_t keySize = crypto_stream_chacha20_ietf_KEYBYTES; + + std::ofstream file(path + ".hpp"); + + file << "// Plik wygenerowany przez " << PROGRAM_TITLE << " " << PROGRAM_VERSION << std::endl; + file << std::endl; + file << std::endl; + file << "#pragma once" << std::endl; + file << "#include " << std::endl; + file << "#include " << std::endl; + file << std::endl; + file << "namespace enc" << std::endl; + file << "{" << std::endl; + file << " // Klucz deszyfrujący" << std::endl; + file << " const std::array key{" << std::endl; + file << " " << toHex(key.data(), key.size()) << std::endl; + file << " };" << std::endl; + file << std::endl; + file << "} //namespace" << std::endl; + + file.close(); +} + +std::string EncryptionManager::toHex(const unsigned char* data, size_t len) +{ + std::ostringstream oss; + oss << std::hex << std::setfill('0'); + for (size_t i = 0; i < len; ++i) { + oss << "0x" << std::setw(2) << static_cast(data[i]); + if (i + 1 != len) oss << ", "; + if ((i + 1) % 12 == 0 && i + 1 != len) oss << "\n "; + } + return oss.str(); +} + +// Wczytaj klucz +void EncryptionManager::loadKey(const std::string& path) +{ + std::ifstream file(path + ".key", std::ios::binary); + + int sig; + short ver; + int time; + + // Wczytaj + file.read(reinterpret_cast(&sig), sizeof(sig)); + file.read(reinterpret_cast(&ver), sizeof(ver)); + + // Sprawdź czy plik klucza jest poprawny + if (sig != SIGNATURE_KEY_FILE || ver != VERSION) + { + throw std::runtime_error("Invalid key file!"); + } + + std::vector keyVec(key.size()); + uint64_t crcKey; + + file.read(reinterpret_cast(&time), sizeof(time)); + file.read(keyVec.data(), keyVec.size()); + file.read(reinterpret_cast(&crcKey), sizeof(crcKey)); + + // Sprawdź integralność klucza + if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey) + { + throw std::runtime_error("Key integrity error!"); + } + + file.close(); + + // Przekonwertuj vector na array + key = toArray(keyVec); +} + +// Deszyfracja +std::vector EncryptionManager::decrypt(const std::vector& crypt) +{ + const size_t cryptoSize = crypto_stream_chacha20_ietf_NONCEBYTES; + + std::array nonce_local; + std::memcpy(nonce_local.data(), + reinterpret_cast(crypt.data()), cryptoSize); + + + const size_t rawSize = crypt.size() - cryptoSize; + std::vector tmp(rawSize); + std::memcpy(tmp.data(), crypt.data() + cryptoSize, rawSize); + + std::vector raw(rawSize); + + if (crypto_stream_chacha20_ietf_xor( + reinterpret_cast(raw.data()), + reinterpret_cast(tmp.data()), + static_cast(tmp.size()), + nonce_local.data(), key.data()) != 0) + { + throw std::runtime_error("Data decryption error!"); + } + + return raw; +} \ No newline at end of file diff --git a/EncryptionManager.h b/EncryptionManager.h new file mode 100644 index 0000000..61a03e4 --- /dev/null +++ b/EncryptionManager.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DataStruct.h" + +class EncryptionManager +{ +public: + EncryptionManager(); + ~EncryptionManager() = default; + + std::vector encrypt(const std::vector&); + std::vector decrypt(const std::vector&); + + void saveKey(const std::string&, bool); + void loadKey(const std::string&); + +private: + std::array key{}; + bool keyReady; + + void generateKeys(); + std::string toHex(const unsigned char*, size_t); + void saveCppHeadFile(const std::string&); + + template + std::array toArray(const std::vector& vec) { + if (vec.size() < N) { + throw std::runtime_error("Too small vector to convert to array"); + } + + std::array arr{}; + std::memcpy(arr.data(), vec.data(), N); + return arr; + } +}; \ No newline at end of file diff --git a/ExtractCargo.cpp b/ExtractCargo.cpp index bf5e028..4b3e0be 100644 --- a/ExtractCargo.cpp +++ b/ExtractCargo.cpp @@ -45,6 +45,8 @@ bool ExtractCargo::Extract(const std::string& cFile) { cargoFileName = cFile; + std::cout << "START EXTRACT " << cFile << std::endl; + //Sprawdź czy plik istnieje if (!std::filesystem::exists(cargoFileName)) { @@ -59,6 +61,14 @@ bool ExtractCargo::Extract(const std::string& cFile) return false; } + // Wczytaj klucz deszyfrujący + std::filesystem::path kdir = cargoFileName.stem(); + if (std::filesystem::exists(kdir.string() + ".key")) + { + std::cout << "Decryption key detected" << std::endl; + eman.loadKey(kdir.string()); + } + //Otwieranie kontenera cargoFile.open(cargoFileName, std::ios::binary); @@ -79,7 +89,7 @@ bool ExtractCargo::Extract(const std::string& cFile) bool ExtractCargo::CheckCargoFile() { std::vector magic(signature.size()); - uint16_t cargoVer = 0; + short cargoVer = 0; if (!cargoFile.is_open()) { @@ -92,8 +102,6 @@ bool ExtractCargo::CheckCargoFile() cargoFile.read(reinterpret_cast(&filesLen), sizeof(filesLen)); cargoFile.read(reinterpret_cast(&tablePosition), sizeof(tablePosition)); - std::cout << std::string(magic.begin(), magic.end()) << std::endl; - if (std::string(magic.begin(), magic.end()) != signature) { std::cerr << "Error: Corrupted Cargo" << std::endl; @@ -126,13 +134,43 @@ bool ExtractCargo::HashValid(const std::vector& data, const uint64_t& crc) return true; } +//----------------------------------------------------------------------------- +// Magiczna funkcja do dekompresji i deszyfracji danych +//----------------------------------------------------------------------------- +void ExtractCargo::computingBytes(const std::vector& input, std::vector& output, const int16_t& flag) +{ + ChunkManager cm(eman); + + switch (flag) + { + case 1: + output = cm.dechunked(input, true, false); + break; + + case 2: + output = cm.dechunked(input, false, true); + break; + + case 3: + output = cm.dechunked(input, true, true); + break; + + case 4: + output = cm.dechunked(input, false, false); + break; + + default: + output = input; + break; + } +} + //----------------------------------------------------------------------------- // Pobieranie nagłówków plików //----------------------------------------------------------------------------- void ExtractCargo::LoadFilesTable() { cargoFile.seekg(tablePosition); - for (uint32_t i = 0; i < filesLen; ++i) { FilesTable fhTmp; @@ -146,7 +184,7 @@ void ExtractCargo::LoadFilesTable() cargoFile.read(reinterpret_cast(&fhTmp.offset), sizeof(fhTmp.offset)); cargoFile.read(reinterpret_cast(&fhTmp.size), sizeof(fhTmp.size)); cargoFile.read(reinterpret_cast(&fhTmp.crc), sizeof(fhTmp.crc)); - cargoFile.read(reinterpret_cast(&fhTmp.isZip), sizeof(fhTmp.isZip)); + cargoFile.read(reinterpret_cast(&fhTmp.flag), sizeof(fhTmp.flag)); filesHeads.push_back(fhTmp); } @@ -157,8 +195,6 @@ void ExtractCargo::LoadFilesTable() //----------------------------------------------------------------------------- void ExtractCargo::ExtractingFilesFromCargo() { - CompressingManager cm; - for (const auto& fh : filesHeads) { std::filesystem::path dir = cargoFileName.stem() / fh.nameFile; @@ -170,7 +206,8 @@ void ExtractCargo::ExtractingFilesFromCargo() cargoFile.read(buffor.data(), fh.size); - std::vector rawBuffor = fh.isZip ? cm.decompress(buffor) : buffor; + std::vector rawBuffor; + computingBytes(buffor, rawBuffor, fh.flag); if (!HashValid(rawBuffor, fh.crc)) { diff --git a/ExtractCargo.h b/ExtractCargo.h index e7d89b3..0681494 100644 --- a/ExtractCargo.h +++ b/ExtractCargo.h @@ -31,7 +31,8 @@ #include #include "DataStruct.h" -#include "CompressingManager.h" +#include "ChunkManager.h" +#include "EncryptionManager.h" class ExtractCargo { public: @@ -46,9 +47,9 @@ private: uint32_t filesLen; uint64_t tablePosition; - uint8_t filesHeadsOffset; + int filesHeadsOffset; - const uint8_t version; + const short version; const std::string signature; std::vector filesHeads; @@ -56,6 +57,7 @@ private: std::ifstream cargoFile; + EncryptionManager eman; // Sprawdzenie poprawności archiwum @@ -73,4 +75,7 @@ private: // Utwórz katalog void CreateDirections(std::filesystem::path); + // Magiczna funkcja do dekompresji i deszyfracji danych + void computingBytes(const std::vector&, std::vector&, const int16_t&); + }; diff --git a/README.md b/README.md index 3d1d178..704bf0a 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,11 @@ +**libsodium - https://github.com/jedisct1/libsodium** + **xxHash - https://github.com/Cyan4973/xxHash.git** -**LZ4 - https://github.com/lz4/lz4.git** +**Zstd - https://github.com/facebook/zstd.git** **FTXUI - https://github.com/ArthurSonzogni/FTXUI.git** diff --git a/TimeStamp.h b/TimeStamp.h new file mode 100644 index 0000000..b862f6e --- /dev/null +++ b/TimeStamp.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +class TimeStamp +{ +public: + TimeStamp() + :time(std::time(nullptr)) + {} + ~TimeStamp() = default; + + uint32_t get() + { +#if defined(_WIN32) localtime_s(<, &time); +#else localtime_r(<, &time); +#endif + + uint16_t d = dosDate(lt); + uint16_t t = dosTime(lt); + + uint32_t combined = ((uint32_t)d << 16) | t; + return combined; + } + +private: + std::time_t time; + std::tm lt{}; + + uint16_t dosDate(const std::tm& t) + { + int year = t.tm_year + 1900; + int y = (year >= 1980) ? (year - 1980) : 0; + int m = t.tm_mon + 1; + int d = t.tm_mday; + return static_cast((y << 9) | (m << 5) | d); + } + + uint16_t dosTime(const std::tm& t) + { + int h = t.tm_hour; + int min = t.tm_min; + int s2 = t.tm_sec / 2; + return static_cast((h << 11) | (min << 5) | s2); + } +}; \ No newline at end of file diff --git a/Txtpp.h b/Txtpp.h deleted file mode 100644 index 70940bb..0000000 --- a/Txtpp.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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 - -class Txtpp { -public: - Txtpp(const std::string& path = "") - { - if (path != "") - { - Load(path); - } - } - - ~Txtpp() - { - if (file.is_open()) - { - file.close(); - } - } - - bool Load(const std::string& path) - { - if (!std::filesystem::exists(path)) - { - return false; - } - - file.open(path); - - return file.is_open(); - } - - void Close() - { - file.close(); - } - - std::vector Get(const std::string& key) - { - std::vector tmp; - Parse(key, tmp); - return tmp; - } - - template - T getValue(const std::string& key, const std::string& val) - { - std::vector tmp; - Parse(key, tmp); - - for (const auto& line : tmp) - { - std::string cleanLine = RemoveSpaces(line); - std::string t; - std::string v; - - bool tv = false; - - for (const char& c : cleanLine) - { - if (c != ":") {tv = true;} - - if (!tv) { t += c; } - else { v += c; } - } - } - - return tmp; - } - -private: - const char sectionStart = '{'; - const char sectionEnd = '}'; - - std::ifstream file; - - //----------------------------------------------------------------------------- - // Wyszukiwanie danych po kluczu - //----------------------------------------------------------------------------- - void Parse(const std::string& key, std::vector& data) - { - std::string fullkey = sectionStart + key + sectionEnd; - std::string line; - bool wr = false; - - file.clear(); - file.seekg(std::ios::beg); - - while (getline(file, line)) - { - std::string tmp = RemoveSpaces(line); - if (tmp != "") - { - if (CheckKey(tmp)) - { - wr = UpperString(tmp) == fullkey ? true : false; - } - else - { - if (wr) { data.push_back(tmp); } - } - } - } - } - - //----------------------------------------------------------------------------- - // Usuwa spacje - //----------------------------------------------------------------------------- - std::string RemoveSpaces(std::string _line) - { - std::stringstream ss(_line); - char word; - std::string tmp; - std::string beforeWord = ""; - - while (ss >> word) - { - tmp += word; - } - - return tmp; - } - - //----------------------------------------------------------------------------- - // Sprawdza czy dany ciąg jest kluczem - //----------------------------------------------------------------------------- - bool CheckKey(std::string key) - { - if (key[0] == sectionStart && key[key.length() - 1]) - { - return true; - } - return false; - } - - //----------------------------------------------------------------------------- - // Zamień cały ciąg na duże litery - //----------------------------------------------------------------------------- - std::string UpperString(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return static_cast(std::toupper(c)); }); - return s; - } -}; - diff --git a/ViewCargo.cpp b/ViewCargo.cpp index 2a2860e..6eafe9c 100644 --- a/ViewCargo.cpp +++ b/ViewCargo.cpp @@ -58,7 +58,8 @@ bool ViewCargo::View(const std::string& path) //Table Header std::vector headElements; - headElements.push_back(ftxui::text(" Zip ") | ftxui::bold); + headElements.push_back(ftxui::text(" Compressed ") | ftxui::bold); + headElements.push_back(ftxui::text(" Encrypted ") | ftxui::bold); headElements.push_back(ftxui::text("Nazwa pliku") | ftxui::bold | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 56)); headElements.push_back(ftxui::text("Hash Name") | ftxui::bold | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 20)); @@ -80,7 +81,7 @@ bool ViewCargo::View(const std::string& path) bool ViewCargo::CheckCargoFile(const std::string& path) { std::vector magic(signature.length()); - uint16_t cargoVer = 0; + short cargoVer = 0; std::ifstream cargo(path, std::ios::binary); @@ -143,10 +144,10 @@ void ViewCargo::GetFileList(const std::string& path) cargo.read(reinterpret_cast(&fhTmp.offset), sizeof(fhTmp.offset)); cargo.read(reinterpret_cast(&fhTmp.size), sizeof(fhTmp.size)); cargo.read(reinterpret_cast(&fhTmp.crc), sizeof(fhTmp.crc)); - cargo.read(reinterpret_cast(&fhTmp.isZip), sizeof(fhTmp.isZip)); + cargo.read(reinterpret_cast(&fhTmp.flag), sizeof(fhTmp.flag)); //Tworzenie wierszy tabeli - CreateTableRow(fhTmp.nameFile, fhTmp.isZip, fhTmp.hashName); + CreateTableRow(fhTmp.nameFile, fhTmp.flag, fhTmp.hashName); } cargo.close(); @@ -164,19 +165,35 @@ void ViewCargo::CreateTableRow(const std::string& file, const uint8_t& zip, cons std::vector cell; ftxui::Element eZip; + ftxui::Element eEnc; - //Dodawanie check boxa czy plik jest spakowany czy nie - if (zip == 1) + // Ustawianie checkboxów + switch (zip) { + case 1: eZip = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); - } - else - { + eEnc = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + break; + + case 2: eZip = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + eEnc = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); + break; + + case 3: + eZip = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); + eEnc = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); + break; + + default: + eZip = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + eEnc = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + break; } //Dodawanie komurek cell.push_back(eZip); + cell.push_back(eEnc | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 7)); cell.push_back(ftxui::text(file) | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 56)); cell.push_back(ftxui::text(ss.str()) | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 20)); diff --git a/license/libsodium/LICENSE.txt b/license/libsodium/LICENSE.txt new file mode 100644 index 0000000..bb85d39 --- /dev/null +++ b/license/libsodium/LICENSE.txt @@ -0,0 +1,19 @@ +/* + * ISC License + * + * Copyright (c) 2013-2025 + * Frank Denis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/license/xxhash/LICENSE.txt b/license/xxhash/LICENSE.txt new file mode 100644 index 0000000..52b4c4e --- /dev/null +++ b/license/xxhash/LICENSE.txt @@ -0,0 +1,26 @@ +xxHash Library +Copyright (c) 2012-2021 Yann Collet +All rights reserved. + +BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/voidcmd.cpp b/voidcmd.cpp index bd326ff..c719bae 100644 --- a/voidcmd.cpp +++ b/voidcmd.cpp @@ -40,34 +40,35 @@ void RenderHelp() const std::string HelpInstruction = "pakcmd \n" " \n" - " -c Pack and compress with LZ4 \n" - " -p Pack files from the specified directory \n" - " -e Pack and encrypted from the specified directory \n" - " -f Pack the files according to the guidelines given in the .txt \n" + " -c Compressing \n" + " -r Raw files \n" + " -e Encrypted \n" + " -s Compressing and Encrypted \n" + " -f Pack the files according to the guidelines given in the .json \n" " \n" "Extracting: \n" " -x Extract files from the specified container \n" + " \n" + "Others: \n" " -ls List files stored in a container \n" " \n" - " \n" - ".txt \n" + ".json \n" " \n" "Keys: \n" " \n" - " {compress} - Compressing files \n" - " {crypt} - Encrypted files with AES256 \n" + " {compress} - Compressing files \n" + " {crypt} - Encrypted files \n" " {ignore} - Ignoring concrete files \n" " \n" " /path/to/file.ext - Concrete file \n" " *.ext - All files with concrete extension \n" - " *.* - All files !NOT WORKING WITH {ignore} KEY! \n" - " \n"; + " *.* - All files !NOT WORKING WITH {ignore} KEY! \n"; - Interface tui; - tui.TextBorder(HelpTitle, HelpInstruction); + //Interface tui; + //tui.TextBorder(HelpTitle, HelpInstruction); } -bool EmptyPath(std::string path) +static bool EmptyPath(std::string path) { if (path == "") { @@ -109,17 +110,37 @@ int main(int argc, char* argv[]) { if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, true, false)) + if (!cargo.Create(path, 1)) { return 1; } i++; } - if (arg == "-p" && i + 1 < argc) + if (arg == "-r" && i + 1 < argc) { path = argv[i + 1]; - if (!cargo.Create(path, false, false)) + if (!cargo.Create(path, 0)) + { + return 1; + } + i++; + } + + if (arg == "-e" && i + 1 < argc) + { + path = argv[i + 1]; + if (!cargo.Create(path, 2)) + { + return 1; + } + i++; + } + + if (arg == "-s" && i + 1 < argc) + { + path = argv[i + 1]; + if (!cargo.Create(path, 3)) { return 1; } @@ -130,7 +151,7 @@ int main(int argc, char* argv[]) { { path = argv[i + 1]; if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, false, true)) + if (!cargo.Create(path, -1)) { return 1; } diff --git a/voidcmd.vcxproj b/voidcmd.vcxproj index 35415ae..cd5c1f3 100644 --- a/voidcmd.vcxproj +++ b/voidcmd.vcxproj @@ -104,13 +104,13 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp17 - 3rd\crc\include;3rd\ftxui\include;3rd\lz4\include + 3rd\ftxui\include;3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\include;3rd\xxhash\include Console true - 3rd\ftxui\Debug;3rd\lz4\lib - liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib + 3rd\zstd\lib\Debug;3rd\ftxui\Debug;3rd\xxhash\lib\Debug;3rd\libsodium\lib\Debug + ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib;zstd_static.lib;xxhash.lib @@ -122,30 +122,33 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp17 - 3rd\crc\include;3rd\ftxui\include;3rd\lz4\include + 3rd\ftxui\include;3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\include; Console true - 3rd\ftxui\Release;3rd\lz4\lib - liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib + 3rd\zstd\lib\Release;3rd\libsodium\lib\Release;3rd\xxhash\lib\Release;3rd\ftxui\Release + ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib;zstd_static.lib;xxhash.lib - + + + - + + + - diff --git a/voidcmd.vcxproj.filters b/voidcmd.vcxproj.filters index b2edffa..d4a64b3 100644 --- a/voidcmd.vcxproj.filters +++ b/voidcmd.vcxproj.filters @@ -27,13 +27,16 @@ Pliki ĹşrĂłdĹ‚owe - - Pliki ĹşrĂłdĹ‚owe - Pliki ĹşrĂłdĹ‚owe - + + Pliki ĹşrĂłdĹ‚owe + + + Pliki ĹşrĂłdĹ‚owe + + Pliki ĹşrĂłdĹ‚owe @@ -47,19 +50,19 @@ Pliki nagłówkowe - - Pliki nagłówkowe - Pliki nagłówkowe - - Pliki nagłówkowe - Pliki nagłówkowe - + + Pliki nagłówkowe + + + Pliki nagłówkowe + + Pliki nagłówkowe diff --git a/xxhash.dll b/xxhash.dll new file mode 100644 index 0000000..4ee9ba0 Binary files /dev/null and b/xxhash.dll differ