214 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			214 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | #include "EngineCore/Asset_Script.h"
 | ||
|  | #include "Asset_Script.h"
 | ||
|  | 
 | ||
|  | void Asset_Script::Init() | ||
|  | { | ||
|  |     // 读取头建立树
 | ||
|  |     InitHeader(); | ||
|  |     // 读取bin文件
 | ||
|  |     InitBin(); | ||
|  |     // 读取LoadString
 | ||
|  |     InitLoadString(); | ||
|  | 
 | ||
|  |     InitFlag = true; | ||
|  | } | ||
|  | 
 | ||
|  | void Asset_Script::Clear() | ||
|  | { | ||
|  |     FileInfo.clear(); | ||
|  |     BinStringM.clear(); | ||
|  |     LoadStringM.clear(); | ||
|  |     _Data.clear(); | ||
|  |     _Data.shrink_to_fit(); | ||
|  |     InitFlag = false; | ||
|  | } | ||
|  | 
 | ||
|  | void Asset_Script::InitHeader() | ||
|  | { | ||
|  |     // 读取UUID的长度
 | ||
|  |     int UUID_LENGTH = GetInt(); | ||
|  |     // UUID  读 1 - 36位 构造 UTF8 string
 | ||
|  |     std::string UUID = GetString(UUID_LENGTH); | ||
|  |     // 版本号
 | ||
|  |     int Version = GetInt(); | ||
|  |     (void)Version; | ||
|  |     // 文件路径数据的大小
 | ||
|  |     int AlignedIndexHeaderSize = GetInt(); | ||
|  |     // 解密密钥
 | ||
|  |     int IndexHeaderCrc = GetInt(); | ||
|  |     // 文件数量
 | ||
|  |     int IndexSize = GetInt(); | ||
|  |     // 文件起始位置
 | ||
|  |     int FristPos = tellg(); | ||
|  |     CrcDecode(AlignedIndexHeaderSize, IndexHeaderCrc); | ||
|  |     int CurrPos = 0; | ||
|  |     StartPos = AlignedIndexHeaderSize + 56; | ||
|  |     // 建立pvf文件索引表
 | ||
|  |     for (int i = 0; i < IndexSize; i++) | ||
|  |     { | ||
|  |         seek(FristPos + CurrPos); | ||
|  |         int FileNumber = GetInt(); | ||
|  |         (void)FileNumber; | ||
|  |         int FilePathLength = GetInt(); | ||
|  |         std::string FileName = tolower(GetString(FilePathLength)); | ||
|  |         int FileLength = GetInt(); | ||
|  |         int Cre32 = GetInt(); | ||
|  |         int RelativeOffset = GetInt(); | ||
|  |         if (FileLength > 0) | ||
|  |         { | ||
|  |             int RealFileLength = (FileLength + 3) & 4294967292; | ||
|  |             PvfFileInfo Info; | ||
|  |             Info.ROffset = RelativeOffset; | ||
|  |             Info.Cr32 = Cre32; | ||
|  |             Info.Length = RealFileLength; | ||
|  |             Info.DecodeFlag = false; | ||
|  |             FileInfo[FileName] = Info; | ||
|  |         } | ||
|  |         CurrPos += 20; | ||
|  |         CurrPos += FilePathLength; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void Asset_Script::InitBin() | ||
|  | { | ||
|  |     if (FileInfo.count("stringtable.bin") == 0) | ||
|  |     { | ||
|  |         SDL_LogError(0, "stringtable.bin文件不存在"); | ||
|  |         return; | ||
|  |     } | ||
|  |     PvfFileInfo BinInfo = FileInfo["stringtable.bin"]; | ||
|  |     seek(StartPos + BinInfo.ROffset); | ||
|  |     CrcDecode(BinInfo.Length, BinInfo.Cr32); | ||
|  |     seek(StartPos + BinInfo.ROffset); | ||
|  |     int FileHPos = tellg(); | ||
|  |     int Count = GetInt(); | ||
|  |     int CurrentIndex = 0; | ||
|  | 
 | ||
|  |     for (int i = 0; i < Count; i++) | ||
|  |     { | ||
|  |         seek(FileHPos + CurrentIndex * 4 + 4); | ||
|  |         int StartPos = GetInt(); | ||
|  |         int EndPos = GetInt(); | ||
|  |         int Len = EndPos - StartPos; | ||
|  |         seek(FileHPos + StartPos + 4); | ||
|  |         std::string Str = GetString(Len); | ||
|  |         BinStringM[CurrentIndex] = Str; | ||
|  |         CurrentIndex++; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void Asset_Script::InitLoadString() | ||
|  | { | ||
|  |     if (FileInfo.count("n_string.lst") == 0) | ||
|  |     { | ||
|  |         SDL_LogError(0, "n_string.lst文件不存在"); | ||
|  |     } | ||
|  |     PvfFileInfo Info = FileInfo["n_string.lst"]; | ||
|  |     seek(StartPos + Info.ROffset); | ||
|  |     CrcDecode(Info.Length, Info.Cr32); | ||
|  |     seek(StartPos + Info.ROffset); | ||
|  | 
 | ||
|  |     int FileHPos = tellg(); | ||
|  |     int Flag = GetShort(); | ||
|  |     (void)Flag; | ||
|  |     int i = 2; | ||
|  |     while (i < Info.Length) | ||
|  |     { | ||
|  |         if ((Info.Length - i) >= 10) | ||
|  |         { | ||
|  |             seek(FileHPos + i + 6); | ||
|  |             int FindKey = GetInt(); | ||
|  |             std::string Key = GetBinString(FindKey); | ||
|  |             std::string Type = tolower(Key.substr(0, Key.find("/"))); | ||
|  |             if (Key.length() > 0) | ||
|  |             { | ||
|  |                 PvfFileInfo *FileInfo = GetFileInfo(Key); | ||
|  |                 if (FileInfo == nullptr) | ||
|  |                     continue; | ||
|  | 
 | ||
|  |                 seek(StartPos + FileInfo->ROffset); | ||
|  |                 CrcDecode(FileInfo->Length, FileInfo->Cr32); | ||
|  |                 seek(StartPos + FileInfo->ROffset); | ||
|  | 
 | ||
|  |                 std::string Str = GetStringNormal(FileInfo->Length); | ||
|  |                 std::vector<std::string> StrArr = split(Str, "\n"); | ||
|  |                 for (auto it = StrArr.begin(); it != StrArr.end(); ++it) | ||
|  |                 { | ||
|  |                     std::string strobj = *it; | ||
|  |                     if (strobj.find(">") != std::string::npos) | ||
|  |                     { | ||
|  |                         std::vector<std::string> strobjarr = split(strobj, ">"); | ||
|  |                         if (strobjarr.size() > 1) | ||
|  |                         { | ||
|  |                             LoadStringM[Type][strobjarr[0]] = strobjarr[1]; | ||
|  |                         } | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         else | ||
|  |             break; | ||
|  |         i += 10; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | std::string Asset_Script::GetBinString(int Key) | ||
|  | { | ||
|  |     if (BinStringM.count(Key)) | ||
|  |         return BinStringM[Key]; | ||
|  |     return ""; | ||
|  | } | ||
|  | 
 | ||
|  | std::string Asset_Script::GetLoadString(std::string Type, std::string Key) | ||
|  | { | ||
|  |     if (LoadStringM.count(Type) && LoadStringM[Type].count(Key)) | ||
|  |         return LoadStringM[Type][Key]; | ||
|  |     return ""; | ||
|  | } | ||
|  | 
 | ||
|  | Asset_Script::PvfFileInfo *Asset_Script::GetFileInfo(std::string path) | ||
|  | { | ||
|  |     path = tolower(path); | ||
|  |     if (FileInfo.count(path)) | ||
|  |         return &FileInfo[path]; | ||
|  |     return nullptr; | ||
|  | } | ||
|  | 
 | ||
|  | std::string Asset_Script::GetFileContent(std::string path) | ||
|  | { | ||
|  |     if (FileInfo.count(path)) | ||
|  |     { | ||
|  |         seek(StartPos + FileInfo[path].ROffset); | ||
|  |         if (FileInfo[path].DecodeFlag == false) | ||
|  |         { | ||
|  |             CrcDecode(FileInfo[path].Length, FileInfo[path].Cr32); | ||
|  |             seek(StartPos + FileInfo[path].ROffset); | ||
|  |             FileInfo[path].DecodeFlag = true; | ||
|  |         } | ||
|  |         char *blobp = new char[FileInfo[path].Length]; | ||
|  |         read((char *)blobp, FileInfo[path].Length); | ||
|  |         std::string Str(blobp); | ||
|  |         delete[] blobp; | ||
|  |         return Str; | ||
|  |     } | ||
|  |     return std::string(); | ||
|  | } | ||
|  | 
 | ||
|  | std::vector<BYTE> Asset_Script::GetFileContentByte(std::string path) | ||
|  | { | ||
|  |     if (FileInfo.count(path)) | ||
|  |     { | ||
|  |         seek(StartPos + FileInfo[path].ROffset); | ||
|  |         if (FileInfo[path].DecodeFlag == false) | ||
|  |         { | ||
|  |             CrcDecode(FileInfo[path].Length, FileInfo[path].Cr32); | ||
|  |             seek(StartPos + FileInfo[path].ROffset); | ||
|  |             FileInfo[path].DecodeFlag = true; | ||
|  |         } | ||
|  |         std::vector<BYTE> blobp(FileInfo[path].Length); | ||
|  |         read((char *)blobp.data(), FileInfo[path].Length); | ||
|  |         return blobp; | ||
|  |     } | ||
|  |     return std::vector<BYTE>(); | ||
|  | } |