/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include
#include
#include
#include
#include "datafile.h"
#include "memheap.h"
#include "mapchecker.h"
CMapChecker::CMapChecker()
{
Init();
SetDefaults();
}
void CMapChecker::Init()
{
m_Whitelist.Reset();
m_pFirst = 0;
m_RemoveDefaultList = false;
}
void CMapChecker::SetDefaults()
{
AddMaplist(s_aMapVersionList, s_NumMapVersionItems);
m_RemoveDefaultList = true;
}
void CMapChecker::AddMaplist(CMapVersion *pMaplist, int Num)
{
if(m_RemoveDefaultList)
Init();
for(int i = 0; i < Num; ++i)
{
CWhitelistEntry *pEntry = (CWhitelistEntry *)m_Whitelist.Allocate(sizeof(CWhitelistEntry));
pEntry->m_pNext = m_pFirst;
m_pFirst = pEntry;
str_copy(pEntry->m_aMapName, pMaplist[i].m_aName, sizeof(pEntry->m_aMapName));
pEntry->m_MapCrc = (pMaplist[i].m_aCrc[0]<<24) | (pMaplist[i].m_aCrc[1]<<16) | (pMaplist[i].m_aCrc[2]<<8) | pMaplist[i].m_aCrc[3];
pEntry->m_MapSize = (pMaplist[i].m_aSize[0]<<24) | (pMaplist[i].m_aSize[1]<<16) | (pMaplist[i].m_aSize[2]<<8) | pMaplist[i].m_aSize[3];
}
}
bool CMapChecker::IsMapValid(const char *pMapName, unsigned MapCrc, unsigned MapSize)
{
bool StandardMap = false;
for(CWhitelistEntry *pCurrent = m_pFirst; pCurrent; pCurrent = pCurrent->m_pNext)
{
if(str_comp(pCurrent->m_aMapName, pMapName) == 0)
{
StandardMap = true;
if(pCurrent->m_MapCrc == MapCrc && pCurrent->m_MapSize == MapSize)
return true;
}
}
return StandardMap?false:true;
}
bool CMapChecker::ReadAndValidateMap(IStorage *pStorage, const char *pFilename, int StorageType)
{
bool LoadedMapInfo = false;
bool StandardMap = false;
unsigned MapCrc = 0;
unsigned MapSize = 0;
// extract map name
char aMapName[MAX_MAP_LENGTH];
const char *pExtractedName = pFilename;
const char *pEnd = 0;
for(const char *pSrc = pFilename; *pSrc; ++pSrc)
{
if(*pSrc == '/' || *pSrc == '\\')
pExtractedName = pSrc+1;
else if(*pSrc == '.')
pEnd = pSrc;
}
int Length = (int)(pEnd - pExtractedName);
if(Length <= 0 || Length >= MAX_MAP_LENGTH)
return true;
str_copy(aMapName, pExtractedName, min((int)MAX_MAP_LENGTH, (int)(pEnd-pExtractedName+1)));
// check for valid map
for(CWhitelistEntry *pCurrent = m_pFirst; pCurrent; pCurrent = pCurrent->m_pNext)
{
if(str_comp(pCurrent->m_aMapName, aMapName) == 0)
{
StandardMap = true;
if(!LoadedMapInfo)
{
if(!CDataFileReader::GetCrcSize(pStorage, pFilename, StorageType, &MapCrc, &MapSize))
return true;
LoadedMapInfo = true;
}
if(pCurrent->m_MapCrc == MapCrc && pCurrent->m_MapSize == MapSize)
return true;
}
}
return StandardMap?false:true;
}