From 7586e8d5abf12161e51b53c0614981f374ac5bab Mon Sep 17 00:00:00 2001 From: xypwn Date: Tue, 5 May 2020 13:40:52 +0200 Subject: [PATCH] Add library functionality for level data --- GDGameSave.hpp | 51 ++++++++++++++++++++++++++++---------------------- Main.cpp | 16 ++++++++++------ 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/GDGameSave.hpp b/GDGameSave.hpp index f5ba638..0fb060d 100644 --- a/GDGameSave.hpp +++ b/GDGameSave.hpp @@ -8,8 +8,7 @@ constexpr int CHUNK = 16384; constexpr int WINDOW_BITS = 15; //Returns true if it was able to open the given file for reading -bool IsFile(const std::string& filename) -{ +bool IsFile(const std::string& filename) { std::ifstream file(filename); const bool ret = file.good(); file.close(); @@ -44,8 +43,7 @@ void Xor_Str(std::string& str, unsigned char key) { } } -std::string GZipDecompress(const std::string& in) -{ +std::string GZipDecompress(const std::string& in) { //Initialize all members of strm to be 0 z_stream strm = {}; //Output buffer @@ -82,8 +80,7 @@ std::string GZipDecompress(const std::string& in) return final_output; } -std::string GZipCompress(const std::string& in) -{ +std::string GZipCompress(const std::string& in) { //Initialize all members of strm to be 0 z_stream strm = {}; //Output buffer @@ -114,11 +111,17 @@ std::string GZipCompress(const std::string& in) return final_output; } -std::string Decrypt(const std::string& filename) { - //load file - std::string ret = FileToStr(filename); - //Xor with value 11 - Xor_Str(ret, 11); +/** @brief Decrypt GD save files or level data * + * @param in_data encrypted input data * + * @param xor11 whether or not the data should be xored with 11; * + * select true for gamesave or false for level data * + * @retval decrypted data **/ +std::string Decrypt(const std::string& in_data, bool xor11) { + //Retun value + std::string ret = in_data; + //Xor with value 11 if nescessary + if(xor11) + Xor_Str(ret, 11); //replace - with + and _ with / for (auto& i : ret) { if (i == '-') @@ -134,20 +137,23 @@ std::string Decrypt(const std::string& filename) { return ret; } -std::string Encrypt(const std::string& filename) { - //load file - std::string data = FileToStr(filename); - //Calculate crc32 checksum - uLong crc = crc32(0L, Z_NULL, 0); - uint32_t crc32_sum = crc32(crc, (Bytef*)data.data(), data.size()); - uint32_t dataSize = data.size(); +/** @brief Encrypt GD save files or level data * + * @param in_data decrypted input data * + * @param xor11 whether or not the data should be xored with 11; * + * select true for gamesave or false for level data * + * @retval encrypted data **/ +std::string Encrypt(const std::string& in_data, bool xor11) { + //Calculate crc32 checksum and size + const uLong crc = crc32(0L, Z_NULL, 0); + const uint32_t crc32_sum = crc32(crc, (Bytef*)in_data.data(), in_data.size()); + const uint32_t dataSize = in_data.size(); //Compress with GZip - std::string ret = GZipCompress(data); + std::string ret = GZipCompress(in_data); //Remove first 2 and last 4 chars of string ret = ret.substr(2, ret.size() - 4 - 2); //Add header, checksum and size char header[10] = {'\x1f', '\x8b', '\x08', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0b'}; - ret = std::string(header, sizeof(header)) + + ret = std::string(header, sizeof(header)) + ret + std::string((const char*)&crc32_sum, sizeof(crc32_sum)) + //Use raw binary data std::string((const char*)&dataSize, sizeof(dataSize)); //Use raw binary data @@ -160,8 +166,9 @@ std::string Encrypt(const std::string& filename) { if (i == '/') i = '_'; } - //Xor with value 11 - Xor_Str(ret, 11); + //Xor with value 11 if nescessary + if(xor11) + Xor_Str(ret, 11); //Return return ret; } \ No newline at end of file diff --git a/Main.cpp b/Main.cpp index 859d0b7..5e8d925 100755 --- a/Main.cpp +++ b/Main.cpp @@ -20,24 +20,27 @@ const std::string commands = R"(Commands: 3: Encrypt and save to GD folder 0: Quit)"; -enum class Command -{ +enum class Command { Decrypt, Encrypt }; -bool ExecCommand(Command cmd, const std::string& in_filename, const std::string& out_filename) -{ +bool ExecCommand(Command cmd, const std::string& in_filename, const std::string& out_filename) { + //Check if input file is valid if(!IsFile(in_filename)) { std::cerr << "ERROR: Could not open file " << in_filename << " for reading" << std::endl; return false; } + //Read file data into a string + std::string data = FileToStr(in_filename); + switch(cmd) { case Command::Decrypt: std::cout << "Decrypting " << in_filename << "..." << std::endl; - if(!StrToFile(out_filename, Decrypt(in_filename))) + // Attempt to decrypt data and save it in the given output file + if(!StrToFile(out_filename, Decrypt(data, true))) { std::cerr << "ERROR: Could not open file " << out_filename << " for writing" << std::endl; return false; @@ -45,7 +48,8 @@ bool ExecCommand(Command cmd, const std::string& in_filename, const std::string& break; case Command::Encrypt: std::cout << "Encrypting " << in_filename << "..." << std::endl; - if(!StrToFile(out_filename, Encrypt(in_filename))) + // Attempt to encrypt data and save it in the given output file + if(!StrToFile(out_filename, Encrypt(data, true))) { std::cerr << "ERROR: Could not open file " << out_filename << " for writing" << std::endl; return false;