diff --git a/.gitignore b/.gitignore index 47fe4dc..1b9f212 100644 --- a/.gitignore +++ b/.gitignore @@ -371,14 +371,4 @@ x64/ test.* pest2.* *.hh -*.key -test3/ -test4/ -test5/ -test6/ -test7/ -test8/ -test9/ -test10/ -testx/ -testv/ \ No newline at end of file +*.key \ No newline at end of file diff --git a/CompressingManager.cpp b/CompressingManager.cpp new file mode 100644 index 0000000..74d0b93 --- /dev/null +++ b/CompressingManager.cpp @@ -0,0 +1,119 @@ +#include "CompressingManager.h" + +CompressingManager::CompressingManager() +{ } + +CompressingManager::~CompressingManager() +{ } + +//----------------------------------------------------------------------------- +// Kompresja blokowa +// +// Dzielenie vectora na chunki dokładnie po 128KB +// Kompresowanie chunków bez nagłówka +//----------------------------------------------------------------------------- +std::vector CompressingManager::compress(const std::vector& raw) +{ + //std::vector blockSizes; + + // Maksymalny rozmiar chunka + const size_t maxBlockSize = BLOCK_SIZE; + const size_t rawSize = raw.size(); + + uint16_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); + + // Obliczanie rozmiaru skompresowanego bloku + int maxZipChunkSize = LZ4_compressBound(chunkSize); + + // 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); + + uint32_t chs = chunk.size(); + uint32_t zch = zipChunk.size(); + + //addIntToVector(compressedBlocks, chs); + lastChunkRawSize = chs; + addIntToVector(compressedBlocks, zch); + compressedBlocks.insert(compressedBlocks.end(), zipChunk.begin(), zipChunk.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 CompressingManager::decompress(const std::vector& zip) +{ + size_t offset = 0; + const uint16_t chunkLen = getIntFromVector(zip, offset); + const uint32_t chunkBeforeSize = getIntFromVector(zip, offset); + const uint32_t chunkLastSize = getIntFromVector(zip, offset); + + 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 zipChunk(chunkZipSize); + std::memcpy(zipChunk.data(), zip.data() + offset, chunkZipSize); + offset += chunkZipSize; + + // 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); + + // Scal chunki + chunksString.insert(chunksString.end(), chunk.begin(), chunk.end()); + } + + return chunksString; +} \ No newline at end of file diff --git a/CompressingManager.h b/CompressingManager.h new file mode 100644 index 0000000..e3fd839 --- /dev/null +++ b/CompressingManager.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 131072 // 128KB + +struct BlockSize +{ + uint32_t raw; + uint32_t zip; +}; + +class CompressingManager +{ +public: + CompressingManager(); + ~CompressingManager(); + + // Kompresja danych + std::vector compress(const std::vector&); + + // Dekompresja + std::vector decompress(const std::vector&); + +private: + std::vector blockSizes; + + // 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 deleted file mode 100644 index 0c934b8..0000000 --- a/CompressionManager.cpp +++ /dev/null @@ -1,111 +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 . - */ - -#include "CompressionManager.h" - -CompressionManager::CompressionManager() - :cctx(ZSTD_createCCtx()) - ,dctx(ZSTD_createDCtx()) -{ - // 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, zstd::compression_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 deleted file mode 100644 index 5f747fb..0000000 --- a/CompressionManager.h +++ /dev/null @@ -1,51 +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 -#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 - -namespace zstd -{ - inline constexpr short 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 fe6f7aa..cac09a2 100644 --- a/CreateCargo.cpp +++ b/CreateCargo.cpp @@ -20,15 +20,13 @@ #include "CreateCargo.h" CreateCargo::CreateCargo() - : signature(fl::sigpak) - , extension(fl::extpak) + : signature(SIGNATURE) + , extension(EXTENSION) + , version(VERSION) , methodFlags(0) - , xxhState(XXH64_createState()) , offset(0) - , hppKey(false) { // TODO Auto-generated constructor stub - XXH64_reset(xxhState, 0); } CreateCargo::~CreateCargo() { @@ -39,7 +37,7 @@ CreateCargo::~CreateCargo() { //----------------------------------------------------------------------------- // Punk wejścia do tworzenia archivum //----------------------------------------------------------------------------- -bool CreateCargo::Create(const std::string& path, const uint8_t& flag) +bool CreateCargo::Create(const std::string& path, int8_t flag) { cargoFile = path + "." + extension; catalogPath = path; @@ -58,6 +56,14 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) return false; } + //Pobieranie listy plików do spakowania + std::cout << "Creating a file list..." << std::endl; + if (!GetFileList(path)) + { + std::cerr << "Error: The specified directory contains no files!" << std::endl; + return false; + } + // Pobieranie listy plików wyjątków if (flag == -1) { @@ -70,14 +76,6 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) GetFilters(filterFile); } - //Pobieranie listy plików do spakowania - std::cout << "Creating a file list..." << std::endl; - if (!GetFileList(path)) - { - std::cerr << "Error: The specified directory contains no files!" << std::endl; - return false; - } - // Utworzenie kontenera cargo.open(cargoFile, std::ios::binary); @@ -88,12 +86,6 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) return false; } - // Zapisywanie klucza szyfrującego - if (flag == flag::enc || flag == flag::ezd || encList.size() > 0) - { - eman.saveKey(catalogPath, hppKey); - } - return true; } @@ -111,43 +103,14 @@ bool CreateCargo::GetFileList(const std::string& path) } else { - std::string fileRef = RemoveStartPath(PathToUnixLike(tmpPath)); - - if (fileRef.length() > 255) + if (CheckIgnorePath(tmpPath)) { - std::cerr << "The file path is too long. It exceeds 255 characters." << std::endl; - } - else - { - PathConf pc; - if (methodFlags != 0xAB) - { - 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) ? flag::ezd : flag::zip; - } - else - { - pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? flag::enc : flag::raw; - } - pc.path = PathToUnixLike(tmpPath); - std::cout << pc.path << " - " << pc.parameter << std::endl; - filesPaths.push_back(pc); - } - } + filesList.push_back(PathToUnixLike(tmpPath)); } } } - return filesPaths.size() > 0 ? true : false; + return filesList.size() > 0 ? true : false; } //----------------------------------------------------------------------------- @@ -184,13 +147,49 @@ CargoHead CreateCargo::CreateCargoHead(const uint32_t& filesLen, const uint64_t& { CargoHead ch; - ch.signature = fl::sigpak; - ch.table = table; + ch.signature = signature; + ch.version = version; ch.files = filesLen; + ch.table = table; return ch; } +//----------------------------------------------------------------------------- +// Sprawdza czy plik znajduje się na liście +//----------------------------------------------------------------------------- +uint8_t CreateCargo::CheckFileOnTheList(const std::string& path, 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; + + // Kompresja + if (methodFlags == 1) + { + output = cm.compress(input); + return 1; + } + + // Szyfrowanie + if (methodFlags == 2) + { + output = crypt.encrypt(input); + return 2; + } + + // Kompresja i szyfrowanie + if (methodFlags == 3) + { + output = crypt.encrypt(cm.compress(input)); + return 1; + } + + // Zwraca surowe dane + output = std::move(input); + return 0; +} + //----------------------------------------------------------------------------- // Przygotowanie nagłówków i plików //----------------------------------------------------------------------------- @@ -198,123 +197,52 @@ std::vector CreateCargo::ComputingHeadFiles() { //Utwórz header TMP. Zabezpiecza Pierwsze bajty na właściwy nagłówek CargoHead cargoHead = CreateCargoHead(0, 0); - offset += cargoHead.signature.length() + sizeof(cargoHead.files) + sizeof(cargoHead.table); + offset += cargoHead.signature.length() + sizeof(cargoHead.version) + sizeof(cargoHead.files) + sizeof(cargoHead.table); - //Zapisanie tymczasowego nagłowka jako rezerwacja miejsca + //Zapisanie TMP nagłowka do pliku cargo.write(cargoHead.signature.data(), cargoHead.signature.length()); - cargo.write(reinterpret_cast(&cargoHead.table), sizeof(cargoHead.table)); + cargo.write(reinterpret_cast(&cargoHead.version), sizeof(cargoHead.version)); cargo.write(reinterpret_cast(&cargoHead.files), sizeof(cargoHead.files)); + cargo.write(reinterpret_cast(&cargoHead.table), sizeof(cargoHead.table)); std::vector filesTable; - //Tworzenie nagłówków plików jednocześnie zapisywanie plików - for (const auto& file : filesPaths) + //Tworzenie nagłówków plików + for (const auto& file : filesList) { - std::string path = PathToUnixLike(RemoveStartPath(file.path)); - std::ifstream f(file.path, std::ios::binary | std::ios::ate); - - std::cout << path << std::endl; + std::string path = PathToUnixLike(RemoveStartPath(file)); + std::ifstream f(file, std::ios::binary | std::ios::ate); //Obliczanie rozmiaru pliku size_t size = f.tellg(); f.seekg(0, std::ios::beg); - if (size > ds::maxFileSize) - { - std::cerr << path << " is too large. It exceeds " << ds::maxFileSize / 1024 / 1024 / 1024 << "GB!" << std::endl; - } - else - { - XXH64_reset(xxhState, 0); + //Wczytanie pliku do pamięci + std::vector buffor(size); + f.read(buffor.data(), size); + f.close(); - //Wczytanie pliku do pamięci - std::vector buffer(ds::chunk_stream); + //Tworzenie hashu CRC + const uint64_t crc = XXH64(buffor.data(), buffor.size(), VERSION); - uint64_t sizeFile = 0; + //Kompresjia + std::vector zip; + uint8_t method = CheckFileOnTheList(path, buffor, zip); - const uint32_t chunkBlockSize = ds::block_size; - const uint32_t quantity = (size + chunkBlockSize) / chunkBlockSize; - const uint32_t lastChunkSize = size - (chunkBlockSize * (quantity - 1)); + FilesTable ft; + ft.nameFile = path; + ft.nameLen = path.length(); + ft.hashName = fnv64(path); + ft.offset = offset; + ft.size = zip.size(); + ft.isZip = method; + ft.crc = crc; - // Jeśli jest ustawiona flaga inna niż RAW - // Dodaj do kontenera konfigurację chunków - if (file.parameter != flag::raw) - { - cargo.write(reinterpret_cast(&quantity), sizeof(quantity)); - cargo.write(reinterpret_cast(&chunkBlockSize), sizeof(chunkBlockSize)); - cargo.write(reinterpret_cast(&lastChunkSize), sizeof(lastChunkSize)); - sizeFile = sizeof(quantity) + sizeof(chunkBlockSize) + sizeof(lastChunkSize); - } + cargo.write(reinterpret_cast(zip.data()), zip.size()); - // Strumieniowanie danych - while (f.read(buffer.data(), ds::chunk_stream) || f.gcount() > 0) - { - const int bufferSize = f.gcount(); - buffer.resize(bufferSize); - - // Aktualizacja XXH64 - XXH64_update(xxhState, buffer.data(), buffer.size()); - - if (file.parameter == flag::raw) - { - // Zapisywanie strumienia do kontenera - cargo.write(reinterpret_cast(buffer.data()), buffer.size()); - sizeFile += bufferSize; - } - else - { - for (uint32_t ofs = 0; ofs < bufferSize; ofs += chunkBlockSize) - { - // Rozmiar chunka - const uint32_t chunkSize = std::min(chunkBlockSize, bufferSize - ofs); - - auto begin = buffer.begin() + ofs; - auto end = begin + chunkSize; - - // Skopiuj fragment danych do chunka - std::vector chunk(begin, end); - - std::vector outChunk; - - // Przetwórz chunki i przetwórz - if ((file.parameter & flag::zip) == flag::zip) - { - // Zaszyfruj i skompresuj lub tylko skompresuj - outChunk = (file.parameter & flag::enc) == flag::enc ? - eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); - } - else - { - // Zaszyfruj lub skopiuj - outChunk = eman.encrypt(chunk); - } - - const uint32_t outSize = outChunk.size(); - - cargo.write(reinterpret_cast(&outSize), sizeof(outSize)); - sizeFile += sizeof(outSize); - - cargo.write(reinterpret_cast(outChunk.data()), outChunk.size()); - sizeFile += outSize; - } - } - } - - f.close(); - - FilesTable ft; - ft.nameFile = path; - ft.nameLen = path.length(); - ft.offset = offset; - ft.size = sizeFile; - ft.flag = file.parameter; - ft.crc = XXH64_digest(xxhState); - - filesTable.push_back(ft); - offset += sizeFile; - } + filesTable.push_back(ft); + offset += zip.size(); } - return filesTable; } @@ -331,27 +259,43 @@ void CreateCargo::GetFilters(const std::string& filterFile) file.close(); // Lista plików do skompresowania - if (jslist.contains(key::zip)) - { - zipList = jslist[key::zip].get>(); - } + std::vector zip = jslist[KEY_ZIP].get>(); // Lista plików do zaszyfrowania - if (jslist.contains(key::enc)) - { - encList = jslist[key::enc].get>(); - } + std::vector enc = jslist[KEY_ENCRYPT].get>(); // Lista plików do pominięcia - if (jslist.contains(key::ignore)) - { - ignoreList = jslist[key::ignore].get>(); - } + std::vector ignore = jslist[KEY_IGNORE].get>(); - // Flaga tworzenia klucza jako plik nagłówka c++ - hppKey = jslist.value(key::hpp, false); + PrepareList(zip, enc, ignore); } +//----------------------------------------------------------------------------- +// Przygotuj listę plików do spakowania +//----------------------------------------------------------------------------- +void CreateCargo::PrepareList(const std::vector& zip, const std::vector& enc, const std::vector& ignore) +{ + PathConf pc; + + for (const auto& item : filesList) + { + if (!FindOnTheList(ignore, item)) + { + if (FindOnTheList(zip, item)) + { + pc.parameter = FindOnTheList(enc, item) ? 3 : 1; + } + else + { + pc.parameter = FindOnTheList(enc, item) ? 2 : 0; + } + pc.path = item; + filesPaths.push_back(pc); + } + } +} + + //----------------------------------------------------------------------------- // Znajdź wskazany element na liście //----------------------------------------------------------------------------- @@ -362,22 +306,32 @@ bool CreateCargo::FindOnTheList(const std::vector& list, const std: } //----------------------------------------------------------------------------- -// Sprawdzanie rozszeżeń plików +// Rozdzielanie paternu od ścieżki //----------------------------------------------------------------------------- -bool CreateCargo::CheckFileExtension(const std::string& p, const std::vector& patterns) { - std::filesystem::path _p = p; - std::string ext = "*" + UpperString(_p.extension().string()); - - for (const auto& e : patterns) +void CreateCargo::ExtPatternAndPathDetection(const std::vector& data, std::vector& pattern, std::vector& path) +{ + for (const auto& d : data) { - std::string element = UpperString(e); - if (element == ext) + if (d.front() == '*') { - return true; + std::string tmpPattern = d; + tmpPattern.erase(tmpPattern.begin()); + pattern.push_back(UpperString(tmpPattern)); + } + else + { + path.push_back(d); } } +} - return false; +//----------------------------------------------------------------------------- +// Sprawdzanie rozszeżeń plików +//----------------------------------------------------------------------------- +bool CreateCargo::CheckFileExtension(const std::filesystem::path& p, const std::vector& patterns) { + std::string ext = UpperString(p.extension().string()); + + return FindOnTheList(patterns, ext); } //----------------------------------------------------------------------------- @@ -389,6 +343,87 @@ std::string CreateCargo::UpperString(std::string s) { return s; } +//----------------------------------------------------------------------------- +// Wygenerój FNV-1a HASH +//----------------------------------------------------------------------------- +uint64_t CreateCargo::fnv64(const std::string& data) +{ + const uint64_t fnvOffset = 14695981039346656037u; + const uint64_t fnvPrime = 1099511628211u; + + uint64_t hash = fnvOffset; + for (unsigned char c : data) + { + hash ^= c; + hash *= fnvPrime; + } + + 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 //----------------------------------------------------------------------------- @@ -396,7 +431,7 @@ bool CreateCargo::WriteCargo() { std::cout << "Packing files..." << std::endl; - uint32_t filesLen = filesPaths.size(); + uint32_t filesLen = filesList.size(); //Przygotowanie nagłówków plików i przetworzenie danych std::vector filesHead = ComputingHeadFiles(); @@ -415,10 +450,11 @@ bool CreateCargo::WriteCargo() cargo.write(reinterpret_cast(&head.nameLen), sizeof(head.nameLen)); cargo.write(head.nameFile.data(), head.nameLen); + cargo.write(reinterpret_cast(&head.hashName), sizeof(head.hashName)); 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.flag), sizeof(head.flag)); + cargo.write(reinterpret_cast(&head.isZip), sizeof(head.isZip)); } //Cofnij się na początek pliku @@ -429,11 +465,15 @@ bool CreateCargo::WriteCargo() //Nadpisz tymczasowy nagłówek cargo.write(cargoHead.signature.data(), cargoHead.signature.length()); - cargo.write(reinterpret_cast(&cargoHead.table), sizeof(cargoHead.table)); + cargo.write(reinterpret_cast(&cargoHead.version), sizeof(cargoHead.version)); cargo.write(reinterpret_cast(&cargoHead.files), sizeof(cargoHead.files)); + cargo.write(reinterpret_cast(&cargoHead.table), sizeof(cargoHead.table)); cargo.close(); + // Zapisywanie klucza szyfrującego + //crypt.saveKey(catalogPath); + std::cout << "The container was successfully created! " << cargoFile << std::endl; return true; diff --git a/CreateCargo.h b/CreateCargo.h index 279930f..ab2d93b 100644 --- a/CreateCargo.h +++ b/CreateCargo.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -33,32 +34,26 @@ #include #include "DataStruct.h" +#include "Txtpp.h" +#include "CompressingManager.h" #include "EncryptionManager.h" -#include "CompressionManager.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 -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 = ".*"; +#define COMPRESSION_LEVEL 12 // Poziom kompresji plików (3 < 12) - inline constexpr std::string_view hpp = "keyhpp"; -} +#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 struct PathConf { std::string path; - uint8_t parameter; + int8_t parameter; }; class CreateCargo { @@ -67,15 +62,14 @@ public: virtual ~CreateCargo(); // Punk wejścia do tworzenia archivum - bool Create(const std::string&, const uint8_t&); + bool Create(const std::string&, int8_t); private: const std::string signature; const std::string extension; + const uint8_t version; - uint8_t methodFlags; - - XXH64_state_t* xxhState; + int8_t methodFlags; std::string catalogPath; @@ -84,14 +78,11 @@ private: std::vector filesList; - EncryptionManager eman; - CompressionManager cman; - bool hppKey; + EncryptionManager crypt; // listy wyjątków std::vector ignoreList; std::vector zipList; - std::vector encList; // Główna lista plików z parametrami std::vector filesPaths; @@ -101,6 +92,7 @@ private: uint64_t offset; + // Tworzenie listy plików do spakowania bool GetFileList(const std::string&); @@ -119,16 +111,34 @@ 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&); + // Sprawdzanie rozszeżeń plików - bool CheckFileExtension(const std::string&, const std::vector&); + bool CheckFileExtension(const std::filesystem::path&, const std::vector&); // Zamień cały ciąg na duże litery std::string UpperString(std::string); + // Wygenerój FNV-1a HASH + uint64_t fnv64(const std::string& data); + + // 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&); + + // Przygotuj listę plików do spakowania + void PrepareList(const std::vector&, const std::vector&, const std::vector&); }; diff --git a/DataStruct.h b/DataStruct.h index 91bf253..8136b69 100644 --- a/DataStruct.h +++ b/DataStruct.h @@ -22,61 +22,55 @@ #include #include -namespace ui +#define EXTENSION "pak" +#define SIGNATURE "XPAK" + +#define SIGNATURE_KEY_FILE 1497713496 // XKEY + +#define VERSION 100 + +enum StoreMethod { - inline constexpr std::string_view title = "exPak"; - inline constexpr std::string_view ver = "0.5"; -} + FILTERING = -1, + RAW = 0, + COMPRESS = 1, + ENCRYPT = 2, + COMPRESSxENCRYPT = 3 +}; -// Pliki -namespace fl -{ - inline constexpr std::string_view sigpak = "XPAK"; - inline constexpr std::string_view sigkey = "XKEY"; - inline constexpr std::string_view extpak = "pak"; - inline constexpr std::string_view extkey = "key"; -} +//Prgoram title +#define PROGRAM_TITLE "eXtendet PAK" +#define PROGRAM_VERSION "v1.1" +#define PROGRAM_AUTHOR "Yanczi" +#define PROGRAM_COMPILING "24 October 2025" +#define PROGRAM_LICENSE "GNU LGPL v3" -// Size -namespace ds -{ - // Chunki streamowania - inline constexpr uint32_t chunk_stream = 268435456; // 256MB +//Limity +#define MAX_FILE_SIZE 2147483648 // 2GB +#define MAX_PAK_SIZE 8796093022208 // 8TB - // Blok chunków - inline constexpr uint32_t block_size = 131072; // 128KB - - // Maksymalny rozmiar pliku do spakowania - inline constexpr uint64_t maxFileSize = 8589934592; // 8GB -} - -// 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 - - // Flaga do aktywacji filtra zdefiniowanego w json - inline constexpr uint8_t filter = 0xAB; -} +// Metody zapisania pliku +#define RAW_FILE 0 +#define ZIP_FILE 1 +#define CRYPT_FILE 2 +#define CRYPT_ZIP 3 struct CargoHead { std::string signature; - uint8_t version; - uint64_t table; + uint16_t version; uint32_t files; + uint64_t table; }; struct FilesTable { uint8_t nameLen; std::string nameFile; + uint64_t hashName; uint64_t offset; - uint64_t size; + uint32_t size; uint64_t crc; - uint8_t flag; + uint8_t isZip; }; \ No newline at end of file diff --git a/EncryptionManager.cpp b/EncryptionManager.cpp index a44085e..ed67797 100644 --- a/EncryptionManager.cpp +++ b/EncryptionManager.cpp @@ -1,22 +1,3 @@ -/* - * 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 "EncryptionManager.h" EncryptionManager::EncryptionManager() @@ -27,46 +8,47 @@ EncryptionManager::EncryptionManager() } 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 crypt(raw.size()); + + // Generowanie kluczy + generateKeys(); - std::vector tmp(raw.size()); if (crypto_stream_chacha20_ietf_xor_ic( - reinterpret_cast(tmp.data()), + reinterpret_cast(crypt.data()), reinterpret_cast(raw.data()), - static_cast(raw.size()), - nonce_local.data(), 0, key.data()) != 0) + static_cast(raw.size()), + nonce.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; + return crypt; } void EncryptionManager::generateKeys() { if (keyReady) return; + std::cout << "GENEROWANIE KLUCZA" << std::endl; + //randombytes_buf(key.data(), key.size()); crypto_stream_chacha20_ietf_keygen(key.data()); + randombytes_buf(nonce.data(), nonce.size()); keyReady = true; } -void EncryptionManager::saveKey(const std::string& path, bool hpp) +void EncryptionManager::saveKey(const std::string& path) { + std::cout << "ZAPISYWANIE KLUCZA" << std::endl; + + 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); @@ -75,86 +57,111 @@ 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); + std::vector nonceVec(reinterpret_cast(nonce.data()), + reinterpret_cast(nonce.data()) + nonce.size()); + + const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION); + const uint64_t crcNonce = XXH64(nonceVec.data(), nonceVec.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; } + if (!file) { std::cout << "Dupa nie zapisało" << std::endl; } - file.write(fl::sigkey.data(), fl::sigkey.length()); + 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.write(reinterpret_cast(nonceVec.data()), nonceVec.size()); + file.write(reinterpret_cast(&crcNonce), sizeof(crcNonce)); + + if (!file.good()) { std::cout << "Dupa nie zapisało" << std::endl; } file.close(); - if (hpp) {saveCppHeadFile(path);} + //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::vector keyVec(key.begin(), key.end()); + std::vector nonceVec(nonce.begin(), nonce.end()); - std::ofstream file(path + ".hpp"); - - file << "// Plik wygenerowany przez " << ui::title << " " << ui::ver << 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; + const std::string headerText = + "// Plik wygenerowany przy wykorzystaniu exPAK\n\n" + "// Klucz deszyfrujący\n" + "const std::array key{" + toHex(keyVec) + "};\n\n" + "// Ciąg nonce\n" + "const std::array nonce{" + toHex(nonceVec) + "}; "; + std::ofstream file(path + ".hh"); + file << headerText; file.close(); } -std::string EncryptionManager::toHex(const unsigned char* data, size_t len) +std::string EncryptionManager::toHex(const std::vector& data) { - 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 "; + std::string bytes; + int sk = data.size(); + int skp = 1; + + for (const auto& b : data) + { + std::stringstream ss; + ss << "0x" << std::hex << std::uppercase << std::setw(2) << std::setfill('0') + << static_cast(b); + + bytes += "'"; + bytes += ss.str(); + bytes += "'"; + + if (skp < sk) + { + bytes += ", "; + skp++; + } } - return oss.str(); + + return bytes; } // Wczytaj klucz void EncryptionManager::loadKey(const std::string& path) { + std::cout << "ODCZYT KLUCZA" << std::endl; std::ifstream file(path + ".key", std::ios::binary); - std::vector sig(fl::sigkey.size()); - int8_t ver; + + int sig; + short ver; int time; // Wczytaj - file.read(sig.data(), sig.size()); + file.read(reinterpret_cast(&sig), sizeof(sig)); + file.read(reinterpret_cast(&ver), sizeof(ver)); // Sprawdź czy plik klucza jest poprawny - if (std::string(sig.begin(), sig.end()) != fl::sigkey) + if (sig != SIGNATURE_KEY_FILE || ver != VERSION) { throw std::runtime_error("Invalid key file!"); } std::vector keyVec(key.size()); + std::vector nonceVec(nonce.size()); uint64_t crcKey; + uint64_t crcNonce; file.read(reinterpret_cast(&time), sizeof(time)); file.read(keyVec.data(), keyVec.size()); file.read(reinterpret_cast(&crcKey), sizeof(crcKey)); + file.read(nonceVec.data(), nonceVec.size()); + file.read(reinterpret_cast(&crcNonce), sizeof(crcNonce)); + + std::cout << crcKey << " - " << XXH64(keyVec.data(), keyVec.size(), VERSION) << std::endl; // Sprawdź integralność klucza - if (XXH64(keyVec.data(), keyVec.size(), 0) != crcKey) + if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey + || XXH64(nonceVec.data(), nonceVec.size(), VERSION) != crcNonce) { throw std::runtime_error("Key integrity error!"); } @@ -163,29 +170,19 @@ void EncryptionManager::loadKey(const std::string& path) // Przekonwertuj vector na array key = toArray(keyVec); + nonce = toArray(nonceVec); } // 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); + std::vector raw(crypt.size()); if (crypto_stream_chacha20_ietf_xor( reinterpret_cast(raw.data()), - reinterpret_cast(tmp.data()), - static_cast(tmp.size()), - nonce_local.data(), key.data()) != 0) + reinterpret_cast(crypt.data()), + static_cast(crypt.size()), + nonce.data(), key.data()) != 0) { throw std::runtime_error("Data decryption error!"); } diff --git a/EncryptionManager.h b/EncryptionManager.h index b502b1b..bee6845 100644 --- a/EncryptionManager.h +++ b/EncryptionManager.h @@ -1,22 +1,3 @@ -/* - * 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 @@ -42,19 +23,16 @@ public: std::vector encrypt(const std::vector&); std::vector decrypt(const std::vector&); - void saveKey(const std::string&, bool); + void saveKey(const std::string&); void loadKey(const std::string&); - // Generowanie hash BLAKE2b - //static std::array hashBlake(const std::vector&); - //static bool compareBlake(const std::vector&, const std::array&); - private: std::array key{}; + std::array nonce{}; bool keyReady; void generateKeys(); - std::string toHex(const unsigned char*, size_t); + std::string toHex(const std::vector&); void saveCppHeadFile(const std::string&); template diff --git a/ExtractCargo.cpp b/ExtractCargo.cpp index c944347..fbbfeb8 100644 --- a/ExtractCargo.cpp +++ b/ExtractCargo.cpp @@ -22,11 +22,12 @@ ExtractCargo::ExtractCargo() :filesLen(0) , tablePosition(0) - , xxhState(XXH64_createState()) - , signature(fl::sigpak) + , filesHeadsOffset(0) + , version(VERSION) + , signature(SIGNATURE) { // TODO Auto-generated constructor stub - XXH64_reset(xxhState, 0); + } ExtractCargo::~ExtractCargo() @@ -44,8 +45,6 @@ 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)) { @@ -61,12 +60,8 @@ bool ExtractCargo::Extract(const std::string& cFile) } // 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()); - } + //std::filesystem::path kdir = cargoFileName.stem(); + //eman.loadKey(kdir.string()); //Otwieranie kontenera cargoFile.open(cargoFileName, std::ios::binary); @@ -88,7 +83,7 @@ bool ExtractCargo::Extract(const std::string& cFile) bool ExtractCargo::CheckCargoFile() { std::vector magic(signature.size()); - int8_t cargoVer = 0; + uint16_t cargoVer = 0; if (!cargoFile.is_open()) { @@ -97,15 +92,40 @@ bool ExtractCargo::CheckCargoFile() } cargoFile.read(magic.data(), magic.size()); + cargoFile.read(reinterpret_cast(&cargoVer), sizeof(cargoVer)); + 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; return false; } - // Pobierz pozycję tablicy plików i jej rozmiar - cargoFile.read(reinterpret_cast(&tablePosition), sizeof(tablePosition)); - cargoFile.read(reinterpret_cast(&filesLen), sizeof(filesLen)); + if (cargoVer != version) + { + std::cerr << "Error: Wrong cargo version" << std::endl; + return false; + } + + filesHeadsOffset = signature.length() + sizeof(cargoVer) + sizeof(filesLen); + + return true; +} + +//----------------------------------------------------------------------------- +// Sprawdzanie sumy kontrolnej +//----------------------------------------------------------------------------- +bool ExtractCargo::HashValid(const std::vector& data, const uint64_t& crc) +{ + uint64_t actualCrc = XXH64(data.data(), data.size(), VERSION); + + if (actualCrc != crc) + { + return false; + } return true; } @@ -116,6 +136,7 @@ bool ExtractCargo::CheckCargoFile() void ExtractCargo::LoadFilesTable() { cargoFile.seekg(tablePosition); + for (uint32_t i = 0; i < filesLen; ++i) { FilesTable fhTmp; @@ -125,10 +146,11 @@ void ExtractCargo::LoadFilesTable() cargoFile.read(nameBuffor.data(), fhTmp.nameLen); fhTmp.nameFile = std::string(nameBuffor.begin(), nameBuffor.end()); + cargoFile.read(reinterpret_cast(&fhTmp.hashName), sizeof(fhTmp.hashName)); 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.flag), sizeof(fhTmp.flag)); + cargoFile.read(reinterpret_cast(&fhTmp.isZip), sizeof(fhTmp.isZip)); filesHeads.push_back(fhTmp); } @@ -139,80 +161,29 @@ void ExtractCargo::LoadFilesTable() //----------------------------------------------------------------------------- void ExtractCargo::ExtractingFilesFromCargo() { + CompressingManager cm; + for (const auto& fh : filesHeads) { std::filesystem::path dir = cargoFileName.stem() / fh.nameFile; CreateDirections(dir); - - std::cout << dir.string() << std::endl; - std::ofstream file(dir, std::ios::binary); + 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 = fh.isZip ? cm.decompress(buffor) : eman.decrypt(buffor); + + 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..164a0fc 100644 --- a/ExtractCargo.h +++ b/ExtractCargo.h @@ -28,12 +28,11 @@ #include #include #include -#include #include #include "DataStruct.h" +#include "CompressingManager.h" #include "EncryptionManager.h" -#include "CompressionManager.h" class ExtractCargo { public: @@ -48,8 +47,9 @@ private: uint32_t filesLen; uint64_t tablePosition; - XXH64_state_t* xxhState; + uint8_t filesHeadsOffset; + const uint8_t version; const std::string signature; std::vector filesHeads; @@ -58,7 +58,7 @@ private: std::ifstream cargoFile; EncryptionManager eman; - CompressionManager cman; + // Sprawdzenie poprawności archiwum bool CheckCargoFile(); @@ -69,6 +69,9 @@ 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); diff --git a/Interface.cpp b/Interface.cpp new file mode 100644 index 0000000..9e0d7e6 --- /dev/null +++ b/Interface.cpp @@ -0,0 +1,18 @@ +#include "Interface.h" + +Interface::Interface() { + // TODO Auto-generated constructor stub + +} + +Interface::~Interface() { + // TODO Auto-generated destructor stub +} + +void Interface::TextBorder(const std::string& title, const std::string& text) +{ + auto element = ftxui::window(ftxui::text(title), ftxui::paragraphAlignLeft(text)); + auto screen = ftxui::Screen::Create(ftxui::Dimension::Fit(element)); + ftxui::Render(screen, element); + screen.Print(); +} \ No newline at end of file diff --git a/Interface.h b/Interface.h new file mode 100644 index 0000000..e060f7f --- /dev/null +++ b/Interface.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +class Interface { +public: + Interface(); + virtual ~Interface(); + + void TextBorder(const std::string&, const std::string&); +}; + diff --git a/README.md b/README.md index 704bf0a..e1ca22d 100644 --- a/README.md +++ b/README.md @@ -91,9 +91,7 @@ **libsodium - https://github.com/jedisct1/libsodium** -**xxHash - https://github.com/Cyan4973/xxHash.git** - -**Zstd - https://github.com/facebook/zstd.git** +**LZ4 - https://github.com/lz4/lz4.git** **FTXUI - https://github.com/ArthurSonzogni/FTXUI.git** diff --git a/Tui.cpp b/Tui.cpp deleted file mode 100644 index eff5894..0000000 --- a/Tui.cpp +++ /dev/null @@ -1,71 +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 . - */ - -#include "Tui.h" - -Tui::Tui() { - // TODO Auto-generated constructor stub - -} - -Tui::~Tui() { - // TODO Auto-generated destructor stub -} - -void Tui::TextBorder(const std::string& title, const std::string& text) -{ - auto element = ftxui::window(ftxui::text(title), ftxui::paragraphAlignLeft(text)); - auto screen = ftxui::Screen::Create(ftxui::Dimension::Fit(element)); - ftxui::Render(screen, element); - screen.Print(); -} - -void Tui::table(const std::vector>& data) -{ - ftxui::Table table(data); - - // Styl ogólny tabeli (ramki) - table.SelectAll().Border(ftxui::LIGHT); - - // Oddzielenie nagłówka od danych podwójną linią - table.SelectRow(0).Border(ftxui::LIGHT); - table.SelectRow(0).Decorate(ftxui::bold); // Pogrubienie nagłówka - table.SelectRow(0).SeparatorVertical(ftxui::LIGHT); - table.SelectRow(0).Border(ftxui::LIGHT); - - table.SelectColumn(0).DecorateCells(ftxui::center); - table.SelectColumn(1).DecorateCells(ftxui::center); - - table.SelectColumn(2).DecorateCells([](ftxui::Element e) { - return e | ftxui::flex; - }); - - table.SelectColumn(3).DecorateCells(ftxui::center); - - table.SelectColumn(0).BorderRight(ftxui::LIGHT); - table.SelectColumn(1).BorderRight(ftxui::LIGHT); - table.SelectColumn(2).BorderRight(ftxui::LIGHT); - - auto document = table.Render(); - - auto screen = ftxui::Screen::Create(ftxui::Dimension::Full(), ftxui::Dimension::Fit(document)); - - ftxui::Render(screen, document); - screen.Print(); -} \ No newline at end of file diff --git a/Tui.h b/Tui.h deleted file mode 100644 index d3b7b99..0000000 --- a/Tui.h +++ /dev/null @@ -1,34 +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 - -class Tui { -public: - Tui(); - virtual ~Tui(); - - void TextBorder(const std::string&, const std::string&); - void table(const std::vector>&); -}; \ No newline at end of file diff --git a/Txtpp.h b/Txtpp.h new file mode 100644 index 0000000..70940bb --- /dev/null +++ b/Txtpp.h @@ -0,0 +1,174 @@ +/* + * 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 9b95d12..2a2860e 100644 --- a/ViewCargo.cpp +++ b/ViewCargo.cpp @@ -20,7 +20,14 @@ #include "ViewCargo.h" ViewCargo::ViewCargo() -{} + :signature(SIGNATURE) + , version(VERSION) + , filesLen(0) + , tablePos(0) +{ + // TODO Auto-generated constructor stub + +} //----------------------------------------------------------------------------- // Wywoływanie @@ -42,25 +49,38 @@ bool ViewCargo::View(const std::string& path) } //Sprawdź czy kontener jest prawidłowy - if (!ViewFiles(path)) + if (!CheckCargoFile(path)) { std::cerr << "Nie prawidlowa struktura kontenera Void" << std::endl; return false; } + //Table Header + std::vector headElements; + + headElements.push_back(ftxui::text(" Zip ") | 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)); + + filesList.push_back(hbox(std::move(headElements))); + + + //Pobieranie listy plików + GetFileList(path); + + //Renderowanie listy plików + RenderList(); + return true; } //----------------------------------------------------------------------------- // Sprawdzenie poprawności kontenera //----------------------------------------------------------------------------- -bool ViewCargo::ViewFiles(const std::string& path) +bool ViewCargo::CheckCargoFile(const std::string& path) { - uint64_t tabPos = 0; - uint32_t tabSize = 0; - - std::vector magic(fl::sigpak.length()); - int8_t cargoVer = 0; + std::vector magic(signature.length()); + uint16_t cargoVer = 0; std::ifstream cargo(path, std::ios::binary); @@ -71,45 +91,30 @@ bool ViewCargo::ViewFiles(const std::string& path) } //--------------------------------------------------------------- - // Odczytywanie pierwszych 16 bajtów nagłówka pliku - // 4 Sygnatura kontenera XPAK - // 8 Offset tablicy plików - // 4 Rozmiar tablicy plików + // Odczytywanie pierwszych 11 bajtów nagłówka pliku + // 6 pierwszych to sygnatura + // 1 wersja kontenera + // 4 ilość plików w kontenerze //--------------------------------------------------------------- cargo.read(magic.data(), magic.size()); - cargo.read(reinterpret_cast(&tabPos), sizeof(tabPos)); - cargo.read(reinterpret_cast(&tabSize), sizeof(tabSize)); + cargo.read(reinterpret_cast(&cargoVer), sizeof(cargoVer)); + cargo.read(reinterpret_cast(&filesLen), sizeof(filesLen)); + cargo.read(reinterpret_cast(&tablePos), sizeof(tablePos)); //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(); return false; } - std::cout << "ZIP" << " " << "ENC" << " " << "Path" << std::endl; - - // Przeskocz do tablicy plików - cargo.seekg(tabPos); - - // Załaduj dane o plikach - for (uint32_t i = 0; i < tabSize; ++i) + //Sprawdź spójność wersji kontenera + if (cargoVer != version) { - FilesTable fhTmp; - cargo.read(reinterpret_cast(&fhTmp.nameLen), sizeof(fhTmp.nameLen)); - - std::vector nameBuffor(fhTmp.nameLen); - cargo.read(nameBuffor.data(), fhTmp.nameLen); - fhTmp.nameFile = std::string(nameBuffor.begin(), nameBuffor.end()); - - 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.flag), sizeof(fhTmp.flag)); - - //Tworzenie wierszy tabeli - ShowFile(fhTmp.nameFile, fhTmp.flag); + std::cerr << "Error: Wrong cargo version" << std::endl; + cargo.close(); + return false; } cargo.close(); @@ -118,35 +123,76 @@ bool ViewCargo::ViewFiles(const std::string& path) } //----------------------------------------------------------------------------- -// Generowanie wierszy do tabeli +// Pobieranie listy plików z kontenera //----------------------------------------------------------------------------- -void ViewCargo::ShowFile(const std::string& file, const uint8_t& flag) +void ViewCargo::GetFileList(const std::string& path) { - std::string compresedCheck = "[ ]"; - std::string encryptedCheck = "[ ]"; + std::ifstream cargo(path, std::ios::binary); + cargo.seekg(tablePos); - // Ustawianie checkboxów - switch (flag) + for (uint32_t i = 0; i < filesLen; ++i) { - case flag::zip: - compresedCheck = "[x]"; - break; + FilesTable fhTmp; + cargo.read(reinterpret_cast(&fhTmp.nameLen), sizeof(fhTmp.nameLen)); - case flag::enc: - encryptedCheck = "[x]"; - break; + std::vector nameBuffor(fhTmp.nameLen); + cargo.read(nameBuffor.data(), fhTmp.nameLen); + fhTmp.nameFile = std::string(nameBuffor.begin(), nameBuffor.end()); - case flag::ezd: - compresedCheck = "[x]"; - encryptedCheck = "[x]"; - break; + cargo.read(reinterpret_cast(&fhTmp.hashName), sizeof(fhTmp.hashName)); + 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)); - default: - compresedCheck = "[ ]"; - encryptedCheck = "[ ]"; - break; + //Tworzenie wierszy tabeli + CreateTableRow(fhTmp.nameFile, fhTmp.isZip, fhTmp.hashName); } - // Wyświetlanie - std::cout << compresedCheck << " " << encryptedCheck << " " << file << std::endl; + cargo.close(); +} + +//----------------------------------------------------------------------------- +// Generowanie wierszy do tabeli +//----------------------------------------------------------------------------- +void ViewCargo::CreateTableRow(const std::string& file, const uint8_t& zip, const uint64_t& hash) +{ + //Zamiania crc liczbowej na hex string + std::stringstream ss; + ss << "0x" << std::hex << std::uppercase << hash; + + std::vector cell; + + ftxui::Element eZip; + + //Dodawanie check boxa czy plik jest spakowany czy nie + if (zip == 1) + { + eZip = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); + } + else + { + eZip = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + } + + //Dodawanie komurek + cell.push_back(eZip); + 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)); + + //Konwersja komurek na wiersz + filesList.push_back(ftxui::hbox(std::move(cell))); +} + +//----------------------------------------------------------------------------- +// Renderowanie listy plików +//----------------------------------------------------------------------------- +void ViewCargo::RenderList() +{ + //Dodawanie wierszy do kolumn + ftxui::Element table = ftxui::vbox(std::move(filesList)); + + auto screen = ftxui::Screen::Create(ftxui::Dimension::Fit(table)); + ftxui::Render(screen, table); + screen.Print(); } diff --git a/ViewCargo.h b/ViewCargo.h index 576b336..bdfb7f8 100644 --- a/ViewCargo.h +++ b/ViewCargo.h @@ -27,7 +27,6 @@ #include #include #include -#include #include "DataStruct.h" @@ -39,8 +38,17 @@ public: bool View(const std::string&); private: - bool ViewFiles(const std::string&); - void ShowFile(const std::string&, const uint8_t&); + const std::string signature; + const uint16_t version; + + uint32_t filesLen; + uint64_t tablePos; + std::vector filesList; + + bool CheckCargoFile(const std::string&); + void GetFileList(const std::string&); + void RenderList(); + void CreateTableRow(const std::string&, const uint8_t&, const uint64_t&); }; diff --git a/license/FTXUI/LICENSE.txt b/license/FTXUI/LICENSE.txt deleted file mode 100644 index fe4588c..0000000 --- a/license/FTXUI/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2019 Arthur Sonzogni. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/license/lz4/LICENSE.txt b/license/lz4/LICENSE.txt new file mode 100644 index 0000000..972594f --- /dev/null +++ b/license/lz4/LICENSE.txt @@ -0,0 +1,12 @@ +This repository uses 2 different licenses : +- all files in the `lib` directory use a BSD 2-Clause license +- all other files use a GPL-2.0-or-later license, unless explicitly stated otherwise + +Relevant license is reminded at the top of each source file, +and with presence of COPYING or LICENSE file in associated directories. + +This model is selected to emphasize that +files in the `lib` directory are designed to be included into 3rd party applications, +while all other files, in `programs`, `tests` or `examples`, +are intended to be used "as is", as part of their intended scenarios, +with no intention to support 3rd party integration use cases. \ No newline at end of file diff --git a/license/zstd/LICENSE.txt b/license/zstd/LICENSE.txt deleted file mode 100644 index ca66d17..0000000 --- a/license/zstd/LICENSE.txt +++ /dev/null @@ -1,30 +0,0 @@ -BSD License - -For Zstandard software - -Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. - -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. - - * Neither the name Facebook, nor Meta, nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -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/testx/herrsher-of-the-void.png b/testx/herrsher-of-the-void.png deleted file mode 100644 index d6dfc12..0000000 Binary files a/testx/herrsher-of-the-void.png and /dev/null differ diff --git a/testx/mus_honkai_space.ogg b/testx/mus_honkai_space.ogg deleted file mode 100644 index 136cba5..0000000 Binary files a/testx/mus_honkai_space.ogg and /dev/null differ diff --git a/testx/text_file.txt b/testx/text_file.txt deleted file mode 100644 index 02a2623..0000000 --- a/testx/text_file.txt +++ /dev/null @@ -1,126 +0,0 @@ -Nam strzelać nie kazano. - WstÄ…piĹ‚em na dziaĹ‚o -I spĂłjrzaĹ‚em na pole; dwieĹ›cie armat grzmiaĹ‚o. -Artyleryi ruskiej ciÄ…gnÄ… siÄ™ szeregi, -Prosto, dĹ‚ugo, daleko, jako morza brzegi; -I widziaĹ‚em ich wodza: przybiegĹ‚, mieczem skinÄ…Ĺ‚ -I jak ptak jedno skrzydĹ‚o wojska swego zwinÄ…Ĺ‚; -Wylewa siÄ™ spod skrzydĹ‚a Ĺ›ciĹ›niona piechota -DĹ‚ugÄ… czarnÄ… kolumnÄ…, jako lawa bĹ‚ota, -Nasypana iskrami bagnetĂłw. Jak sÄ™py -Czarne chorÄ…gwie na Ĺ›mierć prowadzÄ… zastÄ™py. - -Przeciw nim sterczy biaĹ‚a, wÄ…ska, zaostrzona, -Jak gĹ‚az bodzÄ…cy morze, reduta Ordona. -Sześć tylko miaĹ‚a armat; wciÄ…ĹĽ dymiÄ… i Ĺ›wiecÄ…; -I nie tyle prÄ™dkich słów gniewne usta miecÄ…, -Nie tyle przejdzie uczuć przez duszÄ™ w rozpaczy, -Ile z tych dziaĹ‚ leciaĹ‚o bomb, kul i kartaczy. -Patrz, tam granat w sam Ĺ›rodek kolumny siÄ™ nurza, -Jak w fale bryĹ‚a lawy, puĹ‚k dymem zachmurza; -PÄ™ka Ĺ›rĂłd dymu granat, szyk pod niebo leci -I ogromna Ĺ‚ysina Ĺ›rĂłd kolumny Ĺ›wieci. - -Tam kula, lecÄ…c, z dala grozi, szumi, wyje. -Ryczy jak byk przed bitwÄ…, miota siÄ™, grunt ryje; - -JuĹĽ dopadĹ‚a; jak boa Ĺ›rĂłd kolumn siÄ™ zwija, -Pali piersiÄ…, rwie zÄ™bem, oddechem zabija. -Najstraszniejszej nie widać, lecz sĹ‚ychać po dĹşwiÄ™ku, -Po waleniu siÄ™ trupĂłw, po ranionych jÄ™ku: -Gdy kolumnÄ™ od koĹ„ca do koĹ„ca przewierci, -Jak gdyby Ĺ›rodkiem wojska przeszedĹ‚ anioĹ‚ Ĺ›mierci. - -GdzieĹĽ jest krĂłl, co na rzezie tĹ‚umy te wyprawia? -Czy dzieli ich odwagÄ™, czy pierĹ› sam nadstawia? -Nie, on siedzi o pięćset mil na swej stolicy, -KrĂłl wielki, samowĹ‚adnik Ĺ›wiata poĹ‚owicy; -ZmarszczyĹ‚ brwi, - i tysiÄ…ce kibitek wnet leci; -PodpisaĹ‚, - tysiÄ…c matek opĹ‚akuje dzieci; -SkinÄ…Ĺ‚, - padajÄ… knuty od Niemna do Chiwy. -Mocarzu, jak BĂłg silny, jak szatan zĹ‚oĹ›liwy, -Gdy TurkĂłw za BaĹ‚kanem twoje straszÄ… spiĹĽe, -Gdy poselstwo paryskie twoje stopy liĹĽe, - -Warszawa jedna twojej mocy siÄ™ urÄ…ga, -Podnosi na ciÄ™ rÄ™kÄ™ i koronÄ™ Ĺ›ciÄ…ga, -KoronÄ™ KazimierzĂłw, Chrobrych z twojej gĹ‚owy, -BoĹ› jÄ… ukradĹ‚ i skrwawiĹ‚, synu Wasilowy! - -Car dziwi siÄ™ - ze strachu. drzÄ… Petersburczany, -Car gniewa siÄ™ - ze strachu mrÄ… jego dworzany; -Ale sypiÄ… siÄ™ wojska, ktĂłrych BĂłg i wiara -Jest Car. - Car gniewny: umrzem, rozweselim Cara. -PosĹ‚any wĂłdz kaukaski z siĹ‚ami pół-Ĺ›wiata, -Wierny, czynny i sprawny - jak knut w rÄ™ku kata. - -Ura! ura! Patrz, blisko reduty, juĹĽ w rowy -WalÄ… siÄ™, na faszynÄ™ kĹ‚adÄ…c swe tuĹ‚owy; -JuĹĽ czerniÄ… siÄ™ na biaĹ‚ych palisadach wałów. -Jeszcze reduta w Ĺ›rodku, jasna od wystrzałów, -Czerwieni siÄ™ nad czerniÄ…: jak w Ĺ›rodek mrowiaka -Wrzucony motyl bĹ‚yska, - mrowie go naciska, - -ZgasĹ‚ - tak zgasĹ‚a reduta. CzyĹĽ ostatnie dziaĹ‚o -StrÄ…cone z Ĺ‚oĹĽa w piasku paszczÄ™ zagrzebaĹ‚o? -Czy zapaĹ‚ krwiÄ… ostatni bombardyjer zalaĹ‚? -ZgasnÄ…Ĺ‚ ogieĹ„. - JuĹĽ Moskal rogatki wywalaĹ‚. - -GdzieĹĽ rÄ™czna broĹ„? - Ach, dzisiaj pracowaĹ‚a wiÄ™cej -NiĹĽ na wszystkich przeglÄ…dach za wĹ‚adzy ksiÄ…ĹĽÄ™cej; -ZgadĹ‚em, dlaczego milczy, - bo nieraz widziaĹ‚em -GarstkÄ™ naszych walczÄ…cÄ… z Moskali nawaĹ‚em. -Gdy godzinÄ™ woĹ‚ano dwa sĹ‚owa: pal, nabij; -Gdy oddechy dym tĹ‚umi, trud ramiona sĹ‚abi; -A wciÄ…ĹĽ grzmi rozkaz wodzĂłw, wre ĹĽoĹ‚nierza czynność; -Na koniec bez rozkazu peĹ‚niÄ… swÄ… powinność, -Na koniec bez rozwagi, bez czucia, pamiÄ™ci, -Ĺ»oĹ‚nierz jako mĹ‚yn palny nabija - grzmi - krÄ™ci -BroĹ„ od oka do nogi, od nogi na oko: -AĹĽ rÄ™ka w Ĺ‚adownicy dĹ‚ugo i głęboko -SzukaĹ‚a, nie znalazĹ‚a - i ĹĽoĹ‚nierz pobladnÄ…Ĺ‚, -Nie znalazĹ‚szy Ĺ‚adunku, juĹĽ broniÄ… nie wĹ‚adnÄ…Ĺ‚; -I uczuĹ‚, ĹĽe go pali strzelba rozogniona; -UpuĹ›ciĹ‚ jÄ… i upadĹ‚; - nim dobijÄ…, skona. -Takem myĹ›liĹ‚, - a w szaniec nieprzyjaciół kupa -JuĹĽ Ĺ‚azĹ‚a, jak robactwo na Ĺ›wieĹĽego trupa. - -PociemniaĹ‚o mi w oczach - a gdym Ĺ‚zy ocieraĹ‚, -SĹ‚yszaĹ‚em, ĹĽe coĹ› do mnie mĂłwiĹ‚ mĂłj JeneraĹ‚. -On przez lunetÄ™ wspartÄ… na moim ramieniu -DĹ‚ugo na szturm i szaniec poglÄ…daĹ‚ w milczeniu. -Na koniec rzekĹ‚; "Stracona". - Spod lunety jego -Wymknęło siÄ™ Ĺ‚ez kilka, - rzekĹ‚ do mnie: "Kolego, -Wzrok mĹ‚ody od szkieĹ‚ lepszy; patrzaj, tam na wale, -Znasz Ordona, czy widzisz, gdzie jest?" - "Jenerale, -Czy go znam? - Tam staĹ‚ zawsze, to dziaĹ‚o kierowaĹ‚. -Nie widzÄ™ - znajdÄ™ - dojrzÄ™! - Ĺ›rĂłd dymu siÄ™ schowaĹ‚: -Lecz Ĺ›rĂłd najgÄ™stszych kłębĂłw dymu ileĹĽ razy -WidziaĹ‚em rÄ™kÄ™ jego, dajÄ…cÄ… rozkazy. - -WidzÄ™ go znowu, - widzÄ™ rÄ™kÄ™ - bĹ‚yskawicÄ™, -Wywija, grozi wrogom, trzyma palnÄ… Ĺ›wiĂ©cÄ™, -BiorÄ… go - zginÄ…Ĺ‚ - o nie, - skoczyĹ‚ w dół, - do lochĂłw"! -"Dobrze - rzecze JeneraĹ‚ - nie odda im prochĂłw". - -Tu blask - dym - chwila cicho - i huk jak stu gromĂłw. -ZaćmiĹ‚o siÄ™ powietrze od ziemi wylomĂłw, -Harmaty podskoczyĹ‚y i jak wystrzelone -ToczyĹ‚y siÄ™ na koĹ‚ach - lonty zapalone -Nie trafiĹ‚y do swoich panew. I dym wionÄ…Ĺ‚ -Prosto ku nam; i w gÄ™stej chmurze nas ochĹ‚onÄ…Ĺ‚. -I nie byĹ‚o nic widać prĂłcz granatĂłw blasku -I powoli dym rzedniaĹ‚, opadaĹ‚ deszcz piasku. -SpojrzaĹ‚em na redutÄ™; - waĹ‚y, palisady, -DziaĹ‚a i naszych garstka, i wrogĂłw gromady; -Wszystko jako sen znikĹ‚o. - Tylko czarna bryĹ‚a -Ziemi nieksztaĹ‚tnej leĹĽy - rozjemcza mogiĹ‚a. -Tam i ci, co bronili, -i ci, co siÄ™ wdarli, -Pierwszy raz pokĂłj szczery i wieczny zawarli. -Choćby cesarz Moskalom kazaĹ‚ wstać, juĹĽ dusza -Moskiewska. tam raz pierwszy, cesarza nie sĹ‚usza. -Tam zagrzebane tylu set ciaĹ‚a, imiona: -Dusze gdzie? nie wiem; lecz wiem, gdzie dusza Ordona. -On bÄ™dzie Patron szaĹ„cĂłw! - Bo dzieĹ‚o zniszczenia -W dobrej sprawie jest Ĺ›wiÄ™te, Jak dzieĹ‚o tworzenia; -BĂłg wyrzekĹ‚ sĹ‚owo staĹ„ siÄ™, BĂłg i zgiĹ„ wyrzecze. -Kiedy od ludzi wiara i wolność uciecze, -Kiedy ziemiÄ™ despotyzm i duma szalona -OblejÄ…, jak Moskale redutÄ™ Ordona - -KarzÄ…c plemiÄ™ zwyciężcĂłw zbrodniami zatrute, -BĂłg wysadzi tÄ™ ziemiÄ™, jak on swÄ… redutÄ™. \ No newline at end of file diff --git a/voidcmd.cpp b/voidcmd.cpp index 22e1520..5908996 100644 --- a/voidcmd.cpp +++ b/voidcmd.cpp @@ -32,7 +32,7 @@ #include "CreateCargo.h" #include "ExtractCargo.h" #include "ViewCargo.h" -#include "Tui.h" +#include "Interface.h" void RenderHelp() { @@ -40,35 +40,36 @@ void RenderHelp() const std::string HelpInstruction = "pakcmd \n" " \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" + " -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" + " -s Pack and encrypted \n" + " -cs Pack and compress \n" " \n" "Extracting: \n" " -x Extract files from the specified container \n" - " \n" - "Others: \n" " -ls List files stored in a container \n" " \n" - ".json \n" + " \n" + ".txt \n" " \n" "Keys: \n" " \n" - " {compress} - Compressing files \n" - " {crypt} - Encrypted files \n" + " {compress} - Compressing files \n" + " {crypt} - Encrypted files with ChaCha20 \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"; + " *.* - All files !NOT WORKING WITH {ignore} KEY! \n" + " \n"; - //Interface tui; - //tui.TextBorder(HelpTitle, HelpInstruction); + Interface tui; + tui.TextBorder(HelpTitle, HelpInstruction); } -static bool EmptyPath(std::string path) +bool EmptyPath(std::string path) { if (path == "") { @@ -80,16 +81,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]; @@ -100,37 +111,17 @@ int main(int argc, char* argv[]) { if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, 0x0F)) + if (!cargo.Create(path, 1)) { return 1; } i++; } - if (arg == "-r" && i + 1 < argc) + if (arg == "-p" && i + 1 < argc) { path = argv[i + 1]; - if (!cargo.Create(path, 0x00)) - { - return 1; - } - i++; - } - - if (arg == "-e" && i + 1 < argc) - { - path = argv[i + 1]; - if (!cargo.Create(path, 0xF0)) - { - return 1; - } - i++; - } - - if (arg == "-s" && i + 1 < argc) - { - path = argv[i + 1]; - if (!cargo.Create(path, 0xFF)) + if (!cargo.Create(path, 0)) { return 1; } @@ -141,7 +132,7 @@ int main(int argc, char* argv[]) { { path = argv[i + 1]; if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, 0xAB)) + if (!cargo.Create(path, -1)) { return 1; } diff --git a/voidcmd.vcxproj b/voidcmd.vcxproj index ee82946..d0fe1d7 100644 --- a/voidcmd.vcxproj +++ b/voidcmd.vcxproj @@ -101,16 +101,16 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);SODIUM_STATIC + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - stdcpp20 - 3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\include + stdcpp17 + 3rd\ftxui\include;3rd\libsodium\include;3rd\json\include;3rd\lz4\include;3rd\xxhash\include Console true - 3rd\zstd\lib\Debug;3rd\xxhash\lib\Debug;3rd\libsodium\x64\Debug\v143\static - libsodium.lib;zstd_static.lib;xxhash.lib + 3rd\ftxui\Debug;3rd\lz4\lib;3rd\libsodium\lib\Debug + liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib @@ -119,32 +119,35 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);SODIUM_STATIC + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp17 - 3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\include + 3rd\ftxui\include;3rd\libsodium\include;3rd\json\include;3rd\lz4\include; Console true - 3rd\zstd\lib\Release;3rd\libsodium\x64\Release\v143\static;3rd\xxhash\lib\Release - libsodium.lib;zstd_static.lib;xxhash.lib + 3rd\libsodium\lib\Release;3rd\ftxui\Release;3rd\lz4\lib + liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib - + + - + + + diff --git a/voidcmd.vcxproj.filters b/voidcmd.vcxproj.filters index 4dec7bb..7752806 100644 --- a/voidcmd.vcxproj.filters +++ b/voidcmd.vcxproj.filters @@ -27,10 +27,13 @@ Pliki ĹşrĂłdĹ‚owe - + Pliki ĹşrĂłdĹ‚owe - + + Pliki ĹşrĂłdĹ‚owe + + Pliki ĹşrĂłdĹ‚owe @@ -44,13 +47,19 @@ 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 deleted file mode 100644 index 4ee9ba0..0000000 Binary files a/xxhash.dll and /dev/null differ