增加Lua导出和FileList

This commit is contained in:
2025-09-02 20:39:30 +08:00
parent 1fb319f0e8
commit 6788128cc3
18 changed files with 682 additions and 56 deletions
+2
View File
@@ -11,6 +11,8 @@ set(LIBNPK_SOURCE_FILES
./source/libNPK_Utils.cpp
./source/libNPK_FileStream.h
./source/libNPK_FileStream.cpp
./source/libNPK_FileList.h
./source/libNPK_FileList.cpp
)
add_library(libNPK STATIC
+41 -15
View File
@@ -1,5 +1,8 @@
#pragma once
#include <stdint.h>
#include <string>
namespace NPK
{
@@ -8,6 +11,7 @@ namespace NPK
//------------------------------------
class INPKFile;
class IFileStream;
class IFileList;
//------------------------------------
// NPK file error codes
@@ -24,6 +28,7 @@ enum ErrorCode
NPK_ERR_FILE_WRITE,
NPK_ERR_PARAM,
NPK_ERR_INVALID_STATE,
NPK_ERR_NEW_FAILED,
//Other errors
NPK_ERR_UNKNOWN
@@ -39,6 +44,12 @@ INPKFile* createNPKFile();
// destroy an NPK interface
void closeNPKFile(INPKFile* npkFile);
// Create empty file list
IFileList* createEmptyFileList();
// destroy a file list
void destoryFileList(IFileList* fileList);
// Get the last error code
ErrorCode getLastErrorCode();
@@ -48,27 +59,33 @@ const char* getLastErrorMessage();
//------------------------------------
// define the NPK file interface
//------------------------------------
struct FileItemBaseInfo
{
std::string keyName; // utf8 'common/etc/tribe.img'
uint32_t fileOffset = 0;
uint32_t fileSize = 0;
};
struct FileItemFullInfo
{
std::string npkName; // utf8 'sprite_interface2_hud.npk'
std::string npkBase; // utf8 'd:/dnf/ImagePacks2'
std::string keyName; // 'common/etc/tribe.img'
uint32_t fileOffset = 0;
uint32_t fileSize = 0;
uint32_t fileCRC = 0;
};
class INPKFile
{
public:
struct FileNode
{
std::string fileName;
uint32_t fileOffset = 0;
uint32_t fileSize = 0;
};
public:
virtual bool openPakFile(const char* szPackFileName) = 0;
virtual bool openPakFile(const wchar_t* wszNpkPathName) = 0;
virtual bool closePakFile(void) = 0;
virtual int32_t getFileCount(void) const = 0;
virtual bool getFileNode(int32_t index, FileNode& fileNode) const = 0;
virtual int32_t getFileCounts(void) const = 0;
virtual bool getFileItemBaseInfo(int32_t index, FileItemBaseInfo* baseInfo) const = 0;
virtual IFileStream* openFileStream(const char* szFileName) = 0;
virtual void closeFileStream(IFileStream* fileStream) = 0;
virtual IFileList* generateFullInfoList(void) = 0;
};
class IFileStream
@@ -83,4 +100,13 @@ public:
virtual bool isEOF(void) const = 0;
};
class IFileList
{
public:
virtual int32_t getFileCounts(void) const = 0;
virtual bool getFileItem(int32_t index, FileItemFullInfo* fileItemFullInfo) const = 0;
virtual void addFileNode(const FileItemFullInfo& fileItemFullInfo) = 0;
virtual void mergeOtherListInto(const IFileList* sourceFileList) = 0;
};
}
+6
View File
@@ -14,6 +14,12 @@ int compareTwoFileName(const char* szFileName1, const char* szFileName2);
// Convert a standard ANSI string to a wide string (UTF-16)
std::wstring convertAnsiStringToWide(const char* szSource);
// Convert a wide string(UTF-16) to utf8 string
std::string convertWideStringToUtf8(const wchar_t* source);
// Convert a utf8 string to wide string(UTF-16)
std::wstring convertUtf8StringToWide(const char* szSource);
// Read a file into a buffer and return the buffer pointer.
uint8_t* readFileToBuffer(const char* filename, int64_t& outSize);
+43
View File
@@ -0,0 +1,43 @@
#include "libNPK_FileList.h"
namespace NPK
{
int32_t NPKFileList::getFileCounts(void) const
{
return (int32_t)m_fileList.size();
}
bool NPKFileList::getFileItem(int32_t index, FileItemFullInfo* fullInfo) const
{
if(index< 0 || index >= getFileCounts())
{
return false;
}
*fullInfo = m_fileList[index];
return true;
}
void NPKFileList::addFileNode(const FileItemFullInfo& fullInfo)
{
//TODO: check duplicate file name?
m_fileList.push_back(fullInfo);
}
void NPKFileList::mergeOtherListInto(const IFileList* source)
{
}
IFileList* createEmptyFileList()
{
return new NPKFileList();
}
// destroy a file list
void destoryFileList(IFileList* fileList)
{
delete ((NPKFileList*)fileList);
}
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "libNPK.h"
#include <vector>
namespace NPK
{
class NPKFileList : public IFileList
{
public:
virtual int32_t getFileCounts(void) const override;
virtual bool getFileItem(int32_t index, FileItemFullInfo* fullInfo) const override;
virtual void addFileNode(const FileItemFullInfo& fullInfo) override;
virtual void mergeOtherListInto(const IFileList* sourceFileList) override;
private:
std::vector<FileItemFullInfo> m_fileList;
};
}
+4 -4
View File
@@ -7,12 +7,12 @@
namespace NPK
{
CFileStream::CFileStream(CNPKFile* pNPKFile, HANDLE hFile, const INPKFile::FileNode& fileNode)
CFileStream::CFileStream(CNPKFile* pNPKFile, HANDLE hFile, const FileItemBaseInfo& baseFileInfo)
: m_pNPKFile(pNPKFile)
, m_hFileandle(hFile)
, m_fileName(fileNode.fileName)
, m_fileOffset(fileNode.fileOffset)
, m_fileSize(fileNode.fileSize)
, m_fileName(baseFileInfo.keyName)
, m_fileOffset(baseFileInfo.fileOffset)
, m_fileSize(baseFileInfo.fileSize)
, m_currentOffset(0)
{
+1 -1
View File
@@ -49,7 +49,7 @@ protected:
bool m_crc32Calculated = false;
private:
CFileStream(CNPKFile* pNPKFile, HANDLE hFile, const INPKFile::FileNode& fileNode);
CFileStream(CNPKFile* pNPKFile, HANDLE hFile, const FileItemBaseInfo& baseFileInfo);
virtual ~CFileStream();
friend IFileStream* CNPKFile::openFileStream(const char* szFileName);
+72 -16
View File
@@ -3,6 +3,7 @@
#include "libNPK_Errors.h"
#include "libEncrypt_SHA256.h"
#include "libNPK_FileStream.h"
#include "libNPK_Utils.h"
#include <assert.h>
@@ -20,13 +21,20 @@ CNPKFile::CNPKFile()
CNPKFile::~CNPKFile()
{
if (m_hPakFile != NULL)
{
::CloseHandle(m_hPakFile);
m_hPakFile = NULL;
}
m_nFileCounts = 0;
m_fileList.clear();
m_hashFileList.clear();
}
bool CNPKFile::openPakFile(const char* szPackFileName)
bool CNPKFile::openPakFile(const wchar_t* wszNpkPathName)
{
assert(szPackFileName);
if (!szPackFileName || szPackFileName[0] == 0)
assert(wszNpkPathName);
if (!wszNpkPathName || wszNpkPathName[0] == 0)
{
setLastError(NPK_ERR_PARAM);
return false;
@@ -35,10 +43,15 @@ bool CNPKFile::openPakFile(const char* szPackFileName)
//close current pak file if it is open
closePakFile();
m_strPackFileName = szPackFileName;
wchar_t wszNpkBaseName[1024] = { 0 };
StringCchCopyW(wszNpkBaseName, 1024, wszNpkPathName);
PathRemoveFileSpecW(wszNpkBaseName);
m_strPackBaseName = convertWideStringToUtf8(wszNpkBaseName);
m_strPackFileName = convertWideStringToUtf8(::PathFindFileNameW(wszNpkPathName));
//open the pak file
m_hPakFile = ::CreateFile(szPackFileName,
m_hPakFile = ::CreateFileW(wszNpkPathName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
@@ -48,7 +61,8 @@ bool CNPKFile::openPakFile(const char* szPackFileName)
if (m_hPakFile == INVALID_HANDLE_VALUE)
{
setLastError(NPK_ERR_FILE_ACCESS, "File=%s, WinErr=%d", szPackFileName, ::GetLastError());
setLastError(NPK_ERR_FILE_ACCESS, "File=%s, WinErr=%d",
convertWideStringToUtf8(wszNpkPathName).c_str(), ::GetLastError());
return false;
}
@@ -67,7 +81,8 @@ bool CNPKFile::openPakFile(const char* szPackFileName)
//Check NPK Magic Header
if(memcmp(fileHeader.szFileHeadMagic, kNPKFileHeaderMagic, kNPKFileHeaderMagicSize) != 0)
{
setLastError(NPK_ERR_INVALID_FILE_FORMAT, "File=%s, Magic=%s", szPackFileName, fileHeader.szFileHeadMagic);
setLastError(NPK_ERR_INVALID_FILE_FORMAT, "File=%s, Magic=%s",
convertWideStringToUtf8(wszNpkPathName).c_str(), fileHeader.szFileHeadMagic);
return false;
}
@@ -94,7 +109,7 @@ bool CNPKFile::openPakFile(const char* szPackFileName)
fileInfo.szFileName[j] ^= kNPKFileNameXorCode[j];
}
m_fileList[i].fileName = fileInfo.szFileName;
m_fileList[i].keyName = fileInfo.szFileName;
m_fileList[i].fileOffset = fileInfo.fileOffset;
m_fileList[i].fileSize = fileInfo.fileSize;
}
@@ -177,8 +192,8 @@ void CNPKFile::buildHashFileList()
m_hashFileList.clear();
for (int32_t i = 0; i < m_nFileCounts; i++)
{
const FileNode& fileNode = m_fileList[i];
m_hashFileList[fileNode.fileName] = i;
const FileItemBaseInfo& baseInfo = m_fileList[i];
m_hashFileList[baseInfo.keyName] = i;
}
}
@@ -194,13 +209,13 @@ bool CNPKFile::closePakFile(void)
return true;
}
bool CNPKFile::getFileNode(int32_t index, INPKFile::FileNode& fileNode) const
bool CNPKFile::getFileItemBaseInfo(int32_t index, FileItemBaseInfo* baseInfo) const
{
if (index < 0 || index >= getFileCount())
if (index < 0 || index >= getFileCounts())
{
return false;
}
fileNode = m_fileList[index];
*baseInfo = m_fileList[index];
return true;
}
@@ -231,13 +246,13 @@ IFileStream* CNPKFile::openFileStream(const char* szFileName)
fileIndex = it->second;
}
if (fileIndex < 0 || fileIndex >= getFileCount())
if (fileIndex < 0 || fileIndex >= getFileCounts())
{
setLastError(NPK_ERR_FILE_NOT_FOUND, "File=%s, FileIndex=%d, not found in NPK file", szFileName, fileIndex);
return nullptr;
}
FileNode& fileNode = m_fileList[fileIndex];
FileItemBaseInfo& fileNode = m_fileList[fileIndex];
CFileStream* pFileStream = new CFileStream(this, m_hPakFile, fileNode);
return pFileStream;
@@ -251,6 +266,47 @@ void CNPKFile::closeFileStream(IFileStream* fileStream)
}
}
IFileList* CNPKFile::generateFullInfoList(void)
{
if (m_hPakFile == NULL)
{
setLastError(NPK_ERR_INVALID_STATE, "NPK file is not opened");
return nullptr;
}
IFileList* pFileList = createEmptyFileList();
if (!pFileList)
{
setLastError(NPK_ERR_NEW_FAILED, "Failed to create empty file list");
return nullptr;
}
for (int32_t i = 0; i < m_nFileCounts; i++)
{
const FileItemBaseInfo& baseInfo = m_fileList[i];
FileItemFullInfo fullInfo;
fullInfo.keyName = baseInfo.keyName;
fullInfo.npkName = m_strPackFileName;
fullInfo.npkBase = m_strPackBaseName;
fullInfo.fileSize = baseInfo.fileSize;
fullInfo.fileOffset = baseInfo.fileOffset;
IFileStream* pFileStream = openFileStream(baseInfo.keyName.c_str());
if (pFileStream)
{
fullInfo.fileCRC = pFileStream->crc32();
closeFileStream(pFileStream);
pFileStream = nullptr;
}
else
{
fullInfo.fileCRC = 0;
}
pFileList->addFileNode(fullInfo); // Add file item to the list
}
return pFileList;
}
INPKFile* createNPKFile()
{
return new CNPKFile();
+8 -5
View File
@@ -28,30 +28,33 @@ public:
} FileInfo;
public:
virtual bool openPakFile(const char* szPackFileName) override;
virtual bool openPakFile(const wchar_t* wszNpkPathName) override;
virtual bool closePakFile(void) override;
virtual int32_t getFileCount(void) const override {
virtual int32_t getFileCounts(void) const override {
return m_nFileCounts;
}
virtual bool getFileNode(int32_t index, FileNode& fileNode) const override;
virtual bool getFileItemBaseInfo(int32_t index, FileItemBaseInfo* baseInfo) const override;
virtual IFileStream* openFileStream(const char* szFileName) override;
virtual void closeFileStream(IFileStream* fileStream) override;
virtual IFileList* generateFullInfoList(void);
private:
bool checkPakFileHash(void);
void buildHashFileList(void);
private:
std::string m_strPackFileName;
std::string m_strPackBaseName; //utf8
std::string m_strPackFileName; //utf8
HANDLE m_hPakFile = NULL;
int32_t m_nFileCounts = 0;
typedef std::vector<FileNode> FileList;
typedef std::vector<FileItemBaseInfo> FileList;
FileList m_fileList;
typedef std::unordered_map<std::string, int32_t> FileHashList;
+46
View File
@@ -109,6 +109,52 @@ std::wstring convertAnsiStringToWide(const char* szSource)
return strReturn;
}
std::string convertWideStringToUtf8(const wchar_t* source)
{
const static int DEFAULT_CHAR_BUF_SIZE = 1024;
char DEFAULT_CHAR_BUF[DEFAULT_CHAR_BUF_SIZE] = { 0 };
if(source==nullptr || source[0]==L'\0')
return std::string();
int targetLen = WideCharToMultiByte(CP_UTF8, 0, source, -1, nullptr, 0, nullptr, nullptr);
if (targetLen == 0)
return std::string();
char* szTemp = 0;
if (targetLen >= DEFAULT_CHAR_BUF_SIZE)
szTemp = new char[targetLen];
else
szTemp = DEFAULT_CHAR_BUF;
WideCharToMultiByte(CP_UTF8, 0, source, -1, szTemp, targetLen, nullptr, nullptr);
return std::string(szTemp);
}
std::wstring convertUtf8StringToWide(const char* source)
{
const static int DEFAULT_WCHAR_BUF_SIZE = 1024;
wchar_t DEFAULT_WCHAR_BUF[DEFAULT_WCHAR_BUF_SIZE] = { 0 };
if (source == nullptr || source[0] == '\0')
return std::wstring();
int targetLen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, source, -1, nullptr, 0);
if (targetLen == 0)
return std::wstring();
wchar_t* wszTemp = 0;
if (targetLen >= DEFAULT_WCHAR_BUF_SIZE)
wszTemp = new wchar_t[targetLen];
else
wszTemp = DEFAULT_WCHAR_BUF;
int result = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, source, -1, wszTemp, targetLen);
return std::wstring(wszTemp);
}
uint8_t* readFileToBuffer(const char* filename, int64_t& outSize)
{
FILE* file = nullptr;
+4
View File
@@ -26,8 +26,12 @@ add_executable(sgutil
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.cpp
sgu_utils.cpp
sgu_utils.h
sgu_lua_npk_file.h
sgu_lua_npk_file.cpp
)
target_include_directories(sgutil
+197
View File
@@ -0,0 +1,197 @@
#include "sgu_lua_npk_file.h"
#include "libNPK_Utils.h"
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#include "lua_tinker.h"
////////////////////////////////////////////////////////////////////////////////////
void LuaNPKFile::registerLuaApi(lua_State* L)
{
lua_tinker::def(L, "createNPKFile", &LuaNPKFile::create);
lua_tinker::def(L, "destroyNPKFile", &LuaNPKFile::destroy);
lua_tinker::def(L, "createEmptyFileList", &LuaNPKFileList::createEmpty);
lua_tinker::def(L, "destroyFileList", &LuaNPKFileList::destroy);
lua_tinker::class_add<LuaNPKFile>(L, "NPKFile");
lua_tinker::class_def<LuaNPKFile>(L, "openPakFile", &LuaNPKFile::openPakFile);
lua_tinker::class_def<LuaNPKFile>(L, "closePakFile", &LuaNPKFile::closePakFile);
lua_tinker::class_def<LuaNPKFile>(L, "getFileCounts", &LuaNPKFile::getFileCounts);
lua_tinker::class_def<LuaNPKFile>(L, "getFileNode", &LuaNPKFile::getFileNode);
lua_tinker::class_def<LuaNPKFile>(L, "openFileStream", &LuaNPKFile::openFileStream);
lua_tinker::class_def<LuaNPKFile>(L, "closeFileStream", &LuaNPKFile::closeFileStream);
lua_tinker::class_def<LuaNPKFile>(L, "generateFullInfoList", &LuaNPKFile::generateFullInfoList);
lua_tinker::class_add<LuaNPKFileItemBaseInfo>(L, "NPKFileItemBaseInfo");
lua_tinker::class_def<LuaNPKFileItemBaseInfo>(L, "keyName", &LuaNPKFileItemBaseInfo::c_keyName);
lua_tinker::class_mem<LuaNPKFileItemBaseInfo>(L, "fileOffset", &LuaNPKFileItemBaseInfo::fileOffset);
lua_tinker::class_mem<LuaNPKFileItemBaseInfo>(L, "fileSize", &LuaNPKFileItemBaseInfo::fileSize);
lua_tinker::class_add<LuaNPKFileItemFullInfo>(L, "LuaNPKFileItemFullInfo");
lua_tinker::class_def<LuaNPKFileItemFullInfo>(L, "npkName", &LuaNPKFileItemFullInfo::c_npkName);
lua_tinker::class_def<LuaNPKFileItemFullInfo>(L, "npkBase", &LuaNPKFileItemFullInfo::c_npkBase);
lua_tinker::class_def<LuaNPKFileItemFullInfo>(L, "keyName", &LuaNPKFileItemFullInfo::c_keyName);
lua_tinker::class_mem<LuaNPKFileItemFullInfo>(L, "fileOffset", &LuaNPKFileItemFullInfo::fileOffset);
lua_tinker::class_mem<LuaNPKFileItemFullInfo>(L, "fileSize", &LuaNPKFileItemFullInfo::fileSize);
lua_tinker::class_mem<LuaNPKFileItemFullInfo>(L, "fileCRC", &LuaNPKFileItemFullInfo::fileCRC);
lua_tinker::class_add<LuaNPKFileList>(L, "LuaNPKFileList");
lua_tinker::class_def<LuaNPKFileList>(L, "getFileCounts", &LuaNPKFileList::getFileCounts);
lua_tinker::class_def<LuaNPKFileList>(L, "getFileItem", &LuaNPKFileList::getFileItem);
lua_tinker::class_add<LuaNPKFileStream>(L, "NPKFileStream");
lua_tinker::class_def<LuaNPKFileStream>(L, "name", &LuaNPKFileStream::name);
lua_tinker::class_def<LuaNPKFileStream>(L, "size", &LuaNPKFileStream::size);
lua_tinker::class_def<LuaNPKFileStream>(L, "read", &LuaNPKFileStream::read);
lua_tinker::class_def<LuaNPKFileStream>(L, "seek", &LuaNPKFileStream::seek);
lua_tinker::class_def<LuaNPKFileStream>(L, "tell", &LuaNPKFileStream::tell);
lua_tinker::class_def<LuaNPKFileStream>(L, "crc32", &LuaNPKFileStream::crc32);
lua_tinker::class_def<LuaNPKFileStream>(L, "isEOF", &LuaNPKFileStream::isEOF);
}
LuaNPKFile* LuaNPKFile::create()
{
return new LuaNPKFile();
}
void LuaNPKFile::destroy(LuaNPKFile* instance)
{
delete instance;
}
LuaNPKFile::LuaNPKFile()
{
m_pNPKFile = NPK::createNPKFile();
}
LuaNPKFile::~LuaNPKFile()
{
closeNPKFile(m_pNPKFile);
m_pNPKFile = nullptr;
}
bool LuaNPKFile::openPakFile(const char* szPackFileName)
{
std::wstring strFullName = convertUtf8StringToWide(szPackFileName);
return m_pNPKFile && m_pNPKFile->openPakFile(strFullName.c_str());
}
bool LuaNPKFile::closePakFile(void)
{
return m_pNPKFile && m_pNPKFile->closePakFile();
}
int32_t LuaNPKFile::getFileCounts(void) const
{
return m_pNPKFile ? m_pNPKFile->getFileCounts() : 0;
}
LuaNPKFileItemBaseInfo LuaNPKFile::getFileNode(int32_t index) const
{
LuaNPKFileItemBaseInfo baseInfo;
m_pNPKFile->getFileItemBaseInfo(index, &baseInfo);
return baseInfo;
}
LuaNPKFileList* LuaNPKFile::generateFullInfoList()
{
LuaNPKFileList* fileList = new LuaNPKFileList();
fileList->m_pFileList = m_pNPKFile->generateFullInfoList();
return fileList;
}
LuaNPKFileStream* LuaNPKFile::openFileStream(const char* szFileName)
{
if(m_pNPKFile)
{
LuaNPKFileStream* fileStream = new LuaNPKFileStream();
fileStream->m_pFileStream = m_pNPKFile->openFileStream(szFileName);
if (fileStream->m_pFileStream)
{
return fileStream;
}
delete fileStream;
}
return nullptr;
}
void LuaNPKFile::closeFileStream(LuaNPKFileStream* fileStream)
{
if (m_pNPKFile && fileStream)
{
m_pNPKFile->closeFileStream(fileStream->m_pFileStream);
fileStream->m_pFileStream = nullptr;
}
delete fileStream;
}
////////////////////////////////////////////////////////////////////////////////////
const char* LuaNPKFileStream::name(void) const
{
return m_pFileStream ? m_pFileStream->name() : nullptr;
}
uint32_t LuaNPKFileStream::size(void) const
{
return m_pFileStream ? m_pFileStream->size() : 0;
}
uint32_t LuaNPKFileStream::read(void* buffer, uint32_t size)
{
return m_pFileStream ? m_pFileStream->read(buffer, size) : 0;
}
bool LuaNPKFileStream::seek(uint32_t offset)
{
return m_pFileStream ? m_pFileStream->seek(offset) : false;
}
uint32_t LuaNPKFileStream::tell(void) const
{
return m_pFileStream ? m_pFileStream->tell() : 0;
}
uint32_t LuaNPKFileStream::crc32(void)
{
return m_pFileStream ? m_pFileStream->crc32() : 0;
}
bool LuaNPKFileStream::isEOF(void) const
{
return m_pFileStream ? m_pFileStream->isEOF() : true;
}
/// /////////////////////////////////////////////////////////////////////////////////
LuaNPKFileList* LuaNPKFileList::createEmpty()
{
LuaNPKFileList* pNewLuaFileList = new LuaNPKFileList();
pNewLuaFileList->m_pFileList = NPK::createEmptyFileList();
return pNewLuaFileList;
}
void LuaNPKFileList::destroy(LuaNPKFileList* instance)
{
NPK::destoryFileList(instance->m_pFileList);
delete instance;
}
int32_t LuaNPKFileList::getFileCounts(void) const
{
return m_pFileList ? m_pFileList->getFileCounts() : 0;
}
LuaNPKFileItemFullInfo LuaNPKFileList::getFileItem(int32_t index) const
{
LuaNPKFileItemFullInfo fullInfo;
if (m_pFileList)
{
m_pFileList->getFileItem(index, &fullInfo);
}
return fullInfo;
}
+70
View File
@@ -0,0 +1,70 @@
#pragma once
#include <stdint.h>
#include "libNPK.h"
struct LuaNPKFileItemBaseInfo : public NPK::FileItemBaseInfo
{
const char* c_keyName() const { return keyName.c_str(); }
};
struct LuaNPKFileItemFullInfo : public NPK::FileItemFullInfo
{
const char* c_npkName() const { return npkName.c_str(); }
const char* c_npkBase() const { return npkBase.c_str(); }
const char* c_keyName() const { return keyName.c_str(); }
};
class LuaNPKFileStream
{
public:
const char* name(void) const;
uint32_t size(void) const;
uint32_t read(void* buffer, uint32_t size);
bool seek(uint32_t offset);
uint32_t tell(void) const;
uint32_t crc32(void);
bool isEOF(void) const;
NPK::IFileStream* m_pFileStream = nullptr;
};
class LuaNPKFileList
{
public:
static LuaNPKFileList* createEmpty();
static void destroy(LuaNPKFileList* instance);
public:
int32_t getFileCounts(void) const;
LuaNPKFileItemFullInfo getFileItem(int32_t index) const;
public:
NPK::IFileList* m_pFileList = nullptr;
};
class LuaNPKFile
{
public:
static void registerLuaApi(struct lua_State* L);
static LuaNPKFile* create();
static void destroy(LuaNPKFile* instance);
public:
bool openPakFile(const char* szPackFileName);
bool closePakFile(void);
int32_t getFileCounts(void) const;
LuaNPKFileList* generateFullInfoList();
LuaNPKFileItemBaseInfo getFileNode(int32_t index) const;
LuaNPKFileStream* openFileStream(const char* szFileName);
void closeFileStream(LuaNPKFileStream* fileStream);
public:
NPK::INPKFile* m_pNPKFile = nullptr;
public:
LuaNPKFile();
~LuaNPKFile();
};
+113 -1
View File
@@ -11,9 +11,100 @@
#include "sgu_mode_npk_dump_list.h"
#include "sgu_mode_npk_extract_files.h"
#include "sgu_mode_download.h"
#include "sgu_mode_run_lua_file.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,
OPT_INPUT, OPT_INPUT2, OPT_OUTPUT,
@@ -65,6 +156,7 @@ static void printUsage(const char* moduleName)
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(" 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");
@@ -77,6 +169,7 @@ static void printUsage(const char* moduleName)
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 RunLuaFile -i script.lua\n");
}
enum WorkMode {
@@ -92,6 +185,7 @@ enum WorkMode {
WM_HTTP_DOWNLOAD,
WM_NPK_DUMPLIST,
WM_NPK_EXTRACT_FILES,
WM_RUN_LUA_FILE,
};
enum HashType {
@@ -138,6 +232,9 @@ WorkMode parserWorkMode(const char* modeStr)
else if (_stricmp(modeStr, "NPKExtractFiles") == 0) {
return WM_NPK_EXTRACT_FILES;
}
else if (_stricmp(modeStr, "RunLuaFile") == 0) {
return WM_RUN_LUA_FILE;
}
return WM_NONE;
}
@@ -418,7 +515,22 @@ int main(int argc, char* argv[])
}
}
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:
{
+9 -7
View File
@@ -16,7 +16,9 @@ bool dumpNPKFileList(const char* inputFilename, const char* outputFilename)
return false;
}
NPK::INPKFile* pakFile = NPK::createNPKFile();
if (!(pakFile->openPakFile(inputFilename)))
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;
@@ -28,27 +30,27 @@ bool dumpNPKFileList(const char* inputFilename, const char* outputFilename)
printf("Error: Failed to open output file: %s\n", outputFilename);
return false;
}
int32_t fileCount = pakFile->getFileCount();
int32_t fileCount = pakFile->getFileCounts();
// Dump file list
for(int32_t i=0; i < fileCount; i++)
{
NPK::INPKFile::FileNode fileNode;
if (!pakFile->getFileNode(i, fileNode))
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(fileNode.fileName.c_str());
NPK::IFileStream* fileStream = pakFile->openFileStream(baseInfo.keyName.c_str());
if (!fileStream)
{
printf("Error: Failed to open file stream for '%s', Error=%s\n", fileNode.fileName.c_str(), NPK::getLastErrorMessage());
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", fileNode.fileName.c_str(), crc32, fileNode.fileSize);
fprintf(fpOutput, "%s\t%08x\t%u\n", baseInfo.keyName.c_str(), crc32, baseInfo.fileSize);
pakFile->closeFileStream(fileStream);
}
+10 -7
View File
@@ -21,19 +21,21 @@ bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir)
{
return false; // Failed to create NPK file interface
}
if (!npkFile->openPakFile(szNPKFileName))
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->getFileCount();
int32_t fileCount = npkFile->getFileCounts();
for (int32_t i = 0; i < fileCount; ++i)
{
NPK::INPKFile::FileNode fileNode;
if (npkFile->getFileNode(i, fileNode))
NPK::FileItemBaseInfo baseInfo;
if (!npkFile->getFileItemBaseInfo(i, &baseInfo))
{
std::string outputPathName = std::string(szOutputDir) + "/" + fileNode.fileName;
std::string outputPathName = std::string(szOutputDir) + "/" + baseInfo.keyName;
char szOutputPath[MAX_PATH];
StringCbCopyA(szOutputPath, sizeof(szOutputPath), outputPathName.c_str());
@@ -46,10 +48,11 @@ bool extractNPKFiles(const char* szNPKFileName, const char* szOutputDir)
return false;
}
NPK::IFileStream* fileStream = npkFile->openFileStream(fileNode.fileName.c_str());
NPK::IFileStream* fileStream = npkFile->openFileStream(baseInfo.keyName.c_str());
if(fileStream == nullptr)
{
printf("Error: Failed to open file stream for '%s', Error=%s\n", fileNode.fileName.c_str(), NPK::getLastErrorMessage());
printf("Error: Failed to open file stream for '%s', Error=%s\n",
baseInfo.keyName.c_str(), NPK::getLastErrorMessage());
NPK::closeNPKFile(npkFile);
return false;
}
+33
View File
@@ -0,0 +1,33 @@
#include "sgu_mode_run_lua_file.h"
#include "sgu_lua_npk_file.h"
#include "libNPK.h"
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#include "lua_tinker.h"
bool run_lua_file(const char* szLuaFilename)
{
lua_State* L = lua_open();
luaL_openlibs(L);
//register global functions
lua_tinker::def(L, "getLastErrorCode", &NPK::getLastErrorCode);
lua_tinker::def(L, "getLastErrorMessage", &NPK::getLastErrorMessage);
//register classes
LuaNPKFile::registerLuaApi(L);
//run lua file
lua_tinker::dofile(L, szLuaFilename);
//cleanup
lua_close(L);
return true;
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
bool run_lua_file(const char* szLuaFilename);