mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58: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) {}
|
m_pDataFile(nullptr) {}
|
||||||
~CDataFileReader() { Close(); }
|
~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 Open(class IStorage *pStorage, const char *pFilename, int StorageType);
|
||||||
bool Close();
|
bool Close();
|
||||||
bool IsOpen() const { return m_pDataFile != nullptr; }
|
bool IsOpen() const { return m_pDataFile != nullptr; }
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
#include <base/log.h>
|
||||||
|
|
||||||
#include <engine/storage.h>
|
#include <engine/storage.h>
|
||||||
|
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
|
@ -63,23 +65,32 @@ bool CMap::Load(const char *pMapName)
|
||||||
IStorage *pStorage = Kernel()->RequestInterface<IStorage>();
|
IStorage *pStorage = Kernel()->RequestInterface<IStorage>();
|
||||||
if(!pStorage)
|
if(!pStorage)
|
||||||
return false;
|
return false;
|
||||||
if(!m_DataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL))
|
|
||||||
return false;
|
// Ensure current datafile is not left in an inconsistent state if loading fails,
|
||||||
// check version
|
// by loading the new datafile separately first.
|
||||||
const CMapItemVersion *pItem = (CMapItemVersion *)m_DataFile.FindItem(MAPITEMTYPE_VERSION, 0);
|
CDataFileReader NewDataFile;
|
||||||
if(!pItem || pItem->m_Version != CMapItemVersion::CURRENT_VERSION)
|
if(!NewDataFile.Open(pStorage, pMapName, IStorage::TYPE_ALL))
|
||||||
return false;
|
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;
|
int GroupsStart, GroupsNum, LayersStart, LayersNum;
|
||||||
m_DataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum);
|
NewDataFile.GetType(MAPITEMTYPE_GROUP, &GroupsStart, &GroupsNum);
|
||||||
m_DataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum);
|
NewDataFile.GetType(MAPITEMTYPE_LAYER, &LayersStart, &LayersNum);
|
||||||
for(int g = 0; g < GroupsNum; g++)
|
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++)
|
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)
|
if(pLayer->m_Type == LAYERTYPE_TILES)
|
||||||
{
|
{
|
||||||
CMapItemLayerTilemap *pTilemap = reinterpret_cast<CMapItemLayerTilemap *>(pLayer);
|
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);
|
const size_t TilemapSize = (size_t)pTilemap->m_Width * pTilemap->m_Height * sizeof(CTile);
|
||||||
CTile *pTiles = static_cast<CTile *>(malloc(TilemapSize));
|
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));
|
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));
|
||||||
m_DataFile.ReplaceData(pTilemap->m_Data, reinterpret_cast<char *>(pTiles), TilemapSize);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7907,7 +7907,6 @@ bool CEditor::Load(const char *pFileName, int StorageType)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_aFileName[0] = 0;
|
m_aFileName[0] = 0;
|
||||||
Reset();
|
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue