diff --git a/ChunkManager.cpp b/ChunkManager.cpp new file mode 100644 index 0000000..cfec97b --- /dev/null +++ b/ChunkManager.cpp @@ -0,0 +1,133 @@ +/* + * This file is part of VoidArchiveTool. + * + * Copyright (C) 2025 Yanczi + * + * Void Archive Toolis free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "ChunkManager.h" + +ChunkManager::ChunkManager(EncryptionManager& em) + :eman(em) +{ } + +ChunkManager::~ChunkManager() +{ } + +//----------------------------------------------------------------------------- +// Kompresja blokowa +// +// Dzielenie vectora na chunki dok³adnie po 128KB +// Kompresowanie chunków bez nag³ówka +//----------------------------------------------------------------------------- +std::vector ChunkManager::chunked(const std::vector& raw, const bool& compress, const bool& encrypt) +{ + //std::vector blockSizes; + + // Maksymalny rozmiar chunka + const size_t maxBlockSize = BLOCK_SIZE; + const size_t rawSize = raw.size(); + + 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); + + std::vector outChunk; + + // Przetwórz chunki i przetwórz + if (compress) + { + // Zaszyfruj i skompresuj lub tylko skompresuj + outChunk = encrypt ? eman.encrypt(cman.compress(chunk)) : cman.compress(chunk); + } + else + { + // Zaszyfruj lub skopiuj + outChunk = encrypt ? eman.encrypt(chunk) : std::move(chunk); + } + + uint32_t chs = chunk.size(); + uint32_t zch = outChunk.size(); + + //addIntToVector(compressedBlocks, chs); + lastChunkRawSize = chs; + addIntToVector(compressedBlocks, zch); + compressedBlocks.insert(compressedBlocks.end(), outChunk.begin(), outChunk.end()); + + blockLen++; + } + + std::vector zip; + // Wstaw liczbê o iloœci bloków do vectora; + // Przekonpwertuj usigned int32 na ci¹g znkaów + // uint16_t blockLen = blockSizes .size(); + addIntToVector(zip, blockLen); + addIntToVector(zip, maxBlockSize); + addIntToVector(zip, lastChunkRawSize); + + // Dodaj skompresowane dane + zip.insert(zip.end(), compressedBlocks.begin(), compressedBlocks.end()); + + return zip; +} + +////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------------- +// Dekompresja blokowa +//----------------------------------------------------------------------------- +std::vector ChunkManager::dechunked(const std::vector& zip, const bool& compress, const bool& encrypt) +{ + size_t offset = 0; + const 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 inChunk(chunkZipSize); + std::memcpy(inChunk.data(), zip.data() + offset, chunkZipSize); + offset += chunkZipSize; + + // Jeœli flaga encrypt jest aktywna najpierw zdeszyfruj blok + std::vector zipChunk = encrypt ? eman.decrypt(inChunk) : std::move(inChunk); + + // Zdeklarój pusty chunk + std::vector chunk = compress ? cman.decompress(zipChunk, chunkSize) : std::move(zipChunk); + + // Scal chunki + chunksString.insert(chunksString.end(), chunk.begin(), chunk.end()); + } + + return chunksString; +} \ No newline at end of file diff --git a/ChunkManager.h b/ChunkManager.h new file mode 100644 index 0000000..dd453c7 --- /dev/null +++ b/ChunkManager.h @@ -0,0 +1,70 @@ +/* + * This file is part of VoidArchiveTool. + * + * Copyright (C) 2025 Yanczi + * + * Void Archive Toolis free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "EncryptionManager.h" +#include "CompressionManager.h" + +#define BLOCK_SIZE 131072 // 128KB + +class ChunkManager +{ +public: + ChunkManager(EncryptionManager& em); + ~ChunkManager(); + + // Kompresja danych + std::vector chunked(const std::vector&, const bool&, const bool&); + + // Dekompresja + std::vector dechunked(const std::vector&, const bool&, const bool&); + +private: + EncryptionManager eman; + CompressionManager cman; + + // Przekonwertuj zmienn¹ na ci¹g na vector + template + void addIntToVector(std::vector& vec, const T& val) + { + size_t tmpSize = vec.size(); + vec.resize(tmpSize + sizeof(val)); + std::memcpy(vec.data() + tmpSize, &val, sizeof(val)); + } + + // Pobierz zmienn¹ z vectora + template + T getIntFromVector(const std::vector& vec, size_t& offset) + { + T tmp{}; + std::memcpy(&tmp, vec.data() + offset, sizeof(tmp)); + offset += sizeof(tmp); + + return tmp; + } +}; + diff --git a/CompressionManager.cpp b/CompressionManager.cpp index 0c934b8..27a2435 100644 --- a/CompressionManager.cpp +++ b/CompressionManager.cpp @@ -23,6 +23,9 @@ CompressionManager::CompressionManager() :cctx(ZSTD_createCCtx()) ,dctx(ZSTD_createDCtx()) { + // Tu ustawienia pod kompresjê + const int level = COMPRESSION_LEVEL; + // Ustawienia frameless size_t rc = 0; @@ -39,7 +42,7 @@ CompressionManager::CompressionManager() rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); // Ustawia poziom kompresji - rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd::compression_level); + rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level); if (ZSTD_isError(rc)) { std::cerr << "ZSTD_CCtx_setParameter error" << std::endl; diff --git a/CompressionManager.h b/CompressionManager.h index 5f747fb..83eef36 100644 --- a/CompressionManager.h +++ b/CompressionManager.h @@ -30,10 +30,7 @@ #error "Wymagane zstd >= 1.4.0 dla ZSTD_c_format / ZSTD_f_zstd1_magicless" #endif -namespace zstd -{ - inline constexpr short compression_level = 3; -} +#define COMPRESSION_LEVEL 3 class CompressionManager { diff --git a/CreateCargo.cpp b/CreateCargo.cpp index fe6f7aa..845a915 100644 --- a/CreateCargo.cpp +++ b/CreateCargo.cpp @@ -20,15 +20,14 @@ #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 +38,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, const int16_t& flag) { cargoFile = path + "." + extension; catalogPath = path; @@ -89,9 +88,9 @@ bool CreateCargo::Create(const std::string& path, const uint8_t& flag) } // Zapisywanie klucza szyfruj¹cego - if (flag == flag::enc || flag == flag::ezd || encList.size() > 0) + if (flag == 2 || flag == 3 || encList.size() > 0) { - eman.saveKey(catalogPath, hppKey); + crypt.saveKey(catalogPath, hppKey); } return true; @@ -112,36 +111,28 @@ bool CreateCargo::GetFileList(const std::string& path) else { std::string fileRef = RemoveStartPath(PathToUnixLike(tmpPath)); - - if (fileRef.length() > 255) + PathConf pc; + if (methodFlags > -1) { - std::cerr << "The file path is too long. It exceeds 255 characters." << std::endl; + pc.path = PathToUnixLike(tmpPath); + pc.parameter = methodFlags; + filesPaths.push_back(pc); } else { - PathConf pc; - if (methodFlags != 0xAB) + if (!FindOnTheList(ignoreList, fileRef) || !CheckFileExtension(fileRef, ignoreList)) { - 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)) { - 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); + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? 3 : 1; } + else + { + pc.parameter = FindOnTheList(encList, fileRef) || CheckFileExtension(fileRef, encList) ? 2 : 0; + } + pc.path = PathToUnixLike(tmpPath); + std::cout << pc.path << " - " << pc.parameter << std::endl; + filesPaths.push_back(pc); } } } @@ -184,13 +175,47 @@ 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 +//----------------------------------------------------------------------------- +void CreateCargo::computingBytes(const int16_t& flag, std::vector& input, std::vector& output) +{ + //Flaga aktywna sprawdza czy plik jest na liœcie. Jeœli jest to zwraca surowedane + //Przeciwnie kompresuje dane + ChunkManager cm(crypt); + + switch (flag) + { + case 1: + output = cm.chunked(input, true, false); + break; + + case 2: + output = cm.chunked(input, false, true); + break; + + case 3: + output = cm.chunked(input, true, true); + break; + + case 4: + output = cm.chunked(input, false, false); + break; + + default: + output = std::move(input); + break; + } +} + //----------------------------------------------------------------------------- // Przygotowanie nag³ówków i plików //----------------------------------------------------------------------------- @@ -198,12 +223,13 @@ 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 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; @@ -213,108 +239,36 @@ std::vector CreateCargo::ComputingHeadFiles() std::string path = PathToUnixLike(RemoveStartPath(file.path)); std::ifstream f(file.path, std::ios::binary | std::ios::ate); - std::cout << path << std::endl; - //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 buffer(size); + f.read(buffer.data(), size); + f.close(); - //Wczytanie pliku do pamiêci - std::vector buffer(ds::chunk_stream); + //Tworzenie hashu CRC + const uint64_t crc = XXH64(buffer.data(), buffer.size(), VERSION); - uint64_t sizeFile = 0; + //Kompresjia + std::vector pakBuffer; + computingBytes(file.parameter, buffer, pakBuffer); - 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 = pakBuffer.size(); + ft.flag = file.parameter; + 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(pakBuffer.data()), pakBuffer.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 += pakBuffer.size(); } - return filesTable; } @@ -331,25 +285,24 @@ void CreateCargo::GetFilters(const std::string& filterFile) file.close(); // Lista plików do skompresowania - if (jslist.contains(key::zip)) + if (jslist.contains(KEY_ZIP)) { - zipList = jslist[key::zip].get>(); + zipList = jslist[KEY_ZIP].get>(); } // Lista plików do zaszyfrowania - if (jslist.contains(key::enc)) + if (jslist.contains(KEY_ENCRYPT)) { - encList = jslist[key::enc].get>(); + encList = jslist[KEY_ENCRYPT].get>(); } // Lista plików do pominiêcia - if (jslist.contains(key::ignore)) + if (jslist.contains(KEY_IGNORE)) { - ignoreList = jslist[key::ignore].get>(); + ignoreList = jslist[KEY_IGNORE].get>(); } - // Flaga tworzenia klucza jako plik nag³ówka c++ - hppKey = jslist.value(key::hpp, false); + hppKey = jslist.value("keyhpp", false); } //----------------------------------------------------------------------------- @@ -389,6 +342,24 @@ 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; +} + //----------------------------------------------------------------------------- // Trworzenie archiwum //----------------------------------------------------------------------------- @@ -415,6 +386,7 @@ 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)); @@ -429,8 +401,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..e11d253 100644 --- a/CreateCargo.h +++ b/CreateCargo.h @@ -33,8 +33,8 @@ #include #include "DataStruct.h" +#include "ChunkManager.h" #include "EncryptionManager.h" -#include "CompressionManager.h" #define KEY_ZIP "compress" // Pliki do skompresowania @@ -44,21 +44,10 @@ #define ALL_FILE ".*" // Wszystkie pliki -namespace key -{ - inline constexpr std::string_view zip = "compress"; - inline constexpr std::string_view raw = "raw"; - inline constexpr std::string_view enc = "encrypt"; - inline constexpr std::string_view ignore = "ignore"; - inline constexpr std::string_view all = ".*"; - - inline constexpr std::string_view hpp = "keyhpp"; -} - struct PathConf { std::string path; - uint8_t parameter; + int16_t parameter; }; class CreateCargo { @@ -67,15 +56,14 @@ public: virtual ~CreateCargo(); // Punk wejœcia do tworzenia archivum - bool Create(const std::string&, const uint8_t&); + bool Create(const std::string&, const int16_t&); private: const std::string signature; const std::string extension; + const short version; - uint8_t methodFlags; - - XXH64_state_t* xxhState; + short methodFlags; std::string catalogPath; @@ -84,8 +72,7 @@ private: std::vector filesList; - EncryptionManager eman; - CompressionManager cman; + EncryptionManager crypt; bool hppKey; // listy wyj¹tków @@ -101,6 +88,7 @@ private: uint64_t offset; + // Tworzenie listy plików do spakowania bool GetFileList(const std::string&); @@ -122,12 +110,18 @@ private: // Wczytanie filtrów wyj¹tków void GetFilters(const std::string&); + // Sprawdza czy plik znajduje siê na liœcie + void computingBytes(const int16_t&, std::vector&, std::vector&); + // Sprawdzanie rozsze¿eñ plików bool CheckFileExtension(const std::string&, 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); + // ZnajdŸ wskazany element na liœcie bool FindOnTheList(const std::vector&, const std::string&); }; diff --git a/DataStruct.h b/DataStruct.h index 91bf253..d941faf 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 300 + +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.3" +#define PROGRAM_AUTHOR "Yanczi" +#define PROGRAM_COMPILING "16 November 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; + int16_t version; uint32_t files; + uint64_t table; }; struct FilesTable { - uint8_t nameLen; + int16_t nameLen; std::string nameFile; + uint64_t hashName; uint64_t offset; - uint64_t size; + uint32_t size; uint64_t crc; - uint8_t flag; + int16_t flag; }; \ No newline at end of file diff --git a/EncryptionManager.cpp b/EncryptionManager.cpp index a44085e..32f533d 100644 --- a/EncryptionManager.cpp +++ b/EncryptionManager.cpp @@ -67,6 +67,9 @@ void EncryptionManager::generateKeys() void EncryptionManager::saveKey(const std::string& path, bool hpp) { + const int sig = SIGNATURE_KEY_FILE; + const short ver = VERSION; + // Wygeneruj time stamp std::time_t now = std::time(nullptr); const int time = static_cast(now); @@ -75,13 +78,14 @@ void EncryptionManager::saveKey(const std::string& path, bool hpp) std::vector keyVec(reinterpret_cast(key.data()), reinterpret_cast(key.data()) + key.size()); - const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), 0); + const uint64_t crcKey = XXH64(keyVec.data(), keyVec.size(), VERSION); // Zapisz ten œmietnik do pliku KEY std::ofstream file(path + ".key", std::ios::binary); if (!file) { std::cout << "Failed to save encryption key to file" << std::endl; } - file.write(fl::sigkey.data(), fl::sigkey.length()); + file.write(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)); @@ -98,7 +102,7 @@ void EncryptionManager::saveCppHeadFile(const std::string& path) std::ofstream file(path + ".hpp"); - file << "// Plik wygenerowany przez " << ui::title << " " << ui::ver << std::endl; + file << "// Plik wygenerowany przez " << PROGRAM_TITLE << " " << PROGRAM_VERSION << std::endl; file << std::endl; file << std::endl; file << "#pragma once" << std::endl; @@ -133,15 +137,17 @@ std::string EncryptionManager::toHex(const unsigned char* data, size_t len) void EncryptionManager::loadKey(const std::string& path) { std::ifstream file(path + ".key", std::ios::binary); - std::vector sig(fl::sigkey.size()); - 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!"); } @@ -154,7 +160,7 @@ void EncryptionManager::loadKey(const std::string& path) file.read(reinterpret_cast(&crcKey), sizeof(crcKey)); // SprawdŸ integralnoœæ klucza - if (XXH64(keyVec.data(), keyVec.size(), 0) != crcKey) + if (XXH64(keyVec.data(), keyVec.size(), VERSION) != crcKey) { throw std::runtime_error("Key integrity error!"); } diff --git a/EncryptionManager.h b/EncryptionManager.h index b502b1b..c795bd7 100644 --- a/EncryptionManager.h +++ b/EncryptionManager.h @@ -45,10 +45,6 @@ public: 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; diff --git a/ExtractCargo.cpp b/ExtractCargo.cpp index c944347..4b3e0be 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() @@ -88,7 +89,7 @@ bool ExtractCargo::Extract(const std::string& cFile) bool ExtractCargo::CheckCargoFile() { std::vector magic(signature.size()); - int8_t cargoVer = 0; + short cargoVer = 0; if (!cargoFile.is_open()) { @@ -97,19 +98,73 @@ 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)); + 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; +} + +//----------------------------------------------------------------------------- +// Magiczna funkcja do dekompresji i deszyfracji danych +//----------------------------------------------------------------------------- +void ExtractCargo::computingBytes(const std::vector& input, std::vector& output, const int16_t& flag) +{ + ChunkManager cm(eman); + + switch (flag) + { + case 1: + output = cm.dechunked(input, true, false); + break; + + case 2: + output = cm.dechunked(input, false, true); + break; + + case 3: + output = cm.dechunked(input, true, true); + break; + + case 4: + output = cm.dechunked(input, false, false); + break; + + default: + output = input; + break; + } +} + //----------------------------------------------------------------------------- // Pobieranie nag³ówków plików //----------------------------------------------------------------------------- @@ -125,6 +180,7 @@ 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)); @@ -143,76 +199,24 @@ void ExtractCargo::ExtractingFilesFromCargo() { std::filesystem::path dir = cargoFileName.stem() / fh.nameFile; CreateDirections(dir); - - std::cout << dir.string() << std::endl; - std::ofstream file(dir, std::ios::binary); + cargoFile.seekg(fh.offset); + std::vector buffor(fh.size); - XXH64_reset(xxhState, 0); + cargoFile.read(buffor.data(), fh.size); - // Strumieñ wyci¹gaj¹cy - if (fh.flag == flag::raw) + std::vector rawBuffor; + computingBytes(buffor, rawBuffor, fh.flag); + + if (!HashValid(rawBuffor, fh.crc)) { - for (uint64_t sc = 0; sc < fh.size; sc += ds::chunk_stream) - { - const uint32_t streamChunk = std::min(ds::chunk_stream, static_cast(fh.size - sc)); - - std::vector buffer(streamChunk); - cargoFile.read(buffer.data(), streamChunk); - XXH64_update(xxhState, buffer.data(), buffer.size()); - file.write(reinterpret_cast(buffer.data()), streamChunk); - } + std::cerr << fh.nameFile << " Error: Corrupted data integration CRC" << std::endl; } - else - { - uint32_t chunkLen; - uint32_t chunkBeforeSize; - uint32_t chunkLastSize; - cargoFile.read(reinterpret_cast(&chunkLen), sizeof(chunkLen)); - cargoFile.read(reinterpret_cast(&chunkBeforeSize), sizeof(chunkBeforeSize)); - cargoFile.read(reinterpret_cast(&chunkLastSize), sizeof(chunkLastSize)); - - std::vector chunksString; - - // Dekompresja bloków - for (size_t i = 0; i < chunkLen; ++i) - { - // Pobierz rozmiar chunków przed i po skompresowaniem - uint32_t chunkSize = i < chunkLen - 1 ? chunkBeforeSize : chunkLastSize; - - uint32_t chunkZipSize; - cargoFile.read(reinterpret_cast(&chunkZipSize), sizeof(chunkZipSize)); - - // Pobierz blok chunka - std::vector buffer(chunkZipSize); - cargoFile.read(buffer.data(), chunkZipSize); - - std::vector rawBuffer(chunkSize); - if ((fh.flag & flag::zip) == flag::zip) - { - rawBuffer = (fh.flag & flag::enc) == flag::enc ? - cman.decompress(eman.decrypt(buffer), chunkSize) : - cman.decompress(buffer, chunkSize); - } - else - { - rawBuffer = eman.decrypt(buffer); - } - - XXH64_update(xxhState, rawBuffer.data(), rawBuffer.size()); - file.write(reinterpret_cast(rawBuffer.data()), chunkSize); - } - } + file.write(reinterpret_cast(rawBuffor.data()), rawBuffor.size()); file.close(); - - if (XXH64_digest(xxhState) != fh.crc) - { - std::cerr << dir.string() << " Error: Corrupted data integration CRC" << std::endl; - - } } std::cout << "Unpacking complete!" << std::endl; diff --git a/ExtractCargo.h b/ExtractCargo.h index 9fce5f5..0681494 100644 --- a/ExtractCargo.h +++ b/ExtractCargo.h @@ -28,12 +28,11 @@ #include #include #include -#include #include #include "DataStruct.h" +#include "ChunkManager.h" #include "EncryptionManager.h" -#include "CompressionManager.h" class ExtractCargo { public: @@ -48,8 +47,9 @@ private: uint32_t filesLen; uint64_t tablePosition; - XXH64_state_t* xxhState; + int filesHeadsOffset; + const short 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,7 +69,13 @@ private: // Pobieranie nag³ówków plików void LoadFilesTable(); + // Sprawdzanie sumy kontrolnej + bool HashValid(const std::vector&, const uint64_t&); + // Utwórz katalog void CreateDirections(std::filesystem::path); + // Magiczna funkcja do dekompresji i deszyfracji danych + void computingBytes(const std::vector&, std::vector&, const int16_t&); + }; diff --git a/ViewCargo.cpp b/ViewCargo.cpp index 9b95d12..d5a0df2 100644 --- a/ViewCargo.cpp +++ b/ViewCargo.cpp @@ -20,7 +20,14 @@ #include "ViewCargo.h" ViewCargo::ViewCargo() -{} + :signature(SIGNATURE) + , version(VERSION) + , filesLen(0) + , tablePos(0) +{ + std::vector header = {"Comress", "Encrypt", "Path", "RefHASH"}; + list.push_back(header); +} //----------------------------------------------------------------------------- // Wywo³ywanie @@ -42,25 +49,28 @@ 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; } + //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()); + short cargoVer = 0; std::ifstream cargo(path, std::ios::binary); @@ -71,45 +81,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(); @@ -117,36 +112,91 @@ bool ViewCargo::ViewFiles(const std::string& path) return true; } +//----------------------------------------------------------------------------- +// Pobieranie listy plików z kontenera +//----------------------------------------------------------------------------- +void ViewCargo::GetFileList(const std::string& path) +{ + std::ifstream cargo(path, std::ios::binary); + cargo.seekg(tablePos); + + for (uint32_t i = 0; i < filesLen; ++i) + { + 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.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.flag), sizeof(fhTmp.flag)); + + //Tworzenie wierszy tabeli + CreateTableRow(fhTmp.nameFile, fhTmp.flag, fhTmp.hashName); + } + + cargo.close(); + tui.table(list); +} + //----------------------------------------------------------------------------- // Generowanie wierszy do tabeli //----------------------------------------------------------------------------- -void ViewCargo::ShowFile(const std::string& file, const uint8_t& flag) +void ViewCargo::CreateTableRow(const std::string& file, const uint8_t& zip, const uint64_t& hash) { - std::string compresedCheck = "[ ]"; - std::string encryptedCheck = "[ ]"; + //Zamiania crc liczbowej na hex string + std::stringstream ss; + ss << "0x" << std::hex << std::uppercase << hash; + + //Lista + std::vector tmpList = { "[ ]", "[ ]", file, ss.str() }; + + std::vector cell; + + ftxui::Element eZip; + ftxui::Element eEnc; // Ustawianie checkboxów - switch (flag) + switch (zip) { - case flag::zip: - compresedCheck = "[x]"; + case 1: + //eZip = ftxui::text(" [x] ") | ftxui::color(ftxui::Color::Cyan); + //eEnc = ftxui::text(" [ ] ") | ftxui::color(ftxui::Color::White); + tmpList[0] = "[x]"; break; - case flag::enc: - encryptedCheck = "[x]"; + case 2: + tmpList[1] = "[x]"; break; - case flag::ezd: - compresedCheck = "[x]"; - encryptedCheck = "[x]"; + case 3: + tmpList[0] = "[x]"; + tmpList[1] = "[x]"; break; default: - compresedCheck = "[ ]"; - encryptedCheck = "[ ]"; + tmpList[0] = "[ ]"; + tmpList[1] = "[ ]"; break; } - // Wyœwietlanie - std::cout << compresedCheck << " " << encryptedCheck << " " << file << std::endl; + //Dodanie wiersza do listy + list.push_back(tmpList); +} + +//----------------------------------------------------------------------------- +// 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..1ab452e 100644 --- a/ViewCargo.h +++ b/ViewCargo.h @@ -30,6 +30,7 @@ #include #include "DataStruct.h" +#include "Tui.h" class ViewCargo { public: @@ -39,8 +40,19 @@ public: bool View(const std::string&); private: - bool ViewFiles(const std::string&); - void ShowFile(const std::string&, const uint8_t&); + Tui tui; + const std::string signature; + const uint16_t version; + + uint32_t filesLen; + uint64_t tablePos; + std::vector filesList; + std::vector> list; + + 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/text_file.txt b/testx/text_file.txt index 02a2623..ed2b7f7 100644 --- a/testx/text_file.txt +++ b/testx/text_file.txt @@ -1,126 +1,251 @@ 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 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..35e3644 100644 --- a/voidcmd.cpp +++ b/voidcmd.cpp @@ -80,16 +80,26 @@ static bool EmptyPath(std::string path) } int main(int argc, char* argv[]) { - std::cout << ui::title << std::endl << "ver. " << ui::ver << std::endl; - std::cout << "Author: Yanczi" << std::endl; - std::cout << "License: GNU LGPL v3" << "\n" << std::endl; + std::string path = ""; + + std::cout << + " 8888888b. d8888 888 d8P \n" + " 888 Y88b d88888 888 d8P \n" + " 888 888 d88P888 888 d8P \n" + " .d88b. 888 888 888 d88P d88P 888 888d88K \n" + "d8P Y8b `Y8bd8P' 8888888P\" d88P 888 8888888b \n" + "88888888 X88K 888 d88P 888 888 Y88b \n" + "Y8b. .d8\"\"8b. 888 d8888888888 888 Y88b \n" + " \"Y8888 888 888 888 d88P 888 888 Y88b\n" + << std::endl; + std::cout << "\n" << PROGRAM_VERSION << " Release " << PROGRAM_COMPILING << std::endl; + std::cout << "Author: " << PROGRAM_AUTHOR << std::endl; + std::cout << "License: " << PROGRAM_LICENSE << "\n" << std::endl; CreateCargo cargo; ExtractCargo extract; ViewCargo viewCargo; - std::string path = ""; - for (int i = 0; i < argc; ++i) { std::string arg = argv[i]; @@ -100,7 +110,7 @@ int main(int argc, char* argv[]) { if (!EmptyPath(path)) { return 1; } - if (!cargo.Create(path, 0x0F)) + if (!cargo.Create(path, 1)) { return 1; } @@ -110,7 +120,7 @@ int main(int argc, char* argv[]) { if (arg == "-r" && i + 1 < argc) { path = argv[i + 1]; - if (!cargo.Create(path, 0x00)) + if (!cargo.Create(path, 0)) { return 1; } @@ -120,7 +130,7 @@ int main(int argc, char* argv[]) { if (arg == "-e" && i + 1 < argc) { path = argv[i + 1]; - if (!cargo.Create(path, 0xF0)) + if (!cargo.Create(path, 2)) { return 1; } @@ -130,7 +140,7 @@ int main(int argc, char* argv[]) { if (arg == "-s" && i + 1 < argc) { path = argv[i + 1]; - if (!cargo.Create(path, 0xFF)) + if (!cargo.Create(path, 3)) { return 1; } @@ -141,7 +151,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..119342f 100644 --- a/voidcmd.vcxproj +++ b/voidcmd.vcxproj @@ -103,14 +103,14 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions);SODIUM_STATIC 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\zstd\include;3rd\xxhash\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\zstd\lib\Debug;3rd\ftxui\Debug;3rd\xxhash\lib\Debug;3rd\libsodium\x64\Debug\v143\static + ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib;zstd_static.lib;xxhash.lib @@ -122,29 +122,33 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);SODIUM_STATIC true stdcpp17 - 3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\include + 3rd\ftxui\include;3rd\libsodium\include;3rd\json\include;3rd\zstd\include;3rd\xxhash\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\zstd\lib\Release;3rd\libsodium\x64\Release\v143\static;3rd\xxhash\lib\Release;3rd\ftxui\Release + ftxui-component.lib;ftxui-dom.lib;ftxui-screen.lib;libsodium.lib;zstd_static.lib;xxhash.lib + + + + diff --git a/voidcmd.vcxproj.filters b/voidcmd.vcxproj.filters index 4dec7bb..d4a64b3 100644 --- a/voidcmd.vcxproj.filters +++ b/voidcmd.vcxproj.filters @@ -27,6 +27,12 @@ Pliki źródÅ‚owe + + Pliki źródÅ‚owe + + + Pliki źródÅ‚owe + Pliki źródÅ‚owe @@ -47,6 +53,12 @@ Pliki nagłówkowe + + Pliki nagłówkowe + + + Pliki nagłówkowe + Pliki nagłówkowe