Add config_store and config_retrieve tool

This commit is contained in:
heinrich5991 2015-08-21 23:02:50 +02:00
parent db696c0e78
commit d13ebf93a2
8 changed files with 257 additions and 12 deletions

View file

@ -452,13 +452,16 @@ CDataFileWriter::~CDataFileWriter()
m_pDatas = 0;
}
bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename)
bool CDataFileWriter::OpenFile(class IStorage *pStorage, const char *pFilename)
{
dbg_assert(!m_File, "a file already exists");
m_File = pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
if(!m_File)
return false;
return m_File != 0;
}
void CDataFileWriter::Init()
{
dbg_assert(!m_File, "a file already exists");
m_NumItems = 0;
m_NumDatas = 0;
m_NumItemTypes = 0;
@ -469,8 +472,12 @@ bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename)
m_pItemTypes[i].m_First = -1;
m_pItemTypes[i].m_Last = -1;
}
}
return true;
bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename)
{
Init();
return OpenFile(pStorage, pFilename);
}
int CDataFileWriter::AddItem(int Type, int ID, int Size, void *pData)

View file

@ -80,6 +80,8 @@ class CDataFileWriter
public:
CDataFileWriter();
~CDataFileWriter();
void Init();
bool OpenFile(class IStorage *pStorage, const char *pFilename);
bool Open(class IStorage *pStorage, const char *Filename);
int AddData(int Size, void *pData);
int AddDataSwapped(int Size, void *pData);

View file

@ -433,3 +433,13 @@ public:
};
IStorage *CreateStorage(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments) { return CStorage::Create(pApplicationName, StorageType, NumArgs, ppArguments); }
IStorage *CreateLocalStorage()
{
CStorage *pStorage = new CStorage();
if(pStorage)
{
pStorage->AddPath("$CURRENTDIR");
}
return pStorage;
}

View file

@ -33,6 +33,7 @@ public:
};
extern IStorage *CreateStorage(const char *pApplicationName, int StorageType, int NumArgs, const char **ppArguments);
extern IStorage *CreateLocalStorage();
#endif

View file

@ -2534,7 +2534,7 @@ void CGameContext::OnMapChange(char *pNewMapName, int MapNameSize)
char aConfig[128];
char aTemp[128];
str_format(aConfig, sizeof(aConfig), "maps/%s.cfg", g_Config.m_SvMap);
str_format(aTemp, sizeof(aTemp), "%s.temp.%d", pNewMapName, pid(), pNewMapName);
str_format(aTemp, sizeof(aTemp), "%s.temp.%d", pNewMapName, pid());
IOHANDLE File = pStorage->OpenFile(aConfig, IOFLAG_READ, IStorage::TYPE_ALL);
if(!File)
@ -2587,15 +2587,25 @@ void CGameContext::OnMapChange(char *pNewMapName, int MapNameSize)
CMapItemInfoSettings *pInfo = (CMapItemInfoSettings *)pData;
if(Size >= (int)sizeof(CMapItemInfoSettings))
{
SettingsIndex = pInfo->m_Settings;
char *pMapSettings = (char *)Reader.GetData(SettingsIndex);
int DataSize = Reader.GetUncompressedDataSize(SettingsIndex);
if(DataSize == TotalLength && mem_comp(pSettings, pMapSettings, Size) == 0)
if(pInfo->m_Settings > -1)
{
// Configs coincide, no need to update map.
return;
SettingsIndex = pInfo->m_Settings;
char *pMapSettings = (char *)Reader.GetData(SettingsIndex);
int DataSize = Reader.GetUncompressedDataSize(SettingsIndex);
if(DataSize == TotalLength && mem_comp(pSettings, pMapSettings, Size) == 0)
{
// Configs coincide, no need to update map.
return;
}
Reader.UnloadData(pInfo->m_Settings);
}
else
{
MapInfo = *pInfo;
MapInfo.m_Settings = SettingsIndex;
pData = (int *)&MapInfo;
Size = sizeof(MapInfo);
}
Reader.UnloadData(pInfo->m_Settings);
}
else
{
@ -2668,6 +2678,7 @@ void CGameContext::LoadMapSettings()
pNext += StrSize;
}
pMap->UnloadData(pItem->m_Settings);
break;
}
char aBuf[128];

37
src/tools/config_common.h Normal file
View file

@ -0,0 +1,37 @@
#include <base/system.h>
#include <engine/storage.h>
int main(int argc, const char **argv)
{
dbg_logger_stdout();
IStorage *pStorage = CreateLocalStorage();
if(argc == 1)
{
dbg_msg("Usage", "%s FILE1 [ FILE2... ]", argv[0]);
return -1;
}
for(int i = 1; i < argc; i++)
{
char aConfig[2048];
size_t Len = str_length(argv[i]) + 1; // including '\0'
if(Len > sizeof(aConfig))
{
dbg_msg("config_common", "can't process overlong filename '%s'", argv[i]);
continue;
}
if(Len < sizeof(".map") || str_comp(argv[i] + Len - sizeof(".map"), ".map") != 0)
{
dbg_msg("config_common", "can't process non-map file '%s'", argv[i]);
continue;
}
str_copy(aConfig, argv[i], sizeof(aConfig));
aConfig[Len - sizeof(".map")] = 0;
str_append(aConfig, ".cfg", sizeof(aConfig));
dbg_msg("config_common", "processing '%s'", argv[i]);
Process(pStorage, argv[i], aConfig);
}
return 0;
}

View file

@ -0,0 +1,58 @@
#include <base/system.h>
#include <engine/shared/datafile.h>
#include <engine/storage.h>
#include <game/mapitems.h>
void Process(IStorage *pStorage, const char *pMapName, const char *pConfigName)
{
CDataFileReader Map;
if(!Map.Open(pStorage, pMapName, 2))
{
dbg_msg("config_retrieve", "error opening map '%s'", pMapName);
return;
}
bool ConfigFound = false;
int Start, Num;
Map.GetType(MAPITEMTYPE_INFO, &Start, &Num);
for(int i = Start; i < Start + Num; i++)
{
int ItemID;
CMapItemInfoSettings *pItem = (CMapItemInfoSettings *)Map.GetItem(i, 0, &ItemID);
int ItemSize = Map.GetItemSize(i) - 8;
if(!pItem || ItemID != 0)
continue;
if(ItemSize < (int)sizeof(CMapItemInfoSettings))
break;
if(!(pItem->m_Settings > -1))
break;
ConfigFound = true;
IOHANDLE Config = io_open(pConfigName, IOFLAG_WRITE);
if(!Config)
{
dbg_msg("config_retrieve", "error opening config for writing '%s'", pConfigName);
return;
}
int Size = Map.GetUncompressedDataSize(pItem->m_Settings);
char *pSettings = (char *)Map.GetData(pItem->m_Settings);
char *pNext = pSettings;
while(pNext < pSettings + Size)
{
int StrSize = str_length(pNext) + 1;
io_write(Config, pNext, StrSize - 1);
io_write_newline(Config);
pNext += StrSize;
}
Map.UnloadData(pItem->m_Settings);
io_close(Config);
break;
}
Map.Close();
if(!ConfigFound)
{
fs_remove(pConfigName);
}
}
#include "config_common.h"

119
src/tools/config_store.cpp Normal file
View file

@ -0,0 +1,119 @@
#include <base/system.h>
#include <base/tl/array.h>
#include <engine/shared/datafile.h>
#include <engine/shared/linereader.h>
#include <engine/storage.h>
#include <game/mapitems.h>
void Process(IStorage *pStorage, const char *pMapName, const char *pConfigName)
{
IOHANDLE File = pStorage->OpenFile(pConfigName, IOFLAG_READ, IStorage::TYPE_ALL);
array<char *> aLines;
char *pSettings = NULL;
if(!File)
{
dbg_msg("config_store", "config '%s' not found", pConfigName);
return;
}
CLineReader LineReader;
LineReader.Init(File);
char *pLine;
int TotalLength = 0;
while((pLine = LineReader.Get()))
{
int Length = str_length(pLine) + 1;
char *pCopy = (char *)mem_alloc(Length, 1);
mem_copy(pCopy, pLine, Length);
aLines.add(pCopy);
TotalLength += Length;
}
pSettings = (char *)mem_alloc(TotalLength, 1);
int Offset = 0;
for(int i = 0; i < aLines.size(); i++)
{
int Length = str_length(aLines[i]) + 1;
mem_copy(pSettings + Offset, aLines[i], Length);
Offset += Length;
mem_free(aLines[i]);
}
CDataFileReader Reader;
Reader.Open(pStorage, pMapName, IStorage::TYPE_ALL);
CDataFileWriter Writer;
Writer.Init();
int SettingsIndex = Reader.NumData();
for(int i = 0; i < Reader.NumItems(); i++)
{
int TypeID;
int ItemID;
int *pData = (int *)Reader.GetItem(i, &TypeID, &ItemID);
// GetItemSize returns item size including header, remove that.
int Size = Reader.GetItemSize(i) - sizeof(int) * 2;
CMapItemInfoSettings MapInfo;
if(TypeID == MAPITEMTYPE_INFO && ItemID == 0)
{
CMapItemInfoSettings *pInfo = (CMapItemInfoSettings *)pData;
if(Size >= (int)sizeof(CMapItemInfoSettings))
{
MapInfo = *pInfo;
pData = (int *)&MapInfo;
Size = sizeof(MapInfo);
if(pInfo->m_Settings > -1)
{
SettingsIndex = pInfo->m_Settings;
char *pMapSettings = (char *)Reader.GetData(SettingsIndex);
int DataSize = Reader.GetUncompressedDataSize(SettingsIndex);
if(DataSize == TotalLength && mem_comp(pSettings, pMapSettings, Size) == 0)
{
dbg_msg("config_store", "configs coincide, not updating map");
return;
}
Reader.UnloadData(pInfo->m_Settings);
}
else
{
MapInfo = *pInfo;
MapInfo.m_Settings = SettingsIndex;
pData = (int *)&MapInfo;
Size = sizeof(MapInfo);
}
}
else
{
*(CMapItemInfo *)&MapInfo = *(CMapItemInfo *)pInfo;
MapInfo.m_Settings = SettingsIndex;
pData = (int *)&MapInfo;
Size = sizeof(MapInfo);
}
}
Writer.AddItem(TypeID, ItemID, Size, pData);
}
for(int i = 0; i < Reader.NumData() || i == SettingsIndex; i++)
{
if(i == SettingsIndex)
{
Writer.AddData(TotalLength, pSettings);
continue;
}
unsigned char *pData = (unsigned char *)Reader.GetData(i);
int Size = Reader.GetUncompressedDataSize(i);
Writer.AddData(Size, pData);
Reader.UnloadData(i);
}
Reader.Close();
if(!Writer.Open(pStorage, pMapName))
{
dbg_msg("config_store", "couldn't open map file '%s' for writing", pMapName);
return;
}
Writer.Finish();
dbg_msg("config_store", "imported settings");
}
#include "config_common.h"