使用lua实现npk操作
This commit is contained in:
@@ -27,10 +27,10 @@ uint8_t* readFileToBuffer(const char* filename, int64_t& outSize);
|
|||||||
void freeFileBuffer(uint8_t* buffer);
|
void freeFileBuffer(uint8_t* buffer);
|
||||||
|
|
||||||
// Clears the specified path by deleting all files and optionally removing the directory itself.
|
// Clears the specified path by deleting all files and optionally removing the directory itself.
|
||||||
bool clearPath(const char* szPath, bool recursion, bool removeSelf);
|
bool clearPath(const wchar_t* szPath, bool recursion, bool removeSelf);
|
||||||
|
|
||||||
//Creates an empty directory at the specified path. If the path already exists and is a directory, clears its contents.
|
//Creates an empty directory at the specified path. If the path already exists and is a directory, clears its contents.
|
||||||
bool createEmptyPath(const char* szPath);
|
bool createEmptyPath(const wchar_t* szPath);
|
||||||
|
|
||||||
// Force create a directory path, ensuring all parent directories are created as needed.
|
// Force create a directory path, ensuring all parent directories are created as needed.
|
||||||
bool forceCreatePath(const wchar_t* szPath);
|
bool forceCreatePath(const wchar_t* szPath);
|
||||||
|
|||||||
@@ -186,13 +186,13 @@ void freeFileBuffer(uint8_t* buffer)
|
|||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clearPath(const char* szPath, bool recursion, bool removeSelf)
|
bool clearPath(const wchar_t* szPath, bool recursion, bool removeSelf)
|
||||||
{
|
{
|
||||||
char szTemp[MAX_PATH] = { 0 };
|
wchar_t szTemp[MAX_PATH] = { 0 };
|
||||||
StringCbCopyA(szTemp, sizeof(szTemp)-1, szPath);
|
StringCbCopyW(szTemp, sizeof(szTemp)-1, szPath);
|
||||||
PathAppend(szTemp, "*.*");
|
PathAppendW(szTemp, L"*.*");
|
||||||
|
|
||||||
SHFILEOPSTRUCT shf;
|
SHFILEOPSTRUCTW shf;
|
||||||
SecureZeroMemory(&shf, sizeof(SHFILEOPSTRUCT));
|
SecureZeroMemory(&shf, sizeof(SHFILEOPSTRUCT));
|
||||||
|
|
||||||
shf.hwnd = NULL;
|
shf.hwnd = NULL;
|
||||||
@@ -204,37 +204,37 @@ bool clearPath(const char* szPath, bool recursion, bool removeSelf)
|
|||||||
shf.fFlags |= FOF_NORECURSION;
|
shf.fFlags |= FOF_NORECURSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != SHFileOperation(&shf))
|
if (0 != SHFileOperationW(&shf))
|
||||||
{
|
{
|
||||||
return false; // Failed to delete files
|
return false; // Failed to delete files
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removeSelf)
|
if (removeSelf)
|
||||||
{
|
{
|
||||||
if (!RemoveDirectory(szPath))
|
if (!RemoveDirectoryW(szPath))
|
||||||
{
|
{
|
||||||
printf("Error: Failed to remove directory %s\n", szPath);
|
printf("Error: Failed to remove directory\n");
|
||||||
return false; // Failed to remove directory
|
return false; // Failed to remove directory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // Successfully cleared the path
|
return true; // Successfully cleared the path
|
||||||
}
|
}
|
||||||
|
|
||||||
bool createEmptyPath(const char* szPath)
|
bool createEmptyPath(const wchar_t* szPath)
|
||||||
{
|
{
|
||||||
if (!szPath || szPath[0] == 0)
|
if (!szPath || szPath[0] == 0)
|
||||||
{
|
{
|
||||||
printf("Error: Invalid path provided for directory creation.\n");
|
printf("Error: Invalid path provided for directory creation.\n");
|
||||||
return false; // Invalid path
|
return false; // Invalid path
|
||||||
}
|
}
|
||||||
if (::PathFileExists(szPath))
|
if (::PathFileExistsW(szPath))
|
||||||
{
|
{
|
||||||
if (::PathIsDirectory(szPath))
|
if (::PathIsDirectoryW(szPath))
|
||||||
{
|
{
|
||||||
// Clear the directory
|
// Clear the directory
|
||||||
if (!clearPath(szPath, true, false))
|
if (!clearPath(szPath, true, false))
|
||||||
{
|
{
|
||||||
printf("Failed to clear output directory: '%s'\n", szPath);
|
printf("Failed to clear output directory\n");
|
||||||
return false; // Failed to clear output directory
|
return false; // Failed to clear output directory
|
||||||
}
|
}
|
||||||
return true; // Directory exists and is cleared
|
return true; // Directory exists and is cleared
|
||||||
@@ -242,17 +242,17 @@ bool createEmptyPath(const char* szPath)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If it exists but is not a directory, delete the file
|
// If it exists but is not a directory, delete the file
|
||||||
if(!DeleteFileA(szPath) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
|
if(!DeleteFileW(szPath) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||||
{
|
{
|
||||||
printf("Failed to delete existing file: '%s', Error=%d\n", szPath, ::GetLastError());
|
printf("Failed to delete existing file, Error=%d\n", ::GetLastError());
|
||||||
return false; // Failed to delete existing file
|
return false; // Failed to delete existing file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!::CreateDirectory(szPath, NULL) && ::GetLastError() != ERROR_ALREADY_EXISTS)
|
if (!::CreateDirectoryW(szPath, NULL) && ::GetLastError() != ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
printf("Failed to create output directory: '%s', Error=%d\n", szPath, ::GetLastError());
|
printf("Failed to create output directory, Error=%d\n", ::GetLastError());
|
||||||
return false; // Failed to create output directory
|
return false; // Failed to create output directory
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ add_executable(sgutil
|
|||||||
sgu_mode_rand_modify.h
|
sgu_mode_rand_modify.h
|
||||||
sgu_mode_rand_remove.cpp
|
sgu_mode_rand_remove.cpp
|
||||||
sgu_mode_rand_remove.h
|
sgu_mode_rand_remove.h
|
||||||
sgu_mode_npk_dump_list.h
|
|
||||||
sgu_mode_npk_dump_list.cpp
|
|
||||||
sgu_mode_npk_extract_files.h
|
|
||||||
sgu_mode_npk_extract_files.cpp
|
|
||||||
sgu_mode_run_lua_file.h
|
sgu_mode_run_lua_file.h
|
||||||
sgu_mode_run_lua_file.cpp
|
sgu_mode_run_lua_file.cpp
|
||||||
sgu_utils.cpp
|
sgu_utils.cpp
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ function M.extract_npk_files(npkFileName, outputPath)
|
|||||||
|
|
||||||
local ret = npk:openPakFile(npkFileName)
|
local ret = npk:openPakFile(npkFileName)
|
||||||
if(not ret) then
|
if(not ret) then
|
||||||
|
print("Can't open npk file:" .. npkFileName)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
ret = createEmptyPath(outputPath)
|
||||||
|
if(not ret) then
|
||||||
|
print("Can't create ouput path: " .. outputPath)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -19,7 +26,7 @@ function M.extract_npk_files(npkFileName, outputPath)
|
|||||||
|
|
||||||
local fileStream = npk:openFileStream(baseInfo:keyName())
|
local fileStream = npk:openFileStream(baseInfo:keyName())
|
||||||
|
|
||||||
print("keyName=" .. fileStream:name() .. "\n")
|
print("keyName=" .. fileStream:name())
|
||||||
|
|
||||||
local diskFileName = outputPath .. "/" .. baseInfo:keyName()
|
local diskFileName = outputPath .. "/" .. baseInfo:keyName()
|
||||||
ret = forceCreatePathForFile(diskFileName);
|
ret = forceCreatePathForFile(diskFileName);
|
||||||
|
|||||||
@@ -27,8 +27,16 @@ bool luaForceCreatePath(const char* szPath)
|
|||||||
return forceCreatePath(strPath.c_str());
|
return forceCreatePath(strPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//utf8
|
||||||
|
bool luaCreateEmptyPath(const char* szPath)
|
||||||
|
{
|
||||||
|
std::wstring strPath = convertUtf8StringToWide(szPath);
|
||||||
|
return createEmptyPath(strPath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void registerUtilsLuaLibs(struct lua_State* L)
|
void registerUtilsLuaLibs(struct lua_State* L)
|
||||||
{
|
{
|
||||||
lua_tinker::def(L, "forceCreatePath", &luaForceCreatePath);
|
lua_tinker::def(L, "forceCreatePath", &luaForceCreatePath);
|
||||||
lua_tinker::def(L, "forceCreatePathForFile", &luaForceCreatePathForFile);
|
lua_tinker::def(L, "forceCreatePathForFile", &luaForceCreatePathForFile);
|
||||||
|
lua_tinker::def(L, "createEmptyPath", &luaCreateEmptyPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,104 +8,11 @@
|
|||||||
#include "sgu_mode_make_diff.h"
|
#include "sgu_mode_make_diff.h"
|
||||||
#include "sgu_mode_apply_patch.h"
|
#include "sgu_mode_apply_patch.h"
|
||||||
#include "sgu_mode_hash_file.h"
|
#include "sgu_mode_hash_file.h"
|
||||||
#include "sgu_mode_npk_dump_list.h"
|
|
||||||
#include "sgu_mode_npk_extract_files.h"
|
|
||||||
#include "sgu_mode_download.h"
|
#include "sgu_mode_download.h"
|
||||||
#include "sgu_mode_run_lua_file.h"
|
#include "sgu_mode_run_lua_file.h"
|
||||||
|
|
||||||
#include "libEncrypt_AES.h"
|
#include "libEncrypt_AES.h"
|
||||||
|
|
||||||
//int TestFunc(lua_State* L)
|
|
||||||
//{
|
|
||||||
// printf("# TestFunc\n");
|
|
||||||
// return lua_yield(L, 0);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int TestFunc2(lua_State* L, float a)
|
|
||||||
//{
|
|
||||||
// printf("# TestFunc2(L,%f)\n", a);
|
|
||||||
// return lua_yield(L, 0);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//class TestClass
|
|
||||||
//{
|
|
||||||
//public:
|
|
||||||
//
|
|
||||||
// int TestFunc(lua_State* L, int a)
|
|
||||||
// {
|
|
||||||
// m_data = a;
|
|
||||||
// printf("# TestClass::TestFunc\n");
|
|
||||||
// return lua_yield(L, 0);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// int TestFunc2(lua_State* L, float a)
|
|
||||||
// {
|
|
||||||
// printf("# TestClass::TestFunc2(L,%d, %f)\n", m_data, a);
|
|
||||||
// return lua_yield(L, 0);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
// int m_data;
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//int foo()
|
|
||||||
//{
|
|
||||||
// lua_State* L = lua_open();
|
|
||||||
// luaopen_base(L);
|
|
||||||
// luaopen_string(L);
|
|
||||||
//
|
|
||||||
// lua_tinker::def(L, "TestFunc", &TestFunc);
|
|
||||||
// lua_tinker::def(L, "TestFunc2", &TestFunc2);
|
|
||||||
//
|
|
||||||
// lua_tinker::class_add<TestClass>(L, "TestClass");
|
|
||||||
// lua_tinker::class_def<TestClass>(L, "TestFunc", &TestClass::TestFunc);
|
|
||||||
// lua_tinker::class_def<TestClass>(L, "TestFunc2", &TestClass::TestFunc2);
|
|
||||||
//
|
|
||||||
// TestClass g_test;
|
|
||||||
// lua_tinker::set(L, "g_test", &g_test);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// lua_tinker::dostring(L,
|
|
||||||
// "function ThreadTest()\n"
|
|
||||||
// " print(\"ThreadTest\")\n"
|
|
||||||
//
|
|
||||||
// " print(\"TestFunc Begin\")"
|
|
||||||
// " TestFunc()\n"
|
|
||||||
// " TestFunc2(1.2)\n"
|
|
||||||
// " print(\"TestFunc End\")\n"
|
|
||||||
//
|
|
||||||
// " print(\"g_test::TestFunc()\")\n"
|
|
||||||
// " g_test:TestFunc(123)\n"
|
|
||||||
// " g_test:TestFunc2(2.3)\n"
|
|
||||||
// " print(\"g_test::TestFunc()\")\n"
|
|
||||||
// "end\n"
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// lua_newthread(L);
|
|
||||||
// lua_pushstring(L, "ThreadTest");
|
|
||||||
// lua_gettable(L, LUA_GLOBALSINDEX);
|
|
||||||
//
|
|
||||||
// printf("* lua_resume() 1\n");
|
|
||||||
// lua_resume(L, 0);
|
|
||||||
//
|
|
||||||
// printf("* lua_resume() 2\n");
|
|
||||||
// lua_resume(L, 0);
|
|
||||||
//
|
|
||||||
// printf("* lua_resume() 3\n");
|
|
||||||
// lua_resume(L, 0);
|
|
||||||
//
|
|
||||||
// printf("* lua_resume() 4\n");
|
|
||||||
// lua_resume(L, 0);
|
|
||||||
//
|
|
||||||
// printf("* lua_resume() 5\n");
|
|
||||||
// lua_resume(L, 0);
|
|
||||||
//
|
|
||||||
// lua_close(L);
|
|
||||||
//
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
enum { OPT_MODE,
|
enum { OPT_MODE,
|
||||||
OPT_INPUT, OPT_INPUT2, OPT_OUTPUT,
|
OPT_INPUT, OPT_INPUT2, OPT_OUTPUT,
|
||||||
OPT_MIN_SIZE, OPT_MAX_SIZE,
|
OPT_MIN_SIZE, OPT_MAX_SIZE,
|
||||||
@@ -153,8 +60,6 @@ static void printUsage(const char* moduleName)
|
|||||||
printf(" MakeDiff\tCreates a binary diff patch file between two input files using BSDIFF43.\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(" 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(" HashFile\tCalculates the hash(MD5|SHA256) of the contents of a specified file.\n");
|
||||||
printf(" NPKDumpList\tDumps the file list from an NPK archive to a text file.\n");
|
|
||||||
printf(" NPKExtractFiles\tExtracts all files from an NPK archive to a specified output directory.\n");
|
|
||||||
printf(" HttpDownload\tDownloads a file from a specified URL and saves it to a local file.\n");
|
printf(" HttpDownload\tDownloads a file from a specified URL and saves it to a local file.\n");
|
||||||
printf(" RunLuaFile\t xxxx \n");
|
printf(" RunLuaFile\t xxxx \n");
|
||||||
printf("\nSample:\n");
|
printf("\nSample:\n");
|
||||||
@@ -166,8 +71,6 @@ static void printUsage(const char* moduleName)
|
|||||||
printf(" -m ApplyPatch -i ver01.bin -i2 patch_ver01_ver02.diff -o ver02.bin\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 md5 -i ver01.bin\n");
|
||||||
printf(" -m HashFile -t sha256 -i ver01.bin\n");
|
printf(" -m HashFile -t sha256 -i ver01.bin\n");
|
||||||
printf(" -m NPKDumpList -i abc.npk -o abc_file_list.txt\n");
|
|
||||||
printf(" -m NPKExtractFiles -i abc.npk -o output\n");
|
|
||||||
printf(" -m HttpDownload -i http://download.com/file.txt -o file.txt\n");
|
printf(" -m HttpDownload -i http://download.com/file.txt -o file.txt\n");
|
||||||
printf(" -m RunLuaFile -i script.lua\n");
|
printf(" -m RunLuaFile -i script.lua\n");
|
||||||
}
|
}
|
||||||
@@ -183,8 +86,6 @@ enum WorkMode {
|
|||||||
WM_APPLY_PATCH,
|
WM_APPLY_PATCH,
|
||||||
WM_HASH_FILE,
|
WM_HASH_FILE,
|
||||||
WM_HTTP_DOWNLOAD,
|
WM_HTTP_DOWNLOAD,
|
||||||
WM_NPK_DUMPLIST,
|
|
||||||
WM_NPK_EXTRACT_FILES,
|
|
||||||
WM_RUN_LUA_FILE,
|
WM_RUN_LUA_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -226,12 +127,6 @@ WorkMode parserWorkMode(const char* modeStr)
|
|||||||
else if (_stricmp(modeStr, "HttpDownload") == 0) {
|
else if (_stricmp(modeStr, "HttpDownload") == 0) {
|
||||||
return WM_HTTP_DOWNLOAD;
|
return WM_HTTP_DOWNLOAD;
|
||||||
}
|
}
|
||||||
else if (_stricmp(modeStr, "NPKDumpList") == 0) {
|
|
||||||
return WM_NPK_DUMPLIST;
|
|
||||||
}
|
|
||||||
else if (_stricmp(modeStr, "NPKExtractFiles") == 0) {
|
|
||||||
return WM_NPK_EXTRACT_FILES;
|
|
||||||
}
|
|
||||||
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
|
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
|
||||||
return WM_RUN_LUA_FILE;
|
return WM_RUN_LUA_FILE;
|
||||||
}
|
}
|
||||||
@@ -482,39 +377,6 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_NPK_DUMPLIST:
|
|
||||||
{
|
|
||||||
if (inputFilename == nullptr || outputFilename == nullptr)
|
|
||||||
{
|
|
||||||
printf("Error: For 'NPKDumpList' mode, you must specify input NPK file and output file.\n");
|
|
||||||
printUsage(::PathFindFileNameA(argv[0]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("Dumping NPK list from %s to %s\n", inputFilename, outputFilename);
|
|
||||||
if (!dumpNPKFileList(inputFilename, outputFilename))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to dump NPK list.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_NPK_EXTRACT_FILES:
|
|
||||||
{
|
|
||||||
if (inputFilename == nullptr || outputFilename == nullptr)
|
|
||||||
{
|
|
||||||
printf("Error: For 'NPKExtractFiles' mode, you must specify input NPK file and output directory.\n");
|
|
||||||
printUsage(::PathFindFileNameA(argv[0]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("Extracting files from NPK '%s' to directory '%s'\n", inputFilename, outputFilename);
|
|
||||||
if(!extractNPKFiles(inputFilename, outputFilename))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to extract files from NPK.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WM_RUN_LUA_FILE:
|
case WM_RUN_LUA_FILE:
|
||||||
{
|
{
|
||||||
if (inputFilename == nullptr)
|
if (inputFilename == nullptr)
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
#include "sgu_stdafx.h"
|
|
||||||
#include "sgu_mode_npk_dump_list.h"
|
|
||||||
|
|
||||||
#include "libNPK.h"
|
|
||||||
|
|
||||||
bool dumpNPKFileList(const char* inputFilename, const char* outputFilename)
|
|
||||||
{
|
|
||||||
if (!inputFilename || inputFilename[0] == 0)
|
|
||||||
{
|
|
||||||
printf("Error: Input filename is not specified.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!outputFilename || outputFilename[0] == 0)
|
|
||||||
{
|
|
||||||
printf("Error: Output filename is not specified.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NPK::INPKFile* pakFile = NPK::createNPKFile();
|
|
||||||
|
|
||||||
std::wstring strFullName = convertAnsiStringToWide(inputFilename);
|
|
||||||
if (!(pakFile->openPakFile(strFullName.c_str())))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to open NPK file: %s, ErrorCode:%d\n", inputFilename, NPK::getLastErrorCode());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* fpOutput = fopen(outputFilename, "a+");
|
|
||||||
if (!fpOutput)
|
|
||||||
{
|
|
||||||
printf("Error: Failed to open output file: %s\n", outputFilename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int32_t fileCount = pakFile->getFileCounts();
|
|
||||||
|
|
||||||
// Dump file list
|
|
||||||
for(int32_t i=0; i < fileCount; i++)
|
|
||||||
{
|
|
||||||
NPK::FileItemBaseInfo baseInfo;
|
|
||||||
if (!pakFile->getFileItemBaseInfo(i, &baseInfo))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to get file node at index %d\n", i);
|
|
||||||
fclose(fpOutput);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NPK::IFileStream* fileStream = pakFile->openFileStream(baseInfo.keyName.c_str());
|
|
||||||
if (!fileStream)
|
|
||||||
{
|
|
||||||
printf("Error: Failed to open file stream for '%s', Error=%s\n", baseInfo.keyName.c_str(), NPK::getLastErrorMessage());
|
|
||||||
fclose(fpOutput);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint32_t crc32 = fileStream->crc32();
|
|
||||||
fprintf(fpOutput, "%s\t%08x\t%u\n", baseInfo.keyName.c_str(), crc32, baseInfo.fileSize);
|
|
||||||
|
|
||||||
pakFile->closeFileStream(fileStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fpOutput);
|
|
||||||
|
|
||||||
pakFile->closePakFile();
|
|
||||||
NPK::closeNPKFile(pakFile);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dumps the file list from an NPK archive to a text file.
|
|
||||||
*
|
|
||||||
* @param inputFilename The path to the NPK archive file to be read.
|
|
||||||
* @param outputFilename The path to the output text file where the file list will be written.
|
|
||||||
* @return true if the operation succeeds; false otherwise.
|
|
||||||
*
|
|
||||||
* The function performs the following steps:
|
|
||||||
* 1. Validates the input and output file names.
|
|
||||||
* 2. Opens the NPK archive and retrieves the number of contained files.
|
|
||||||
* 3. Iterates through each file entry in the archive, extracting its name, offset, and size.
|
|
||||||
* 4. Writes the file list to the output text file in tab-separated format: fileName, fileOffset, fileSize.
|
|
||||||
* 5. Closes all files and releases resources.
|
|
||||||
* 6. Returns true on success, or false if any error occurs during processing.
|
|
||||||
*/
|
|
||||||
bool dumpNPKFileList(const char* szNPKFileName, const char* szListFileName);
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
#include "sgu_stdafx.h"
|
|
||||||
#include "sgu_mode_npk_extract_files.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (!szNPKFileName || !szOutputDir || szNPKFileName[0] == 0 || szOutputDir[0] == 0)
|
|
||||||
{
|
|
||||||
printf("Error: Invalid parameters. NPK file name and output directory must be specified.\n");
|
|
||||||
return false; // Invalid parameters
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!createEmptyPath(szOutputDir))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to create output directory '%s'.\n", szOutputDir);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NPK::INPKFile* npkFile = NPK::createNPKFile();
|
|
||||||
if (!npkFile)
|
|
||||||
{
|
|
||||||
return false; // Failed to create NPK file interface
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring strFullName = convertAnsiStringToWide(szNPKFileName);
|
|
||||||
if (!(npkFile->openPakFile(strFullName.c_str())))
|
|
||||||
{
|
|
||||||
printf("Failed to open NPK file: '%s', Error=%s\n", szNPKFileName, NPK::getLastErrorMessage());
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
return false; // Failed to open NPK file
|
|
||||||
}
|
|
||||||
int32_t fileCount = npkFile->getFileCounts();
|
|
||||||
for (int32_t i = 0; i < fileCount; ++i)
|
|
||||||
{
|
|
||||||
NPK::FileItemBaseInfo baseInfo;
|
|
||||||
if (!npkFile->getFileItemBaseInfo(i, &baseInfo))
|
|
||||||
{
|
|
||||||
std::string outputPathName = std::string(szOutputDir) + "/" + baseInfo.keyName;
|
|
||||||
|
|
||||||
char szOutputPath[MAX_PATH];
|
|
||||||
StringCbCopyA(szOutputPath, sizeof(szOutputPath), outputPathName.c_str());
|
|
||||||
getParentPath(szOutputPath);// Get the directory part of the path
|
|
||||||
|
|
||||||
if (!forceCreatePath(szOutputPath))
|
|
||||||
{
|
|
||||||
printf("Error: Failed to create output path '%s'.\n", szOutputPath);
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NPK::IFileStream* fileStream = npkFile->openFileStream(baseInfo.keyName.c_str());
|
|
||||||
if(fileStream == nullptr)
|
|
||||||
{
|
|
||||||
printf("Error: Failed to open file stream for '%s', Error=%s\n",
|
|
||||||
baseInfo.keyName.c_str(), NPK::getLastErrorMessage());
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* fpOutput = fopen(outputPathName.c_str(), "wb");
|
|
||||||
if (!fpOutput)
|
|
||||||
{
|
|
||||||
printf("Error: Failed to open output file '%s' for writing.\n", outputPathName.c_str());
|
|
||||||
npkFile->closeFileStream(fileStream);
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
return false; // Failed to open output file
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[4096] = { 0 };
|
|
||||||
uint32_t bytesRead = 0;
|
|
||||||
while ((bytesRead = fileStream->read(buffer, sizeof(buffer))) > 0)
|
|
||||||
{
|
|
||||||
if (fwrite(buffer, 1, bytesRead, fpOutput) != bytesRead)
|
|
||||||
{
|
|
||||||
printf("Error: Failed to write to output file '%s'.\n", outputPathName.c_str());
|
|
||||||
fclose(fpOutput);
|
|
||||||
npkFile->closeFileStream(fileStream);
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
return false; // Failed to write to output file
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(fpOutput);
|
|
||||||
npkFile->closeFileStream(fileStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NPK::closeNPKFile(npkFile);
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts all files from an NPK archive to a specified output directory.
|
|
||||||
*
|
|
||||||
* @param szNPKFileName The path to the NPK archive file to be extracted.
|
|
||||||
* @param szOutputDir The path to the output directory where files will be extracted.
|
|
||||||
* @return true if extraction succeeds; false otherwise.
|
|
||||||
*
|
|
||||||
* The function performs the following steps:
|
|
||||||
* 1. Validates the input parameters.
|
|
||||||
* 2. Creates or clears the output directory.
|
|
||||||
* 3. Opens the NPK archive and retrieves the file list.
|
|
||||||
* 4. For each file in the archive:
|
|
||||||
* - Ensures the output path exists.
|
|
||||||
* - Opens a stream to the file in the archive.
|
|
||||||
* - Creates the corresponding output file.
|
|
||||||
* - Copies the file data from the archive to the output file in chunks.
|
|
||||||
* 5. Closes all resources and returns true on success, or false if any error occurs.
|
|
||||||
*/
|
|
||||||
bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir);
|
|
||||||
Reference in New Issue
Block a user