Rindro-Plugins/Include/PVF_IO.hpp

209 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
};