431 lines
12 KiB
C++
431 lines
12 KiB
C++
#include "sgu_stdafx.h"
|
|
#include "sgu_arg_opt.h"
|
|
#include "sgu_utils.h"
|
|
#include "sgu_mode_gen_rand_file.h"
|
|
#include "sgu_mode_rand_modify.h"
|
|
#include "sgu_mode_rand_remove.h"
|
|
#include "sgu_mode_rand_insert.h"
|
|
#include "sgu_mode_make_diff.h"
|
|
#include "sgu_mode_apply_patch.h"
|
|
#include "sgu_mode_hash_file.h"
|
|
#include "sgu_mode_download.h"
|
|
#include "sgu_mode_run_lua_file.h"
|
|
|
|
#include "libEncrypt_AES.h"
|
|
|
|
enum { OPT_MODE,
|
|
OPT_INPUT, OPT_INPUT2, OPT_OUTPUT,
|
|
OPT_MIN_SIZE, OPT_MAX_SIZE,
|
|
OPT_COUNTS,
|
|
OPT_TYPE,
|
|
OPT_VERBOSE_MODE,
|
|
OPT_HELP
|
|
};
|
|
|
|
CSimpleOptA::SOption g_rgOptions[] = {
|
|
{ OPT_MODE, "-m", SO_REQ_SEP }, // "-m mode"
|
|
{ OPT_INPUT, "-i", SO_REQ_SEP }, // "-i input.bin"
|
|
{ OPT_INPUT2, "-i2", SO_REQ_SEP }, // "-i2 input2.bin"
|
|
{ OPT_OUTPUT, "-o", SO_REQ_SEP }, // "-o output.bin"
|
|
{ OPT_MIN_SIZE, "-min", SO_REQ_SEP }, // "-min 100|201MB|2.5GB"
|
|
{ OPT_MAX_SIZE, "-max", SO_REQ_SEP }, // "-max 100|201MB|2.5GB"
|
|
{ OPT_COUNTS, "-c", SO_REQ_SEP }, // "-c 5"
|
|
{ OPT_TYPE, "-t", SO_REQ_SEP }, // "-t md5|sha256"
|
|
{ OPT_VERBOSE_MODE, "-v", SO_NONE }, // "-v"
|
|
|
|
{ OPT_HELP, "-?", SO_NONE }, // "-?"
|
|
{ OPT_HELP, "--help", SO_NONE }, // "--help"
|
|
SO_END_OF_OPTIONS // END
|
|
};
|
|
|
|
static void printUsage(const char* moduleName)
|
|
{
|
|
printf("===== DNF SideGameplay Utils =====\n");
|
|
printf("Usage: %s -m [MODE] [OPTIONS]\n", moduleName);
|
|
printf("\t -m Mode\tfunctioning mode\n");
|
|
printf("\t -i FileName\tInput file name\n");
|
|
printf("\t -i2 FileName\tSecond Input file name\n");
|
|
printf("\t -o FileName\tOutput file name\n");
|
|
printf("\t -min Size\tMini size[kb|mb|gb]\n");
|
|
printf("\t -max Size\tMax size[kb|mb|gb]\n");
|
|
printf("\t -c Counts\n");
|
|
printf("\t -t Type\n");
|
|
printf("\t -v\t\tVerbose Mode\n");
|
|
printf("\t --help -?\tShow help info\n");
|
|
printf("\nMode List:\n");
|
|
printf(" GenRandFile\tGenerate random file with specified size range\n");
|
|
printf(" RandModifyFile\tModifies an input file by replacing multiple randomly selected segments with random data.\n");
|
|
printf(" RandInsertFile\tInserts random data segments at random positions within an input file.\n");
|
|
printf(" RandRemoveFile\tRemoves multiple randomly selected segments from an input file.\n");
|
|
printf(" MakeDiff\tCreates a binary diff patch file between two input files using BSDIFF43.\n");
|
|
printf(" ApplyPatch\tApplies a BSDIFF43 binary patch to an input file and writes the patched result to an output file.\n");
|
|
printf(" HashFile\tCalculates the hash(MD5|SHA256) of the contents of a specified file.\n");
|
|
printf(" Download\tDownloads a file from a specified URL and saves it to a local file.\n");
|
|
printf(" Upload\tUpload a local file to a specified cos server.\n");
|
|
printf(" RunLuaFile\t xxxx \n");
|
|
printf("\nSample:\n");
|
|
printf(" -m GenRandFile -min 500 -max 1k -o rand.bin\n");
|
|
printf(" -m RandModifyFile -i ver01.bin -min 100 -max 1k -c 3 -o ver02.bin\n");
|
|
printf(" -m RandInsertFile -i ver01.bin -min 1g -max 2g -c 5 -o ver02.bin\n");
|
|
printf(" -m RandRemoveFile -i ver01.bin -min 10m -max 20m -c 2 -o ver02.bin\n");
|
|
printf(" -m MakeDiff -i ver01.bin -i2 ver02.bin -o patch_ver01_ver02.diff\n");
|
|
printf(" -m ApplyPatch -i ver01.bin -i2 patch_ver01_ver02.diff -o ver02.bin\n");
|
|
printf(" -m HashFile -t md5 -i ver01.bin\n");
|
|
printf(" -m HashFile -t sha256 -i ver01.bin\n");
|
|
printf(" -m Download -i http://download.com/file.txt -o file.txt\n");
|
|
printf(" -m Upload -i file.txt -o cos:\\path\file.txt \n");
|
|
printf(" -m RunLuaFile -i script.lua\n");
|
|
}
|
|
|
|
enum WorkMode {
|
|
WM_NONE=0,
|
|
|
|
WM_GEN_RANDOM_FILE,
|
|
WM_RANDOM_MODIFY_FILE,
|
|
WM_RANDOM_INSERT_FILE,
|
|
WM_RANDOM_REMOVE_FILE,
|
|
WM_MAKE_DIFF,
|
|
WM_APPLY_PATCH,
|
|
WM_HASH_FILE,
|
|
WM_DOWNLOAD,
|
|
WM_UPLOAD,
|
|
WM_RUN_LUA_FILE,
|
|
};
|
|
|
|
enum HashType {
|
|
HT_NONE = 0,
|
|
|
|
HT_MD5,
|
|
HT_SHA256,
|
|
HT_CRC32
|
|
};
|
|
|
|
WorkMode parserWorkMode(const char* modeStr)
|
|
{
|
|
if(modeStr== nullptr || *modeStr == '\0') {
|
|
return WM_NONE;
|
|
}
|
|
|
|
if (_stricmp(modeStr, "GenRandFile") == 0) {
|
|
return WM_GEN_RANDOM_FILE;
|
|
}
|
|
else if (_stricmp(modeStr, "RandModifyFile") == 0) {
|
|
return WM_RANDOM_MODIFY_FILE;
|
|
}
|
|
else if (_stricmp(modeStr, "RandInsertFile") == 0) {
|
|
return WM_RANDOM_INSERT_FILE;
|
|
}
|
|
else if (_stricmp(modeStr, "RandRemoveFile") == 0) {
|
|
return WM_RANDOM_REMOVE_FILE;
|
|
}
|
|
else if (_stricmp(modeStr, "MakeDiff") == 0) {
|
|
return WM_MAKE_DIFF;
|
|
}
|
|
else if (_stricmp(modeStr, "ApplyPatch") == 0) {
|
|
return WM_APPLY_PATCH;
|
|
}
|
|
else if (_stricmp(modeStr, "HashFile") == 0) {
|
|
return WM_HASH_FILE;
|
|
}
|
|
else if (_stricmp(modeStr, "Download") == 0) {
|
|
return WM_DOWNLOAD;
|
|
}
|
|
else if (_stricmp(modeStr, "Upload") == 0) {
|
|
return WM_UPLOAD;
|
|
}
|
|
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
|
|
return WM_RUN_LUA_FILE;
|
|
}
|
|
return WM_NONE;
|
|
}
|
|
|
|
HashType parserHashType(const char* typeStr)
|
|
{
|
|
if(typeStr == nullptr || *typeStr == '\0') {
|
|
return HT_NONE;
|
|
}
|
|
|
|
if (_stricmp(typeStr, "md5") == 0) {
|
|
return HT_MD5;
|
|
}
|
|
else if (_stricmp(typeStr, "sha256") == 0) {
|
|
return HT_SHA256;
|
|
}
|
|
else if (_stricmp(typeStr, "crc32") == 0) {
|
|
return HT_CRC32;
|
|
}
|
|
return HT_NONE; // default to HT_NONE
|
|
}
|
|
|
|
const int kDiffCompressMethod = 2;
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
CSimpleOptA args(argc, argv, g_rgOptions);
|
|
|
|
WorkMode workMode = WM_NONE;
|
|
const char* inputFilename = nullptr;
|
|
const char* inputFilename2 = nullptr;
|
|
const char* outputFilename = nullptr;
|
|
int64_t minSize = 0;
|
|
int64_t maxSize = 0;
|
|
int32_t counts = 0;
|
|
const char* stringType = nullptr;
|
|
bool verboseMode = false;
|
|
|
|
while (args.Next()) {
|
|
if (args.LastError() == SO_SUCCESS) {
|
|
if (args.OptionId() == OPT_HELP) {
|
|
printUsage(argv[0]);
|
|
return 0;
|
|
}
|
|
else if (args.OptionId() == OPT_MODE) {
|
|
workMode = parserWorkMode(args.OptionArg());
|
|
}
|
|
else if (args.OptionId() == OPT_INPUT) {
|
|
inputFilename = args.OptionArg();
|
|
}
|
|
else if (args.OptionId() == OPT_INPUT2) {
|
|
inputFilename2 = args.OptionArg();
|
|
}
|
|
else if (args.OptionId() == OPT_OUTPUT) {
|
|
outputFilename = args.OptionArg();
|
|
}
|
|
else if (args.OptionId() == OPT_MIN_SIZE) {
|
|
minSize = sizeFromString(args.OptionArg());
|
|
}
|
|
else if (args.OptionId() == OPT_MAX_SIZE) {
|
|
maxSize = sizeFromString(args.OptionArg());
|
|
}
|
|
else if (args.OptionId() == OPT_COUNTS) {
|
|
counts = atoi(args.OptionArg());
|
|
}
|
|
else if (args.OptionId() == OPT_TYPE) {
|
|
stringType = args.OptionArg();
|
|
}
|
|
else if (args.OptionId() == OPT_VERBOSE_MODE) {
|
|
verboseMode = true;
|
|
}
|
|
}
|
|
else {
|
|
printf("Invalid argument: %s\n", args.OptionText());
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//init random seed
|
|
std::srand((unsigned int)time(NULL));
|
|
|
|
switch (workMode)
|
|
{
|
|
case WM_GEN_RANDOM_FILE:
|
|
{
|
|
if(outputFilename==nullptr || minSize==0 || maxSize==0) {
|
|
printf("Error: For 'gen' mode, you must specify output file and size range.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Generating random file with min size: %s, max size: %s, output: %s\n",
|
|
sizeToString(minSize).c_str(), sizeToString(maxSize).c_str(), outputFilename);
|
|
if (!generateRandomFile(minSize, maxSize, outputFilename))
|
|
{
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_RANDOM_MODIFY_FILE:
|
|
{
|
|
if(inputFilename == nullptr || outputFilename == nullptr || minSize == 0 || maxSize == 0 || counts==0)
|
|
{
|
|
printf("Error: For 'modify' mode, you must specify input file, output file, size range and counts.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
if(!randomModifyFile(inputFilename, outputFilename, minSize, maxSize, counts))
|
|
{
|
|
printf("Error: Failed to modify file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_RANDOM_REMOVE_FILE:
|
|
{
|
|
if (inputFilename == nullptr || outputFilename == nullptr || minSize == 0 || maxSize == 0 || counts == 0)
|
|
{
|
|
printf("Error: For 'remove' mode, you must specify input file, output file, size range and counts.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
if (!randRemovePartOfFile(inputFilename, outputFilename, minSize, maxSize, counts))
|
|
{
|
|
printf("Error: Failed to remove part of file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_RANDOM_INSERT_FILE:
|
|
{
|
|
if (inputFilename == nullptr || outputFilename == nullptr || minSize == 0 || maxSize == 0 || counts == 0)
|
|
{
|
|
printf("Error: For 'insert' mode, you must specify input file, output file, size range and counts.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
if(!insertRandomDataInFile(inputFilename, outputFilename, minSize, maxSize, counts))
|
|
{
|
|
printf("Error: Failed to insert data in file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case WM_HASH_FILE:
|
|
{
|
|
if(inputFilename==nullptr )
|
|
{
|
|
printf("Error: For 'hash' mode, you must specify input file.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
HashType hashType = parserHashType(stringType);
|
|
if(hashType==HT_NONE)
|
|
{
|
|
printf("Error: Invalid hash type '%s'. Supported types are 'md5' and 'sha256'.\n", stringType);
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Calculating hash for file[%s]: %s\n", stringType, inputFilename);
|
|
|
|
if(hashType == HT_SHA256)
|
|
{
|
|
Sha256Digest result;
|
|
if (!sha256File(inputFilename, result))
|
|
{
|
|
return 1;
|
|
}
|
|
printf("SHA256(%s) = %s\n", inputFilename, sha256ToString(result).c_str());
|
|
}
|
|
else if (hashType == HT_MD5)
|
|
{
|
|
MD5Digest result;
|
|
if (!md5File(inputFilename, result))
|
|
{
|
|
return 1;
|
|
}
|
|
printf("MD5(%s) = %s\n", inputFilename, md5ToString(result).c_str());
|
|
}
|
|
else if(hashType == HT_CRC32)
|
|
{
|
|
uint32_t crc32;
|
|
if (!crc32File(inputFilename, crc32))
|
|
{
|
|
return 1;
|
|
}
|
|
printf("CRC32(%s) = %08X\n", inputFilename, crc32);
|
|
}
|
|
else
|
|
{
|
|
printf("Error: Unsupported hash type.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_MAKE_DIFF:
|
|
{
|
|
if (inputFilename == nullptr || inputFilename2 == nullptr || outputFilename == nullptr)
|
|
{
|
|
printf("Error: For 'diff' mode, you must specify two input files and an output file.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Creating diff between %s and %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
|
if (!createDiff(inputFilename, inputFilename2, outputFilename, kDiffCompressMethod))
|
|
{
|
|
printf("Error: Failed to create diff file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_APPLY_PATCH:
|
|
{
|
|
if (inputFilename == nullptr || inputFilename2 == nullptr || outputFilename == nullptr)
|
|
{
|
|
printf("Error: For 'patch' mode, you must specify two input files and an output file.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Applying patch from %s with patch %s, output: %s\n", inputFilename, inputFilename2, outputFilename);
|
|
if (!applyPatch(inputFilename, inputFilename2, outputFilename, kDiffCompressMethod))
|
|
{
|
|
printf("Error: Failed to apply patch.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case WM_DOWNLOAD:
|
|
{
|
|
if (inputFilename == nullptr || outputFilename == nullptr)
|
|
{
|
|
printf("Error: For 'download' mode, you must specify input URL and output file.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Downloading from %s to %s\n", inputFilename, outputFilename);
|
|
if (!downloadFile(inputFilename, outputFilename))
|
|
{
|
|
printf("Error: Failed to download file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_UPLOAD:
|
|
{
|
|
if (inputFilename == nullptr || outputFilename == nullptr)
|
|
{
|
|
printf("Error: For 'upload' mode, you must specify input local file and output cos path.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Uploading from %s to %s\n", inputFilename, outputFilename);
|
|
if(!uploadFile(inputFilename, outputFilename))
|
|
{
|
|
printf("Error: Failed to upload file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_RUN_LUA_FILE:
|
|
{
|
|
if (inputFilename == nullptr)
|
|
{
|
|
printf("Error: For 'RunLuaFile' mode, you must specify input Lua script file.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
printf("Running Lua script file: %s\n", inputFilename);
|
|
if (!run_lua_file(inputFilename))
|
|
{
|
|
printf("Error: Failed to run Lua script file.\n");
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case WM_NONE:
|
|
default:
|
|
{
|
|
printf("Error: Mode is not specified. Use -m option.\n");
|
|
printUsage(::PathFindFileNameA(argv[0]));
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|