209 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| #pragma once
 | ||
| #include "IO_Ex.hpp"
 | ||
| #include <iostream>
 | ||
| #include <map>
 | ||
| #include <cstdint>
 | ||
| #include "squirrel.h"
 | ||
| #include "sqstdaux.h"
 | ||
| #include "sqstdblob.h"
 | ||
| #include "sqstdio.h"
 | ||
| #include "sqstdmath.h"
 | ||
| #include "sqstdstring.h"
 | ||
| #include "sqstdsystem.h"
 | ||
| 
 | ||
| class PVF_IO : public IO_Ex
 | ||
| {
 | ||
|     struct PvfFileInfo
 | ||
|     {
 | ||
|         int ROffset;
 | ||
|         int Cr32;
 | ||
|         int Length;
 | ||
|         bool DecodeFlag = false;
 | ||
|     };
 | ||
| private:
 | ||
|     int StartPos = 0;
 | ||
|     std::map<std::string, PvfFileInfo>FileInfo;
 | ||
|     std::map<int, std::string>BinStringM;
 | ||
|     std::map<std::string, std::string>LoadStringM;
 | ||
| 
 | ||
| public:
 | ||
|     // 构造函数
 | ||
|     PVF_IO(const char* defaultFilename = "Script.pvf") : IO_Ex(defaultFilename) {}
 | ||
| 
 | ||
|     // 析构函数,在对象销毁时,基类(fstream)的析构函数会自动被调用,一般不需要额外特殊处理
 | ||
|     ~PVF_IO() {}
 | ||
| 
 | ||
|     // 显式删除拷贝构造函数,禁止拷贝操作
 | ||
|     PVF_IO(const PVF_IO&) = delete;
 | ||
| 
 | ||
|     // 也可以考虑同时删除拷贝赋值运算符,保持一致的语义,避免误用
 | ||
|     PVF_IO& operator=(const PVF_IO&) = delete;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| public:
 | ||
|     void Init() {
 | ||
|         //读取头建立树
 | ||
|         InitHeader();
 | ||
| 
 | ||
|         //读取bin文件
 | ||
|         InitBin();
 | ||
| 
 | ||
|         //读取LoadString
 | ||
|         InitLoadString();
 | ||
|     }
 | ||
| 
 | ||
|     void InitHeader() {
 | ||
|         //读取UUID的长度
 | ||
|         int UUID_LENGTH = GetInt();
 | ||
|         //UUID  读 1 - 36位 构造 UTF8 string
 | ||
|         std::string UUID = GetString(UUID_LENGTH);
 | ||
|         //版本号
 | ||
|         int Version = GetInt();
 | ||
|         // 文件路径数据的大小
 | ||
|         int AlignedIndexHeaderSize = GetInt();
 | ||
|         // 解密密钥
 | ||
|         int IndexHeaderCrc = GetInt();
 | ||
|         // 文件数量
 | ||
|         int IndexSize = GetInt();
 | ||
| 
 | ||
|         //文件起始位置
 | ||
|         int FristPos = tellg();
 | ||
| 
 | ||
|         //std::cout << "UUID_LENGTH: " << UUID_LENGTH << std::endl;
 | ||
|         //std::cout << "UUID: " << UUID << std::endl;
 | ||
|         //std::cout << "Version: " << Version << std::endl;
 | ||
|         //std::cout << "AlignedIndexHeaderSize: " << AlignedIndexHeaderSize << std::endl;
 | ||
|         //std::cout << "IndexHeaderCrc: " << IndexHeaderCrc << std::endl;
 | ||
|         //std::cout << "IndexSize: " << IndexSize << std::endl;
 | ||
| 
 | ||
|         CrcDecode(AlignedIndexHeaderSize, IndexHeaderCrc);
 | ||
| 
 | ||
|         int CurrPos = 0;
 | ||
|         StartPos = AlignedIndexHeaderSize + 56;
 | ||
| 
 | ||
|         //建立pvf文件索引表
 | ||
|         for (size_t i = 0; i < IndexSize; i++)
 | ||
|         {
 | ||
|             seek(FristPos + CurrPos);
 | ||
|             int FileNumber = GetInt();
 | ||
|             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 InitBin() {
 | ||
|         if (FileInfo.count("stringtable.bin") == 0) {
 | ||
|             std::cout << "bin文件不存在" << std::endl;
 | ||
|             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 InitLoadString() {
 | ||
|         if (FileInfo.count("n_string.lst") == 0) {
 | ||
|             std::cout << "LoadString文件不存在" << std::endl;
 | ||
|             return;
 | ||
|         }
 | ||
|         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();
 | ||
|         int i = 2;
 | ||
|         while (i < Info.Length)
 | ||
|         {
 | ||
|             if ((Info.Length - i) >= 10) {
 | ||
|                 seek(FileHPos + i + 6);
 | ||
|                 int FindKey = GetInt();
 | ||
|                 std::string Key = GetBinString(FindKey);
 | ||
|                 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 = GetString(FileInfo->Length);
 | ||
|                     std::vector<std::string> StrArr = split(Str, "\r\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[strobjarr[0]] = strobjarr[1];
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             else break;
 | ||
|             i += 10;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| public:
 | ||
|     std::string GetBinString(int Key) {
 | ||
|         if (BinStringM.count(Key))return BinStringM[Key];
 | ||
|         return "";
 | ||
|     }
 | ||
|     std::string GetLoadString(std::string Key) {
 | ||
|         if (LoadStringM.count(Key))return LoadStringM[Key];
 | ||
|         return "";
 | ||
|     }
 | ||
|     PvfFileInfo* GetFileInfo(std::string path) {
 | ||
|         path = tolower(path);
 | ||
|         if (FileInfo.count(path))return &FileInfo[path];
 | ||
|         return nullptr;
 | ||
|     }
 | ||
|     void LoadFileToBlob(HSQUIRRELVM v ,std::string path, SQUserPointer blobp) {
 | ||
|         path = tolower(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;
 | ||
|             }
 | ||
|             read((char*)blobp, FileInfo[path].Length);
 | ||
|             return;
 | ||
|         }
 | ||
|         sq_pushnull(v);
 | ||
|         return;
 | ||
|     }
 | ||
| }; |