mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
Merge pull request #7289 from Robyt3/Map-Version-Check
Ensure current map is not corrupted when loading another fails
This commit is contained in:
commit
dbd9da3c7b
|
@ -30,6 +30,13 @@ public:
|
|||
m_pDataFile(nullptr) {}
|
||||
~CDataFileReader() { Close(); }
|
||||
|
||||
CDataFileReader &operator=(CDataFileReader &&Other)
|
||||
{
|
||||
m_pDataFile = Other.m_pDataFile;
|
||||
Other.m_pDataFile = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Open(class IStorage *pStorage, const char *pFilename, int StorageType);
|
||||
bool Close();
|
||||
bool IsOpen() const { return m_pDataFile != nullptr; }
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#include "map.h"
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include <game/mapitems.h>
|
||||
|
@ -63,23 +65,32 @@ bool CMap::Load(const char *pMapName)
|
|||
IStorage *pStorage = Kernel()->RequestInterface<IStorage>();
|
||||
if(!pStorage)
|
||||
return false;
|
||||
if(!m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL))
|
||||
return false;
|
||||
// check version
|
||||
const CMapItemVersion *pItem = (CMapItemVersion *)m_DataFile.FindItem(MAPITEMTYPE_VERSION, 0);
|
||||
if(!pItem || pItem->m_Version != CMapItemVersion::CURRENT_VERSION)
|
||||
|
||||
// Ensure current datafile is not left in an inconsistent state if loading fails,
|
||||
// by loading the new datafile separately first.
|
||||
CDataFileReader NewDataFile;
|
||||
if(!NewDataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL))
|
||||
return false;
|
||||
|
||||
// replace compressed tile layers with uncompressed ones
|
||||
// Check version
|
||||
const CMapItemVersion *pItem = (CMapItemVersion *)NewDataFile.FindItem(MAPITEMTYPE_VERSION, 0);
|
||||
if(pItem == nullptr || pItem->m_Version != CMapItemVersion::CURRENT_VERSION)
|
||||
{
|
||||
log_error("map/load", "Error: map version not supported.");
|
||||
NewDataFile.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Replace compressed tile layers with uncompressed ones
|
||||
int GroupsStart, GroupsNum, LayersStart, LayersNum;
|
||||
m_DataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum);
|
||||
m_DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum);
|
||||
NewDataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum);
|
||||
NewDataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum);
|
||||
for(int g = 0; g < GroupsNum; g++)
|
||||
{
|
||||
const CMapItemGroup *pGroup = static_cast<CMapItemGroup *>(m_DataFile.GetItem(GroupsStart + g));
|
||||
const CMapItemGroup *pGroup = static_cast<CMapItemGroup *>(NewDataFile.GetItem(GroupsStart + g));
|
||||
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
||||
{
|
||||
CMapItemLayer *pLayer = static_cast<CMapItemLayer *>(m_DataFile.GetItem(LayersStart + pGroup->m_StartLayer + l));
|
||||
CMapItemLayer *pLayer = static_cast<CMapItemLayer *>(NewDataFile.GetItem(LayersStart + pGroup->m_StartLayer + l));
|
||||
if(pLayer->m_Type == LAYERTYPE_TILES)
|
||||
{
|
||||
CMapItemLayerTilemap *pTilemap = reinterpret_cast<CMapItemLayerTilemap *>(pLayer);
|
||||
|
@ -87,13 +98,16 @@ bool CMap::Load(const char *pMapName)
|
|||
{
|
||||
const size_t TilemapSize = (size_t)pTilemap->m_Width * pTilemap->m_Height * sizeof(CTile);
|
||||
CTile *pTiles = static_cast<CTile *>(malloc(TilemapSize));
|
||||
ExtractTiles(pTiles, (size_t)pTilemap->m_Width * pTilemap->m_Height, static_cast<CTile *>(m_DataFile.GetData(pTilemap->m_Data)), m_DataFile.GetDataSize(pTilemap->m_Data) / sizeof(CTile));
|
||||
m_DataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast<char *>(pTiles), TilemapSize);
|
||||
ExtractTiles(pTiles, (size_t)pTilemap->m_Width * pTilemap->m_Height, static_cast<CTile *>(NewDataFile.GetData(pTilemap->m_Data)), NewDataFile.GetDataSize(pTilemap->m_Data) / sizeof(CTile));
|
||||
NewDataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast<char *>(pTiles), TilemapSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace existing datafile with new datafile
|
||||
m_DataFile.Close();
|
||||
m_DataFile = std::move(NewDataFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7907,7 +7907,6 @@ bool CEditor::Load(const char *pFileName, int StorageType)
|
|||
else
|
||||
{
|
||||
m_aFileName[0] = 0;
|
||||
Reset();
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue