mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
366 lines
11 KiB
C++
366 lines
11 KiB
C++
/*****************************************************************************/
|
|
/* CascMndxRoot.h Copyright (c) Ladislav Zezula 2014 */
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Interface file for MNDX structures */
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Date Ver Who Comment */
|
|
/* -------- ---- --- ------- */
|
|
/* 15.05.14 1.00 Lad Created */
|
|
/*****************************************************************************/
|
|
|
|
#ifndef __CASC_MNDX_ROOT__
|
|
#define __CASC_MNDX_ROOT__
|
|
|
|
class TFileNameDatabase;
|
|
|
|
#define CASC_MAX_ENTRIES(type) (0xFFFFFFFF / sizeof(type))
|
|
|
|
#define CASC_SEARCH_INITIALIZING 0
|
|
#define CASC_SEARCH_SEARCHING 2
|
|
#define CASC_SEARCH_FINISHED 4
|
|
|
|
typedef struct _TRIPLET
|
|
{
|
|
DWORD BaseValue;
|
|
DWORD Value2;
|
|
DWORD Value3;
|
|
} TRIPLET, *PTRIPLET;
|
|
|
|
typedef struct _NAME_FRAG
|
|
{
|
|
DWORD ItemIndex; // Back index to various tables
|
|
DWORD NextIndex; // The following item index
|
|
DWORD FragOffs; // Higher 24 bits are 0xFFFFFF00 --> A single matching character
|
|
// Otherwise --> Offset to the name fragment table
|
|
} NAME_FRAG, *PNAME_FRAG;
|
|
|
|
typedef struct _PATH_STOP
|
|
{
|
|
DWORD ItemIndex;
|
|
DWORD field_4;
|
|
DWORD field_8;
|
|
DWORD field_C;
|
|
DWORD field_10;
|
|
} PATH_STOP, *PPATH_STOP;
|
|
|
|
typedef union _ARRAY_POINTER
|
|
{
|
|
LPBYTE Bytes; // Pointer to an octet
|
|
char * Chars; // Pointer to a character
|
|
PDWORD Uint32s; // Pointer to a DWORD
|
|
PTRIPLET Triplets; // Pointer to TRIPLET
|
|
PNAME_FRAG NameFrags; // Pointer to name fragment entry
|
|
PPATH_STOP PathStopPtr; // Pointer to path checkpoint
|
|
PULONGLONG Int64Ptr; // Pointer to 64-bit integer
|
|
|
|
} ARRAY_POINTER, *PARRAY_POINTER;
|
|
|
|
// Simple access to various tables within TGenericArray
|
|
#define ByteArray ArrayPointer.Bytes
|
|
#define CharArray ArrayPointer.Chars
|
|
#define Uint32Array ArrayPointer.Uint32s
|
|
#define TripletArray ArrayPointer.Triplets
|
|
#define NameFragArray ArrayPointer.NameFrags
|
|
|
|
class TByteStream
|
|
{
|
|
public:
|
|
|
|
TByteStream();
|
|
|
|
void ExchangeWith(TByteStream & Target);
|
|
int GetBytes(DWORD cbByteCount, PARRAY_POINTER PtrArray);
|
|
int SkipBytes(DWORD cbByteCount);
|
|
int SetByteBuffer(LPBYTE pbNewMarData, DWORD cbNewMarData);
|
|
int GetValue_DWORD(DWORD & Value);
|
|
int GetValue_ItemCount(DWORD & NumberOfBytes, DWORD & ItemCount, DWORD ItemSize);
|
|
int GetArray_DWORDs(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
|
int GetArray_Triplets(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
|
int GetArray_NameTable(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
|
int GetArray_BYTES(PARRAY_POINTER PtrArray, DWORD ItemCount);
|
|
|
|
LPBYTE pbByteData;
|
|
void * pvMappedFile;
|
|
DWORD cbByteData;
|
|
DWORD field_C;
|
|
HANDLE hFile;
|
|
HANDLE hMap;
|
|
};
|
|
|
|
class TGenericArray
|
|
{
|
|
public:
|
|
|
|
TGenericArray();
|
|
~TGenericArray();
|
|
|
|
int SetArrayValid();
|
|
|
|
void ExchangeWith(TGenericArray & Target);
|
|
void CopyFrom(TGenericArray & Source);
|
|
|
|
void SetMaxItems_CHARS(DWORD NewMaxItemCount);
|
|
void SetMaxItems_PATH_STOP(DWORD NewMaxItemCount);
|
|
|
|
void InsertOneItem_CHAR(char OneChar);
|
|
void InsertOneItem_PATH_STOP(PATH_STOP & NewItem);
|
|
|
|
void sub_19583A0(DWORD NewItemCount);
|
|
|
|
int LoadDwordsArray(TByteStream & InStream);
|
|
int LoadTripletsArray(TByteStream & InStream);
|
|
int LoadByteArray(TByteStream & InStream);
|
|
int LoadFragmentInfos(TByteStream & InStream);
|
|
int LoadStrings(TByteStream & InStream);
|
|
|
|
int LoadDwordsArray_Copy(TByteStream & InStream);
|
|
int LoadTripletsArray_Copy(TByteStream & InStream);
|
|
int LoadBytes_Copy(TByteStream & InStream);
|
|
int LoadFragmentInfos_Copy(TByteStream & InStream);
|
|
int LoadStringsWithCopy(TByteStream & InStream);
|
|
|
|
ARRAY_POINTER DataBuffer;
|
|
ARRAY_POINTER FirstValid;
|
|
|
|
ARRAY_POINTER ArrayPointer;
|
|
DWORD ItemCount; // Number of items in the array
|
|
DWORD MaxItemCount; // Capacity of the array
|
|
bool bIsValidArray;
|
|
};
|
|
|
|
class TBitEntryArray : public TGenericArray
|
|
{
|
|
public:
|
|
|
|
TBitEntryArray();
|
|
~TBitEntryArray();
|
|
|
|
DWORD GetBitEntry(DWORD EntryIndex)
|
|
{
|
|
DWORD dwItemIndex = (EntryIndex * BitsPerEntry) >> 0x05;
|
|
DWORD dwStartBit = (EntryIndex * BitsPerEntry) & 0x1F;
|
|
DWORD dwEndBit = dwStartBit + BitsPerEntry;
|
|
DWORD dwResult;
|
|
|
|
// If the end bit index is greater than 32,
|
|
// we also need to load from the next 32-bit item
|
|
if(dwEndBit > 0x20)
|
|
{
|
|
dwResult = (Uint32Array[dwItemIndex + 1] << (0x20 - dwStartBit)) | (Uint32Array[dwItemIndex] >> dwStartBit);
|
|
}
|
|
else
|
|
{
|
|
dwResult = Uint32Array[dwItemIndex] >> dwStartBit;
|
|
}
|
|
|
|
// Now we also need to mask the result by the bit mask
|
|
return dwResult & EntryBitMask;
|
|
}
|
|
|
|
void ExchangeWith(TBitEntryArray & Target);
|
|
int LoadFromStream(TByteStream & InStream);
|
|
int LoadFromStream_Exchange(TByteStream & InStream);
|
|
|
|
DWORD BitsPerEntry;
|
|
DWORD EntryBitMask;
|
|
DWORD TotalEntries;
|
|
};
|
|
|
|
class TStruct40
|
|
{
|
|
public:
|
|
|
|
TStruct40();
|
|
|
|
void InitSearchBuffers();
|
|
|
|
TGenericArray array_00;
|
|
TGenericArray PathStops; // Array of path checkpoints
|
|
DWORD ItemIndex; // Current name fragment: Index to various tables
|
|
DWORD CharIndex;
|
|
DWORD ItemCount;
|
|
DWORD SearchPhase; // 0 = initializing, 2 = searching, 4 = finished
|
|
};
|
|
|
|
class TMndxFindResult
|
|
{
|
|
public:
|
|
|
|
TMndxFindResult();
|
|
~TMndxFindResult();
|
|
|
|
int CreateStruct40();
|
|
void FreeStruct40();
|
|
|
|
int SetSearchPath(const char * szNewSearchPath, size_t cchNewSearchPath);
|
|
|
|
const char * szSearchMask; // Search mask without wioldcards
|
|
size_t cchSearchMask; // Length of the search mask
|
|
DWORD field_8;
|
|
const char * szFoundPath; // Found path name
|
|
size_t cchFoundPath; // Length of the found path name
|
|
DWORD FileNameIndex; // Index of the file name
|
|
TStruct40 * pStruct40;
|
|
};
|
|
|
|
class TSparseArray
|
|
{
|
|
public:
|
|
|
|
TSparseArray();
|
|
|
|
void ExchangeWith(TSparseArray & TargetObject);
|
|
int LoadFromStream(TByteStream & InStream);
|
|
int LoadFromStream_Exchange(TByteStream & InStream);
|
|
|
|
// Returns true if the item at n-th position is present
|
|
DWORD IsItemPresent(DWORD ItemIndex)
|
|
{
|
|
return (ItemBits.Uint32Array[ItemIndex >> 0x05] & (1 << (ItemIndex & 0x1F)));
|
|
}
|
|
|
|
DWORD GetItemValue(DWORD ItemIndex);
|
|
|
|
TGenericArray ItemBits; // Bit array for each item (1 = item is present)
|
|
DWORD TotalItemCount; // Total number of items in the array
|
|
DWORD ValidItemCount; // Number of present items in the array
|
|
TGenericArray BaseValues; // Array of base values for item indexes >= 0x200
|
|
TGenericArray ArrayDwords_38;
|
|
TGenericArray ArrayDwords_50;
|
|
};
|
|
|
|
class TNameIndexStruct
|
|
{
|
|
public:
|
|
|
|
TNameIndexStruct();
|
|
~TNameIndexStruct();
|
|
|
|
bool CheckNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
|
bool CheckAndCopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
|
void CopyNameFragment(TMndxFindResult * pStruct1C, DWORD dwFragOffs);
|
|
|
|
void ExchangeWith(TNameIndexStruct & Target);
|
|
int LoadFromStream(TByteStream & InStream);
|
|
int LoadFromStream_Exchange(TByteStream & InStream);
|
|
|
|
TGenericArray NameFragments;
|
|
TSparseArray Struct68;
|
|
};
|
|
|
|
class TStruct10
|
|
{
|
|
public:
|
|
|
|
TStruct10();
|
|
|
|
void CopyFrom(TStruct10 & Target);
|
|
int sub_1956FD0(DWORD dwBitMask);
|
|
int sub_1957050(DWORD dwBitMask);
|
|
int sub_19572E0(DWORD dwBitMask);
|
|
int sub_1957800(DWORD dwBitMask);
|
|
|
|
DWORD field_0;
|
|
DWORD field_4;
|
|
DWORD field_8;
|
|
DWORD field_C;
|
|
};
|
|
|
|
class TFileNameDatabasePtr
|
|
{
|
|
public:
|
|
|
|
TFileNameDatabasePtr();
|
|
~TFileNameDatabasePtr();
|
|
|
|
int FindFileInDatabase(TMndxFindResult * pStruct1C);
|
|
int sub_1956CE0(TMndxFindResult * pStruct1C, bool * pbFindResult);
|
|
|
|
int GetFileNameCount(PDWORD PtrFileNameCount);
|
|
int CreateDatabase(LPBYTE pbMarData, DWORD cbMarData);
|
|
int SetDatabase(TFileNameDatabase * pNewDB);
|
|
|
|
TFileNameDatabase * pDB;
|
|
};
|
|
|
|
class TFileNameDatabase
|
|
{
|
|
public:
|
|
|
|
TFileNameDatabase();
|
|
|
|
void ExchangeWith(TFileNameDatabase & Target);
|
|
int LoadFromStream(TByteStream & InStream);
|
|
int LoadFromStream_Exchange(TByteStream & InStream);
|
|
|
|
DWORD sub_1959CB0(DWORD dwHashValue);
|
|
DWORD sub_1959F50(DWORD arg_0);
|
|
|
|
// Retrieves the name fragment distance
|
|
// HOTS: 19573D0/inlined
|
|
DWORD GetNameFragmentOffsetEx(DWORD LoBitsIndex, DWORD HiBitsIndex)
|
|
{
|
|
return (FrgmDist_HiBits.GetBitEntry(HiBitsIndex) << 0x08) | FrgmDist_LoBits.ByteArray[LoBitsIndex];
|
|
}
|
|
|
|
// HOTS: 1957350, inlined
|
|
DWORD GetNameFragmentOffset(DWORD LoBitsIndex)
|
|
{
|
|
return GetNameFragmentOffsetEx(LoBitsIndex, Struct68_D0.GetItemValue(LoBitsIndex));
|
|
}
|
|
|
|
bool sub_1957B80(TMndxFindResult * pStruct1C, DWORD dwKey);
|
|
bool CheckNextPathFragment(TMndxFindResult * pStruct1C);
|
|
bool FindFileInDatabase(TMndxFindResult * pStruct1C);
|
|
|
|
void sub_1958D70(TMndxFindResult * pStruct1C, DWORD arg_4);
|
|
bool sub_1959010(TMndxFindResult * pStruct1C, DWORD arg_4);
|
|
bool sub_1958B00(TMndxFindResult * pStruct1C);
|
|
bool sub_1959460(TMndxFindResult * pStruct1C);
|
|
|
|
TSparseArray Struct68_00;
|
|
TSparseArray FileNameIndexes; // Array of file name indexes
|
|
TSparseArray Struct68_D0;
|
|
|
|
// This pair of arrays serves for fast conversion from name hash to fragment offset
|
|
TGenericArray FrgmDist_LoBits; // Array of lower 8 bits of name fragment offset
|
|
TBitEntryArray FrgmDist_HiBits; // Array of upper x bits of name fragment offset
|
|
|
|
TNameIndexStruct IndexStruct_174;
|
|
TFileNameDatabasePtr NextDB;
|
|
|
|
TGenericArray NameFragTable;
|
|
|
|
DWORD NameFragIndexMask;
|
|
DWORD field_214;
|
|
TStruct10 Struct10;
|
|
TByteStream MarStream;
|
|
};
|
|
|
|
typedef struct _MAR_FILE
|
|
{
|
|
TFileNameDatabasePtr * pDatabasePtr;
|
|
LPBYTE pbMarData;
|
|
DWORD cbMarData;
|
|
} MAR_FILE, *PMAR_FILE;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Macros
|
|
|
|
// Returns nonzero if the name fragment match is a single-char match
|
|
inline bool IS_SINGLE_CHAR_MATCH(TGenericArray & Table, DWORD ItemIndex)
|
|
{
|
|
return ((Table.NameFragArray[ItemIndex].FragOffs & 0xFFFFFF00) == 0xFFFFFF00);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CASC functions related to MNDX
|
|
|
|
int LoadMndxRootFile(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile);
|
|
PCASC_PACKAGE FindMndxPackage(TCascStorage * hs, const char * szFileName);
|
|
int SearchMndxInfo(PCASC_MNDX_INFO pMndxInfo, const char * szFileName, DWORD dwPackage, PCASC_ROOT_ENTRY_MNDX * ppFoundInfo);
|
|
bool DoStorageSearch_MNDX(TCascSearch * pSearch, PCASC_FIND_DATA pFindData);
|
|
void FreeMndxInfo(PCASC_MNDX_INFO pMndxInfo);
|
|
|
|
#endif // __CASC_MNDX_ROOT__
|