diff --git a/.gitignore b/.gitignore index 47fe4dc..92b3625 100644 --- a/.gitignore +++ b/.gitignore @@ -367,18 +367,4 @@ test/ test2/ *.pak expak/ -x64/ -test.* -pest2.* -*.hh -*.key -test3/ -test4/ -test5/ -test6/ -test7/ -test8/ -test9/ -test10/ -testx/ -testv/ \ No newline at end of file +x64/ \ 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..40cfbe6 100644 --- a/CreateCargo.cpp +++ b/CreateCargo.cpp @@ -20,15 +20,14 @@ #include "CreateCargo.h" CreateCargo::CreateCargo() - : signature(fl::sigpak) - , extension(fl::extpak) - , methodFlags(0) - , xxhState(XXH64_createState()) + :compressingFlag(false) + , filteringFlag(false) + , signature(SIGNATURE) + , extension(EXTENSION) + , version(VERSION) , offset(0) - , hppKey(false) { // TODO Auto-generated constructor stub - XXH64_reset(xxhState, 0); } CreateCargo::~CreateCargo() { @@ -39,11 +38,12 @@ 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, bool compress, bool filters) { cargoFile = path + "." + extension; catalogPath = path; - methodFlags = flag; + compressingFlag = compress; + filteringFlag = filters; //Sprawdzanie pakowanego kontentu if (!std::filesystem::is_directory(path)) @@ -59,9 +59,9 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) } // Pobieranie listy plików wyjątków - if (flag == -1) + if (filters) { - std::string filterFile = path + ".json"; + std::string filterFile = path + ".txt"; if (!std::filesystem::exists(filterFile)) { std::cerr << "Error: Missing " << filterFile << " file!" << std::endl; @@ -88,12 +88,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 +105,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 +149,48 @@ 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; + + 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) + { + + output = cm.compress(input); + return ZIP_FILE; + } + + output = std::move(input); + return RAW_FILE; +} + //----------------------------------------------------------------------------- // Przygotowanie nagłówków i plików //----------------------------------------------------------------------------- @@ -198,123 +198,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 + 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; } @@ -325,33 +254,18 @@ void CreateCargo::GetFilters(const std::string& filterFile) { std::cout << "Downloading the exception list" << std::endl; - std::ifstream file(filterFile); - nlohmann::json jslist; - file >> jslist; - file.close(); + Txtpp ff(filterFile); // Lista plików do skompresowania - if (jslist.contains(key::zip)) - { - zipList = jslist[key::zip].get>(); - } - - // Lista plików do zaszyfrowania - if (jslist.contains(key::enc)) - { - encList = jslist[key::enc].get>(); - } + zipList = ff.Get(KEY_ZIP); // Lista plików do pominięcia - if (jslist.contains(key::ignore)) - { - ignoreList = jslist[key::ignore].get>(); - } + ignoreList = ff.Get(KEY_IGNORE); - // Flaga tworzenia klucza jako plik nagłówka c++ - hppKey = jslist.value(key::hpp, false); + ff.Close(); } + //----------------------------------------------------------------------------- // Znajdź wskazany element na liście //----------------------------------------------------------------------------- @@ -362,22 +276,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 +313,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 +401,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 +420,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,8 +435,9 @@ 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(); diff --git a/CreateCargo.h b/CreateCargo.h index 279930f..3f020f4 100644 --- a/CreateCargo.h +++ b/CreateCargo.h @@ -25,41 +25,29 @@ #include #include #include +#include #include #include #include #include #include -#include #include "DataStruct.h" -#include "EncryptionManager.h" -#include "CompressionManager.h" +#include "Txtpp.h" +#include "CompressingManager.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_CRYPT "CRYPT" // Plili które mają być zaszyfrowane + +#define ALL_FILE ".*" // Wszystkie pliki -struct PathConf -{ - std::string path; - uint8_t parameter; -}; class CreateCargo { public: @@ -67,15 +55,14 @@ public: virtual ~CreateCargo(); // Punk wejścia do tworzenia archivum - bool Create(const std::string&, const uint8_t&); + bool Create(const std::string&, bool, bool); private: + bool compressingFlag; + bool filteringFlag; const std::string signature; const std::string extension; - - uint8_t methodFlags; - - XXH64_state_t* xxhState; + const uint8_t version; std::string catalogPath; @@ -84,23 +71,18 @@ private: std::vector filesList; - EncryptionManager eman; - CompressionManager cman; - 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; uint64_t offset; + // Tworzenie listy plików do spakowania bool GetFileList(const std::string&); @@ -119,15 +101,33 @@ 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); + + // 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 91bf253..2579c79 100644 --- a/DataStruct.h +++ b/DataStruct.h @@ -21,62 +21,47 @@ #include #include +#include -namespace ui -{ - inline constexpr std::string_view title = "exPak"; - inline constexpr std::string_view ver = "0.5"; -} -// Pliki -namespace fl -{ - inline constexpr std::string_view sigpak = "XPAK"; - inline constexpr std::string_view sigkey = "XKEY"; +#define EXTENSION "pak" +#define SIGNATURE "XPAK" - inline constexpr std::string_view extpak = "pak"; - inline constexpr std::string_view extkey = "key"; -} +#define VERSION 100 -// Size -namespace ds -{ - // Chunki streamowania - inline constexpr uint32_t chunk_stream = 268435456; // 256MB - // Blok chunków - inline constexpr uint32_t block_size = 131072; // 128KB +//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" - // Maksymalny rozmiar pliku do spakowania - inline constexpr uint64_t maxFileSize = 8589934592; // 8GB -} +//Limity +#define MAX_FILE_SIZE 2147483648 // 2GB +#define MAX_PAK_SIZE 8796093022208 // 8TB -// 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 deleted file mode 100644 index a44085e..0000000 --- a/EncryptionManager.cpp +++ /dev/null @@ -1,194 +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 "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) -{ - // 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(), 0); - - // Zapisz ten śmietnik do pliku KEY - std::ofstream file(path + ".key", std::ios::binary); - if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; } - - file.write(fl::sigkey.data(), fl::sigkey.length()); - file.write(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 " << 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; - - 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); - std::vector sig(fl::sigkey.size()); - int8_t ver; - int time; - - // Wczytaj - file.read(sig.data(), sig.size()); - - // Sprawdź czy plik klucza jest poprawny - if (std::string(sig.begin(), sig.end()) != fl::sigkey) - { - 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(), 0) != 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 deleted file mode 100644 index b502b1b..0000000 --- a/EncryptionManager.h +++ /dev/null @@ -1,70 +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 -#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&); - - // Generowanie hash BLAKE2b - //static std::array hashBlake(const std::vector&); - //static bool compareBlake(const std::vector&, const std::array&); - -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 c944347..bf5e028 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)) { @@ -60,14 +59,6 @@ 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); @@ -88,7 +79,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 +88,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 +132,7 @@ bool ExtractCargo::CheckCargoFile() void ExtractCargo::LoadFilesTable() { cargoFile.seekg(tablePosition); + for (uint32_t i = 0; i < filesLen; ++i) { FilesTable fhTmp; @@ -125,10 +142,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 +157,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) : 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..e7d89b3 100644 --- a/ExtractCargo.h +++ b/ExtractCargo.h @@ -28,12 +28,10 @@ #include #include #include -#include #include #include "DataStruct.h" -#include "EncryptionManager.h" -#include "CompressionManager.h" +#include "CompressingManager.h" class ExtractCargo { public: @@ -48,8 +46,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; @@ -57,8 +56,7 @@ private: std::ifstream cargoFile; - EncryptionManager eman; - CompressionManager cman; + // Sprawdzenie poprawności archiwum bool CheckCargoFile(); @@ -69,6 +67,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..3d1d178 100644 --- a/README.md +++ b/README.md @@ -89,11 +89,9 @@ -**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/TimeStamp.h b/TimeStamp.h deleted file mode 100644 index b862f6e..0000000 --- a/TimeStamp.h +++ /dev/null @@ -1,47 +0,0 @@ -#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/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/libsodium/LICENSE.txt b/license/libsodium/LICENSE.txt deleted file mode 100644 index bb85d39..0000000 --- a/license/libsodium/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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/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/xxhash/LICENSE.txt b/license/xxhash/LICENSE.txt deleted file mode 100644 index 52b4c4e..0000000 --- a/license/xxhash/LICENSE.txt +++ /dev/null @@ -1,26 +0,0 @@ -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/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..bd326ff 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,34 @@ 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" " \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 AES256 \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 +79,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 +109,17 @@ int main(int argc, char* argv[]) { if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, 0x0F)) + if (!cargo.Create(path, true, false)) { 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, false, false)) { return 1; } @@ -141,7 +130,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, false, true)) { return 1; } diff --git a/voidcmd.vcxproj b/voidcmd.vcxproj index ee82946..35415ae 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\crc\include;3rd\ftxui\include;3rd\lz4\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 + liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib @@ -119,32 +119,33 @@ 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\crc\include;3rd\ftxui\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\ftxui\Release;3rd\lz4\lib + liblz4_static.lib;ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib - + - + - + - + + diff --git a/voidcmd.vcxproj.filters b/voidcmd.vcxproj.filters index 4dec7bb..b2edffa 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