Add library functionality for level data

This commit is contained in:
xypwn 2020-05-05 13:40:52 +02:00
parent 9bbd5cf16a
commit 7586e8d5ab
2 changed files with 39 additions and 28 deletions

View File

@ -8,8 +8,7 @@ constexpr int CHUNK = 16384;
constexpr int WINDOW_BITS = 15; constexpr int WINDOW_BITS = 15;
//Returns true if it was able to open the given file for reading //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); std::ifstream file(filename);
const bool ret = file.good(); const bool ret = file.good();
file.close(); 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 //Initialize all members of strm to be 0
z_stream strm = {}; z_stream strm = {};
//Output buffer //Output buffer
@ -82,8 +80,7 @@ std::string GZipDecompress(const std::string& in)
return final_output; 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 //Initialize all members of strm to be 0
z_stream strm = {}; z_stream strm = {};
//Output buffer //Output buffer
@ -114,11 +111,17 @@ std::string GZipCompress(const std::string& in)
return final_output; return final_output;
} }
std::string Decrypt(const std::string& filename) { /** @brief Decrypt GD save files or level data *
//load file * @param in_data encrypted input data *
std::string ret = FileToStr(filename); * @param xor11 whether or not the data should be xored with 11; *
//Xor with value 11 * select true for gamesave or false for level data *
Xor_Str(ret, 11); * @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 / //replace - with + and _ with /
for (auto& i : ret) { for (auto& i : ret) {
if (i == '-') if (i == '-')
@ -134,20 +137,23 @@ std::string Decrypt(const std::string& filename) {
return ret; return ret;
} }
std::string Encrypt(const std::string& filename) { /** @brief Encrypt GD save files or level data *
//load file * @param in_data decrypted input data *
std::string data = FileToStr(filename); * @param xor11 whether or not the data should be xored with 11; *
//Calculate crc32 checksum * select true for gamesave or false for level data *
uLong crc = crc32(0L, Z_NULL, 0); * @retval encrypted data **/
uint32_t crc32_sum = crc32(crc, (Bytef*)data.data(), data.size()); std::string Encrypt(const std::string& in_data, bool xor11) {
uint32_t dataSize = data.size(); //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 //Compress with GZip
std::string ret = GZipCompress(data); std::string ret = GZipCompress(in_data);
//Remove first 2 and last 4 chars of string //Remove first 2 and last 4 chars of string
ret = ret.substr(2, ret.size() - 4 - 2); ret = ret.substr(2, ret.size() - 4 - 2);
//Add header, checksum and size //Add header, checksum and size
char header[10] = {'\x1f', '\x8b', '\x08', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x0b'}; 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 + ret +
std::string((const char*)&crc32_sum, sizeof(crc32_sum)) + //Use raw binary data std::string((const char*)&crc32_sum, sizeof(crc32_sum)) + //Use raw binary data
std::string((const char*)&dataSize, sizeof(dataSize)); //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 == '/') if (i == '/')
i = '_'; i = '_';
} }
//Xor with value 11 //Xor with value 11 if nescessary
Xor_Str(ret, 11); if(xor11)
Xor_Str(ret, 11);
//Return //Return
return ret; return ret;
} }

View File

@ -20,24 +20,27 @@ const std::string commands = R"(Commands:
3: Encrypt and save to GD folder 3: Encrypt and save to GD folder
0: Quit)"; 0: Quit)";
enum class Command enum class Command {
{
Decrypt, Decrypt,
Encrypt 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)) if(!IsFile(in_filename))
{ {
std::cerr << "ERROR: Could not open file " << in_filename << " for reading" << std::endl; std::cerr << "ERROR: Could not open file " << in_filename << " for reading" << std::endl;
return false; return false;
} }
//Read file data into a string
std::string data = FileToStr(in_filename);
switch(cmd) switch(cmd)
{ {
case Command::Decrypt: case Command::Decrypt:
std::cout << "Decrypting " << in_filename << "..." << std::endl; 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; std::cerr << "ERROR: Could not open file " << out_filename << " for writing" << std::endl;
return false; return false;
@ -45,7 +48,8 @@ bool ExecCommand(Command cmd, const std::string& in_filename, const std::string&
break; break;
case Command::Encrypt: case Command::Encrypt:
std::cout << "Encrypting " << in_filename << "..." << std::endl; 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; std::cerr << "ERROR: Could not open file " << out_filename << " for writing" << std::endl;
return false; return false;