增加Lua函数

This commit is contained in:
2025-09-02 22:45:41 +08:00
parent 6788128cc3
commit 25e7cff75d
14 changed files with 260 additions and 22 deletions
+3 -1
View File
@@ -29,7 +29,7 @@ enum ErrorCode
NPK_ERR_PARAM, NPK_ERR_PARAM,
NPK_ERR_INVALID_STATE, NPK_ERR_INVALID_STATE,
NPK_ERR_NEW_FAILED, NPK_ERR_NEW_FAILED,
NPK_ERR_FILE_CREATE,
//Other errors //Other errors
NPK_ERR_UNKNOWN NPK_ERR_UNKNOWN
}; };
@@ -98,6 +98,8 @@ public:
virtual uint32_t tell(void) const = 0; virtual uint32_t tell(void) const = 0;
virtual uint32_t crc32(void) = 0; virtual uint32_t crc32(void) = 0;
virtual bool isEOF(void) const = 0; virtual bool isEOF(void) const = 0;
virtual bool writeToDiskFile(const wchar_t* diskPathFile) = 0;
}; };
class IFileList class IFileList
+5 -2
View File
@@ -33,7 +33,10 @@ bool clearPath(const char* szPath, bool recursion, bool removeSelf);
bool createEmptyPath(const char* szPath); bool createEmptyPath(const char* 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 char* szPath); bool forceCreatePath(const wchar_t* szPath);
// Force create a directory path for the file
bool forceCreatePathForFile(const wchar_t* szFilePath);
// Get the parent directory path of the specified path. // Get the parent directory path of the specified path.
void getParentPath(char* szPath); void getParentPath(wchar_t* szPath);
+42
View File
@@ -84,4 +84,46 @@ uint32_t CFileStream::crc32(void)
return m_crc32; return m_crc32;
} }
bool CFileStream::writeToDiskFile(const wchar_t* diskPathFile)
{
HANDLE hFile = ::CreateFileW(diskPathFile,
FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_ARCHIVE,
0);
if (hFile == INVALID_HANDLE_VALUE)
{
setLastError(NPK_ERR_FILE_CREATE, "Failed to open output file for writing, LastError=%d.", ::GetLastError());
return false; // Failed to open output file
}
//store current read offset
uint32_t currentOffset = m_currentOffset;
m_currentOffset = 0;
//read loop
char buffer[4096] = { 0 };
uint32_t bytesRead = 0;
while ((bytesRead = this->read(buffer, sizeof(buffer))) > 0)
{
DWORD dwWriteBytes = 0;
if (!WriteFile(hFile, buffer, bytesRead, &dwWriteBytes, 0) ||
dwWriteBytes != bytesRead)
{
setLastError(NPK_ERR_FILE_WRITE, "Failed to write to output file, LastError=%d", ::GetLastError());
CloseHandle(hFile);
m_currentOffset = currentOffset;
return false; // Failed to write to output file
}
}
CloseHandle(hFile);
m_currentOffset = currentOffset;
return true;
}
} }
+4 -2
View File
@@ -31,6 +31,8 @@ public:
return m_currentOffset >= m_fileSize; return m_currentOffset >= m_fileSize;
} }
virtual bool writeToDiskFile(const wchar_t* diskPathFile);
protected: protected:
//Pack file //Pack file
CNPKFile* m_pNPKFile; CNPKFile* m_pNPKFile;
@@ -38,9 +40,9 @@ protected:
HANDLE m_hFileandle; HANDLE m_hFileandle;
std::string m_fileName; std::string m_fileName;
//offset of the file in the pak file //offset of the file in the pak file
uint32_t m_fileOffset = 0; const uint32_t m_fileOffset = 0;
//size of the file //size of the file
uint32_t m_fileSize = 0; const uint32_t m_fileSize = 0;
//current read offset in the file //current read offset in the file
uint32_t m_currentOffset = 0; uint32_t m_currentOffset = 0;
//CRC32 checksum of the file //CRC32 checksum of the file
+22 -14
View File
@@ -258,34 +258,42 @@ bool createEmptyPath(const char* szPath)
return true; return true;
} }
void getParentPath(char* szPath) void getParentPath(wchar_t* szPath)
{ {
if (!szPath || szPath[0] == 0) return; if (!szPath || szPath[0] == 0) return;
size_t length = strlen(szPath); size_t length = wcslen(szPath);
std::replace(szPath, szPath+length, '/', '\\'); std::replace(szPath, szPath+length, L'/', L'\\');
::PathRemoveFileSpecA(szPath); ::PathRemoveFileSpecW(szPath);
} }
bool forceCreatePath(const char* szPath) bool forceCreatePath(const wchar_t* szPath)
{ {
char szCurrentPath[MAX_PATH] = { 0 }; wchar_t szCurrentPath[MAX_PATH] = { 0 };
StringCchCopyA(szCurrentPath, MAX_PATH, szPath); StringCchCopyW(szCurrentPath, MAX_PATH, szPath);
size_t length = strlen(szPath); size_t length = wcslen(szPath);
std::replace(szCurrentPath, szCurrentPath + length, '/', '\\'); std::replace(szCurrentPath, szCurrentPath + length, L'/', L'\\');
//目录已经存在 //目录已经存在
if (::PathFileExists(szCurrentPath)) return true; if (::PathFileExistsW(szCurrentPath)) return true;
//能够直接创建 //能够直接创建
if (::CreateDirectory(szCurrentPath, 0)) return true; if (::CreateDirectoryW(szCurrentPath, 0)) return true;
//取得上一级目录 //取得上一级目录
char szParentPath[MAX_PATH] = { 0 }; wchar_t szParentPath[MAX_PATH] = { 0 };
StringCchCopyA(szParentPath, MAX_PATH, szPath); StringCchCopyW(szParentPath, MAX_PATH, szPath);
getParentPath(szParentPath); getParentPath(szParentPath);
//创建上一级目录 //创建上一级目录
if (!forceCreatePath(szParentPath)) return false; if (!forceCreatePath(szParentPath)) return false;
return TRUE == ::CreateDirectory(szCurrentPath, 0); return TRUE == ::CreateDirectoryW(szCurrentPath, 0);
}
bool forceCreatePathForFile(const wchar_t* szFilePath)
{
wchar_t szPathForFile[MAX_PATH] = { 0 };
StringCchCopyW(szPathForFile, MAX_PATH, szFilePath);
getParentPath(szPathForFile);
return forceCreatePath(szPathForFile);
} }
+2
View File
@@ -32,6 +32,8 @@ add_executable(sgutil
sgu_utils.h sgu_utils.h
sgu_lua_npk_file.h sgu_lua_npk_file.h
sgu_lua_npk_file.cpp sgu_lua_npk_file.cpp
sgu_lua_utils.h
sgu_lua_utils.cpp
) )
target_include_directories(sgutil target_include_directories(sgutil
+78
View File
@@ -0,0 +1,78 @@
--print npk file list to file
--[[
npkFileName(string): npk file path name(utf8)
listFileName(string): list output path name(utf8)
keyName(boolean): print key name
npkName(boolean): print npk file name
npkBase(boolean): print npk base dir name
fileSize(boolean): print file size
fileCRC(boolean): print file crc
fileOffset(boolean): print file offset
return(boolean): is success
--]]
local M={}
function M.dump_npk_file_list(npkFileName, listFileName, npkBase, npkName, keyName, fileOffset, fileSize, fileCRC)
local npk = createNPKFile();
local ret = npk:openPakFile(npkFileName)
if(not ret) then
return false
end
listOutputFile = io.open(listFileName, "w")
fileList = npk:generateFullInfoList();
counts = fileList:getFileCounts()
for i=0, counts-1, 1 do
local fileInfo = fileList:getFileItem(i)
outputLine=""
if(npkBase) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. fileInfo:npkBase();
end
if(npkName) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. fileInfo:npkName();
end
if(keyName) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. fileInfo:keyName();
end
if(fileOffset) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. tostring(fileInfo.fileOffset);
end
if(fileSize) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. tostring(fileInfo.fileSize);
end
if(fileCRC) then
if(#outputLine>0) then outputLine = outputLine .. "|" end
outputLine = outputLine .. tostring(fileInfo.fileCRC);
end
if(#outputLine>0) then
listOutputFile:write(outputLine .. "\n")
end
end
listOutputFile:close()
destroyFileList(fileList)
npk:closePakFile()
destroyNPKFile(npk)
return true
end
return M;
+48
View File
@@ -0,0 +1,48 @@
--Extracts all files from an NPK archive to a specified output directory.
--[[
npkFileName The path to the NPK archive file to be extracted.
outputPath The path to the output directory where files will be extracted.
return true if extraction succeeds; false otherwise.
--]]
local M={}
function M.extract_npk_files(npkFileName, outputPath)
local npk = createNPKFile();
local ret = npk:openPakFile(npkFileName)
if(not ret) then
return false
end
local counts = npk:getFileCounts()
for i=0, counts-1, 1 do
local baseInfo = npk:getFileNode(i)
local fileStream = npk:openFileStream(baseInfo:keyName())
print("keyName=" .. fileStream:name() .. "\n")
local diskFileName = outputPath .. "/" .. baseInfo:keyName()
ret = forceCreatePathForFile(diskFileName);
if(not ret) then
print("CreatePathForFile failed: " .. diskFileName)
npk:closeFileStream(fileStream)
break
end
ret = fileStream:writeToDiskFile(diskFileName)
if(not ret) then
print("dump file failed: " .. baseInfo:keyName())
print("LastErrorMsg=" .. getLastErrorMessage())
npk:closeFileStream(fileStream)
break
end
npk:closeFileStream(fileStream)
end
npk:closePakFile()
destroyNPKFile(npk)
return true
end
return M;
+9 -1
View File
@@ -11,12 +11,13 @@ extern "C"
#include "lua_tinker.h" #include "lua_tinker.h"
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
void LuaNPKFile::registerLuaApi(lua_State* L) void registerNPKLuaLibs(lua_State* L)
{ {
lua_tinker::def(L, "createNPKFile", &LuaNPKFile::create); lua_tinker::def(L, "createNPKFile", &LuaNPKFile::create);
lua_tinker::def(L, "destroyNPKFile", &LuaNPKFile::destroy); lua_tinker::def(L, "destroyNPKFile", &LuaNPKFile::destroy);
lua_tinker::def(L, "createEmptyFileList", &LuaNPKFileList::createEmpty); lua_tinker::def(L, "createEmptyFileList", &LuaNPKFileList::createEmpty);
lua_tinker::def(L, "destroyFileList", &LuaNPKFileList::destroy); lua_tinker::def(L, "destroyFileList", &LuaNPKFileList::destroy);
lua_tinker::def(L, "getLastErrorMessage", &NPK::getLastErrorMessage);
lua_tinker::class_add<LuaNPKFile>(L, "NPKFile"); lua_tinker::class_add<LuaNPKFile>(L, "NPKFile");
lua_tinker::class_def<LuaNPKFile>(L, "openPakFile", &LuaNPKFile::openPakFile); lua_tinker::class_def<LuaNPKFile>(L, "openPakFile", &LuaNPKFile::openPakFile);
@@ -52,6 +53,7 @@ void LuaNPKFile::registerLuaApi(lua_State* L)
lua_tinker::class_def<LuaNPKFileStream>(L, "tell", &LuaNPKFileStream::tell); lua_tinker::class_def<LuaNPKFileStream>(L, "tell", &LuaNPKFileStream::tell);
lua_tinker::class_def<LuaNPKFileStream>(L, "crc32", &LuaNPKFileStream::crc32); lua_tinker::class_def<LuaNPKFileStream>(L, "crc32", &LuaNPKFileStream::crc32);
lua_tinker::class_def<LuaNPKFileStream>(L, "isEOF", &LuaNPKFileStream::isEOF); lua_tinker::class_def<LuaNPKFileStream>(L, "isEOF", &LuaNPKFileStream::isEOF);
lua_tinker::class_def<LuaNPKFileStream>(L, "writeToDiskFile", &LuaNPKFileStream::writeToDiskFile);
} }
LuaNPKFile* LuaNPKFile::create() LuaNPKFile* LuaNPKFile::create()
@@ -167,6 +169,12 @@ bool LuaNPKFileStream::isEOF(void) const
return m_pFileStream ? m_pFileStream->isEOF() : true; return m_pFileStream ? m_pFileStream->isEOF() : true;
} }
bool LuaNPKFileStream::writeToDiskFile(const char* wszFileName)
{
std::wstring wstrLocalDiskFile = convertUtf8StringToWide(wszFileName);
return m_pFileStream ? m_pFileStream->writeToDiskFile(wstrLocalDiskFile.c_str()) : false;
}
/// ///////////////////////////////////////////////////////////////////////////////// /// /////////////////////////////////////////////////////////////////////////////////
LuaNPKFileList* LuaNPKFileList::createEmpty() LuaNPKFileList* LuaNPKFileList::createEmpty()
{ {
+5 -1
View File
@@ -27,6 +27,9 @@ public:
uint32_t crc32(void); uint32_t crc32(void);
bool isEOF(void) const; bool isEOF(void) const;
//write total file content to local disk file, wszFileName(utf8)
bool writeToDiskFile(const char* wszFileName);
public:
NPK::IFileStream* m_pFileStream = nullptr; NPK::IFileStream* m_pFileStream = nullptr;
}; };
@@ -46,7 +49,6 @@ public:
class LuaNPKFile class LuaNPKFile
{ {
public: public:
static void registerLuaApi(struct lua_State* L);
static LuaNPKFile* create(); static LuaNPKFile* create();
static void destroy(LuaNPKFile* instance); static void destroy(LuaNPKFile* instance);
@@ -68,3 +70,5 @@ public:
LuaNPKFile(); LuaNPKFile();
~LuaNPKFile(); ~LuaNPKFile();
}; };
void registerNPKLuaLibs(struct lua_State* L);
+34
View File
@@ -0,0 +1,34 @@
#include "sgu_lua_utils.h"
#include "libNPK_Utils.h"
#include <strsafe.h>
#include <Shlwapi.h>
#include <algorithm>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#include "lua_tinker.h"
//utf8
bool luaForceCreatePathForFile(const char* szPath)
{
std::wstring strPath = convertUtf8StringToWide(szPath);
return forceCreatePathForFile(strPath.c_str());
}
//utf8
bool luaForceCreatePath(const char* szPath)
{
std::wstring strPath = convertUtf8StringToWide(szPath);
return forceCreatePath(strPath.c_str());
}
void registerUtilsLuaLibs(struct lua_State* L)
{
lua_tinker::def(L, "forceCreatePath", &luaForceCreatePath);
lua_tinker::def(L, "forceCreatePathForFile", &luaForceCreatePathForFile);
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void registerUtilsLuaLibs(struct lua_State* L);
+2
View File
@@ -4,6 +4,7 @@
bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir) bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir)
{ {
#if 0
if (!szNPKFileName || !szOutputDir || szNPKFileName[0] == 0 || szOutputDir[0] == 0) if (!szNPKFileName || !szOutputDir || szNPKFileName[0] == 0 || szOutputDir[0] == 0)
{ {
printf("Error: Invalid parameters. NPK file name and output directory must be specified.\n"); printf("Error: Invalid parameters. NPK file name and output directory must be specified.\n");
@@ -84,5 +85,6 @@ bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir)
} }
} }
NPK::closeNPKFile(npkFile); NPK::closeNPKFile(npkFile);
#endif
return true; return true;
} }
+3 -1
View File
@@ -1,5 +1,6 @@
#include "sgu_mode_run_lua_file.h" #include "sgu_mode_run_lua_file.h"
#include "sgu_lua_npk_file.h" #include "sgu_lua_npk_file.h"
#include "sgu_lua_utils.h"
#include "libNPK.h" #include "libNPK.h"
@@ -22,7 +23,8 @@ bool run_lua_file(const char* szLuaFilename)
lua_tinker::def(L, "getLastErrorMessage", &NPK::getLastErrorMessage); lua_tinker::def(L, "getLastErrorMessage", &NPK::getLastErrorMessage);
//register classes //register classes
LuaNPKFile::registerLuaApi(L); registerNPKLuaLibs(L);
registerUtilsLuaLibs(L);
//run lua file //run lua file
lua_tinker::dofile(L, szLuaFilename); lua_tinker::dofile(L, szLuaFilename);