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:
|
|||
|
|
// <20><><EFBFBD>캯<EFBFBD><ECBAAF>
|
|||
|
|
PVF_IO(const char* defaultFilename = "Script.pvf") : IO_Ex(defaultFilename) {}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ࣨfstream<61><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>һ<EFBFBD>㲻<EFBFBD><E3B2BB>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E2B4A6>
|
|||
|
|
~PVF_IO() {}
|
|||
|
|
|
|||
|
|
// <20><>ʽɾ<CABD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
PVF_IO(const PVF_IO&) = delete;
|
|||
|
|
|
|||
|
|
// Ҳ<><D2B2><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD>ͬʱɾ<CAB1><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD>壬<EFBFBD><E5A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
PVF_IO& operator=(const PVF_IO&) = delete;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
void Init() {
|
|||
|
|
//<2F><>ȡͷ<C8A1><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
InitHeader();
|
|||
|
|
|
|||
|
|
//<2F><>ȡbin<69>ļ<EFBFBD>
|
|||
|
|
InitBin();
|
|||
|
|
|
|||
|
|
//<2F><>ȡLoadString
|
|||
|
|
InitLoadString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void InitHeader() {
|
|||
|
|
//<2F><>ȡUUID<49>ij<EFBFBD><C4B3><EFBFBD>
|
|||
|
|
int UUID_LENGTH = GetInt();
|
|||
|
|
//UUID <20><> 1 - 36λ <20><><EFBFBD><EFBFBD> UTF8 string
|
|||
|
|
std::string UUID = GetString(UUID_LENGTH);
|
|||
|
|
//<2F>汾<EFBFBD><E6B1BE>
|
|||
|
|
int Version = GetInt();
|
|||
|
|
// <20>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>ݵĴ<DDB5>С
|
|||
|
|
int AlignedIndexHeaderSize = GetInt();
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ
|
|||
|
|
int IndexHeaderCrc = GetInt();
|
|||
|
|
// <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int IndexSize = GetInt();
|
|||
|
|
|
|||
|
|
//<2F>ļ<EFBFBD><C4BC><EFBFBD>ʼλ<CABC><CEBB>
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
//<2F><><EFBFBD><EFBFBD>pvf<76>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
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<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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;
|
|||
|
|
}
|
|||
|
|
};
|