Author: 1. Date 2016-09-27 19:40:31, views: 637, Raw
#pragma once #include <WTypes.h> #if REG_DWORD == REG_DWORD_LITTLE_ENDIAN #define __INTEL_BYTE_ORDER__ 1 #endif class FArchive { public: // FArchive interface. virtual ~FArchive() { } virtual void Serialize(void* V, INT Length) { } virtual void SerializeBits(void* V, INT LengthBits) { Serialize(V, (LengthBits + 7) / 8); if (IsLoading()) ((BYTE*)V)[LengthBits / 8] &= ((1 << (LengthBits & 7)) - 1); } virtual void SerializeInt(DWORD& Value, DWORD Max) { *this << *(DWORD*)Value; } virtual void Preload(void* Object) { } virtual void CountBytes(SIZE_T InNum, SIZE_T InMax) { } virtual FArchive& operator<<(class FName& N) { return *this; } virtual FArchive& operator<<(class UObject*& Res) { return *this; } virtual INT MapName(FName* Name) { return 0; } virtual INT MapObject(UObject* Object) { return 0; } virtual INT Tell() { return -1; } virtual INT TotalSize() { return -1; } virtual BOOL AtEnd() { INT Pos = Tell(); return Pos != -1 && Pos >= TotalSize(); } virtual BOOL AtStopper() { BOOL res = FALSE; INT Size = TotalSize(); if (Size != -1) { if (ArStopper != -1 && Size >= ArStopper) res = TRUE; } return res; } virtual void SetStopper(INT Stopper) { ArStopper = Stopper; } virtual void Seek(INT InPos) { } virtual void AttachLazyLoader(void* LazyLoader) { } virtual void DetachLazyLoader(void* LazyLoader) { } virtual void AttachRoughLoader(void* RoughLoader) { } virtual void DetachRoughLoader(void* RoughLoader) { } virtual void Precache(INT HintCount) { } virtual void Flush() { } virtual BOOL Close() { return !ArIsError; } virtual BOOL GetError() { return ArIsError; } virtual INT GetCurrentEncryptVersion() { return 0; } // Hardcoded datatype routines that may not be overridden. FArchive& ByteOrderSerialize(void* V, INT Length) { #if __INTEL_BYTE_ORDER__ Serialize(V, Length); #else if( ArIsPersistent ) { // Transferring between memory and file, so flip the byte order. for( INT i=Length-1; i>=0; i-- ) Serialize( (BYTE*)V + i, 1 ); } else { // Transferring around within memory, so keep the byte order. Serialize( V, Length ); } #endif return *this; } // Constructor. FArchive() : ArVer(/*PACKAGE_FILE_VERSION*/0x7B) , ArNetVer(/*ENGINE_NEGOTIATION_VERSION*/0x7D0) , ArLicenseeVer(/*PACKAGE_FILE_VERSION_LICENSEE*/0x1E) , ArIsLoading(0) , ArIsSaving(0) , ArIsTrans(0) , ArIsPersistent(0) , ArIsError(0) , ArForEdit(0) , ArForClient(0) , ArForServer(0) , ArUnk1(0) , ArStopper(-1) { } // Status accessors. INT Ver() { return ArVer; } INT NetVer() { return ArNetVer & 0x7fffffff; } INT LicenseeVer() { return ArLicenseeVer; } BOOL IsLoading() { return ArIsLoading; } BOOL IsSaving() { return ArIsSaving; } BOOL IsTrans() { return ArIsTrans; } BOOL IsNet() { return (ArNetVer & 0x80000000) != 0; } BOOL IsPersistent() { return ArIsPersistent; } BOOL IsError() { return ArIsError; } BOOL ForEdit() { return ArForEdit; } BOOL ForClient() { return ArForClient; } BOOL ForServer() { return ArForServer; } // Friend archivers. friend FArchive& operator<<(FArchive& Ar, PCHAR& C) { Ar.Serialize(&C, 1); return Ar; } friend FArchive& operator<<(FArchive& Ar, BYTE& B) { Ar.Serialize(&B, 1); return Ar; } friend FArchive& operator<<(FArchive& Ar, CHAR& B) { Ar.Serialize(&B, 1); return Ar; } friend FArchive& operator<<(FArchive& Ar, WORD& W) { Ar.ByteOrderSerialize(&W, sizeof(W)); return Ar; } friend FArchive& operator<<(FArchive& Ar, SHORT& S) { Ar.ByteOrderSerialize(&S, sizeof(S)); return Ar; } friend FArchive& operator<<(FArchive& Ar, DWORD& D) { Ar.ByteOrderSerialize(&D, sizeof(D)); return Ar; } friend FArchive& operator<<(FArchive& Ar, INT& I) { Ar.ByteOrderSerialize(&I, sizeof(I)); return Ar; } friend FArchive& operator<<(FArchive& Ar, FLOAT& F) { Ar.ByteOrderSerialize(&F, sizeof(F)); return Ar; } friend FArchive& operator<<(FArchive& Ar, DWORD64& Q) { Ar.ByteOrderSerialize(&Q, sizeof(Q)); return Ar; } friend FArchive& operator<<(FArchive& Ar, long long& S) { Ar.ByteOrderSerialize(&S, sizeof(S)); return Ar; } friend FArchive& operator<<(FArchive& Ar, /*FTime*/INT& F); public: // Status variables. INT ArVer; INT ArNetVer; INT ArLicenseeVer; BOOL ArIsLoading; BOOL ArIsSaving; BOOL ArIsTrans; BOOL ArIsPersistent; BOOL ArForEdit; BOOL ArForClient; BOOL ArForServer; BOOL ArIsError; BOOL ArUnk1; INT ArStopper; }; class FArchiveFileReader : public FArchive { public: FArchiveFileReader(HANDLE InFile, void* InError, INT InSize) : File(InFile) , Error(InError) , Size(InSize) , Pos(0) , BufferBase(0) , BufferCount(0) , SleepFactor(0.0f) { SetFilePointer(File, 0, 0, FILE_BEGIN); ArIsLoading = ArIsPersistent = 1; } ~FArchiveFileReader() { if (File) { FArchiveFileReader::Close(); } } void Precache(INT HintCount) override { BufferBase = Pos; BufferCount = min( min( HintCount, (INT)(ARRAYSIZE(Buffer) - (Pos & (ARRAYSIZE(Buffer)-1))) ), Size-Pos ); if (!ReadFile(File, Buffer, BufferCount) && BufferCount != 0) { ArIsError = 1; //Error->Logf( TEXT("fread failed: BufferCount=%i"), BufferCount ); return; } } void Seek(INT InPos) override { //assert(InPos >= 0); //assert(InPos <= Size); if (SetFilePointer(File, InPos, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { ArIsError = 1; //Error->Logf( TEXT("Seek failed: %i/%i: %i"), InPos, Size, Pos ); } Pos = InPos; BufferBase = Pos; BufferCount = 0; } INT Tell() override { return Pos; } INT TotalSize() override { return Size; } BOOL Close() override { if (File) CloseHandle(File); File = NULL; return !ArIsError; } void Serialize(void* V, INT Length) override { while (Length > 0) { INT Copy = min( Length, BufferBase+BufferCount-Pos ); if (Copy == 0) { if (Length >= ARRAYSIZE(Buffer)) { if (!ReadFile(File, V, Length)) { ArIsError = 1; //Error->Logf( TEXT("fread failed: Length=%i"), Length ); } Pos += Length; BufferBase += Length; return; } Precache(MAXINT); Copy = min( Length, BufferBase + BufferCount - Pos ); if (Copy <= 0) { ArIsError = 1; //Error->Logf( TEXT("ReadFile beyond EOF %i+%i/%i"), Pos, Length, Size ); } if (ArIsError) return; } ::memcpy(V, Buffer + Pos - BufferBase, Copy); Pos += Copy; Length -= Copy; V = (BYTE*)V + Copy; } } BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead) { DWORD dwRead = 0; BOOL readOk = ::ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, &dwRead, 0) && nNumberOfBytesToRead == dwRead; return readOk; } public: HANDLE File; void* Error; INT Size; INT Pos; INT BufferBase; INT BufferCount; float SleepFactor; BYTE Buffer[1024]; }; extern wchar_t GLineage2Ver[12]; DWORD Get121Key(const wchar_t* FileName); class FL2FileDecryptArchive : public FArchive { public: FL2FileDecryptArchive(HANDLE InFile, void* InError, INT InSize, const wchar_t* FileName) : ArchiveFileReader(nullptr), CryptVer(0), HeaderSize(0), CryptKey(0xAC) { FArchiveFileReader* reader = new FArchiveFileReader(InFile, InError, GetFileSize(InFile, 0)); ArchiveFileReader = reader; if (InSize <= 0x18) { ArchiveFileReader->Seek(0); } else { for (int i = 0; i < 11; ++i) { wchar_t c; ArchiveFileReader->Serialize(&c, sizeof(c)); if (c != GLineage2Ver[i]) { ArchiveFileReader->Seek(0); return; } } wchar_t buf_ver[3]; ArchiveFileReader->Serialize(&buf_ver[0], sizeof(wchar_t)); ArchiveFileReader->Serialize(&buf_ver[1], sizeof(wchar_t)); ArchiveFileReader->Serialize(&buf_ver[2], sizeof(wchar_t)); long ver = wcstol(buf_ver, 0, 10); CryptVer = ver; HeaderSize = 28; if (CryptVer == 111) { CryptKey = 0xAC; } else if (CryptVer == 121) { CryptKey = static_cast<BYTE>(Get121Key(FileName)); } else { CryptKey = 0; } } } ~FL2FileDecryptArchive() { if(ArchiveFileReader) { delete ArchiveFileReader; ArchiveFileReader = 0; } } void Serialize(void* V, INT Length) override { int ver = CryptVer; if (ver > 212) { if (ver != 311 && ver - 411 > 2) return; ArchiveFileReader->Serialize(V, Length); return; } if (ver >= 211 || !ver) { ArchiveFileReader->Serialize(V, Length); return; } if (ver == 111 || ver == 121) { ArchiveFileReader->Serialize(V, Length); for (int i = 0; i < Length; ++i) *((BYTE*)V + i) ^= this->CryptKey; } } INT Tell() override { int ver = CryptVer; if (ver > 212) { if (ver != 311 && ver - 411 > 2) return -1; return ArchiveFileReader->Tell() - this->HeaderSize; } if (ver >= 211) return ArchiveFileReader->Tell() - this->HeaderSize; if (!ver) return ArchiveFileReader->Tell(); if (ver == 111 || ver == 121) return ArchiveFileReader->Tell() - this->HeaderSize; return -1; } INT TotalSize() override { int ver = CryptVer; if (ver > 212) { if (ver != 311 && ver - 411 > 2) return -1; return ArchiveFileReader->TotalSize() - this->HeaderSize; } if (ver >= 211) return ArchiveFileReader->TotalSize() - this->HeaderSize; if (!ver) return ArchiveFileReader->TotalSize(); if (ver == 111 || ver == 121) return ArchiveFileReader->TotalSize() - this->HeaderSize; return -1; } void Seek(INT InPos) override { int ver = this->CryptVer; if (ver > 212) { if (ver != 311 && ver - 411 > 2) return; ArchiveFileReader->Seek(InPos + this->HeaderSize); return; } if (ver >= 211) { ArchiveFileReader->Seek(InPos + this->HeaderSize); return; } if (!ver) { ArchiveFileReader->Seek(InPos); return; } if (ver == 111 || ver == 121) ArchiveFileReader->Seek(InPos + this->HeaderSize); } void Precache(INT HintCount) override { int ver = this->CryptVer; if (ver > 212) { if (ver != 311 && (unsigned int)(ver - 411) > 2) return; ArchiveFileReader->Precache(HintCount); return; } if (ver >= 211 || !ver) { ArchiveFileReader->Precache(HintCount); } else if (ver == 111 || ver == 121) { ArchiveFileReader->Precache(HintCount); } } BOOL Close() override { int ver = this->CryptVer; if (ver > 212) { if (ver != 311 && (unsigned int)(ver - 411) > 2) return ArForServer == 0; return ArchiveFileReader->Close(); } if (ver >= 211 || !ver) { return ArchiveFileReader->Close(); } if (ver == 111 || ver == 121) { return ArchiveFileReader->Close(); } return ArForServer == 0; } INT GetCurrentEncryptVersion() override { return CryptVer; } public: FArchiveFileReader* ArchiveFileReader; int CryptVer; int HeaderSize; BYTE CryptKey; };