增加Lua导出和FileList
This commit is contained in:
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
bool run_lua_file(const char* szLuaFilename);
|
||||
Reference in New Issue
Block a user