SA-MP/saco/archive/ArchiveCommon.h

117 lines
2.1 KiB
C
Raw Permalink Normal View History

2023-11-08 20:29:53 +08:00
#pragma once
#include <windows.h>
#include "Stream.h"
// SAA_FILE_ID := {'S', 'A', 'M', 'P'} ignoring first 3 bits of each char
// first 3 bits are 010 anyhow :)
#define SAA_FILE_ID 0x83433
#define SAA_FILE_VERSION 2
#define SAA_BLOCK_SIZE 2048
2023-11-08 20:29:53 +08:00
#define SAA_MAX_ENTRIES 256
#define SAA_MAX_FAKEDATA 120
typedef struct _SAA_ENTRY
{
DWORD dwFileNameHash;
union
{
struct
{
DWORD dwPrevEntry : 8; // index to previous entry (link to fake entry if none)
DWORD dwFileSize : 24; // 24bits = max filesize of 16mb
};
DWORD dwDataBlock;
};
2023-11-08 20:29:53 +08:00
} SAA_ENTRY;
typedef struct _SAA_FILE_HEADER
{
// This is a fake header
struct VER1_HEADER
{
DWORD dwSAAV;
DWORD dwFileCount;
WORD wFakeData[SAA_MAX_FAKEDATA];
} headerV1; /* 248 bytes */
struct VER2_HEADER
{
union
{
struct
{
DWORD dwSAMPID : 20;
DWORD dwVersion : 3;
DWORD dwSignSize : 8;
DWORD dwPadding1 : 1;
};
DWORD dwCompleteID;
};
union
{
struct
{
DWORD dwPadding2 : 5;
DWORD dwInvalidIndex : 8;
DWORD dwPadding3 : 19;
};
DWORD dwXORKey;
};
} headerV2; /* 8 bytes */
DWORD dwFakeDataSize;
_SAA_FILE_HEADER()
{
dwFakeDataSize = SAA_MAX_FAKEDATA;
}
DWORD SizeOf()
{
return(sizeof(DWORD)*2 + sizeof(WORD)*dwFakeDataSize + sizeof(VER2_HEADER));
}
2024-05-23 23:22:12 +08:00
#ifdef ARCTOOL
void InitializeDataV1()
{
headerV1.dwSAAV = 0x32414153; // "SAA2"
headerV1.dwFileCount = 0x16;
// All other data should be random, or predefined outside.
}
void InitializeDataV2()
{
headerV2.dwSAMPID = SAA_FILE_ID;
headerV2.dwVersion = SAA_FILE_VERSION;
}
void Write(FILE *f)
{
fseek(f, 0, SEEK_SET);
fwrite(&headerV1, 1, sizeof(DWORD)*2 + sizeof(WORD)*dwFakeDataSize, f);
fwrite(&headerV2, 1, sizeof(VER2_HEADER), f);
}
#endif
2023-11-08 20:29:53 +08:00
bool VerifyIdentifier()
{
return ((headerV2.dwSAMPID == SAA_FILE_ID) &&
(headerV2.dwVersion == SAA_FILE_VERSION));
}
void XorV2Identifier() {
this->headerV2.dwCompleteID ^= this->headerV2.dwXORKey;
}
void Read(CAbstractStream *pStream)
{
pStream->Read(&headerV1, sizeof(DWORD)*2 + sizeof(WORD)*dwFakeDataSize);
pStream->Read(&headerV2, sizeof(VER2_HEADER));
}
} SAA_FILE_HEADER;