1#include <base/math.h>
2#include <base/system.h>
3#include <engine/shared/datafile.h>
4#include <engine/shared/linereader.h>
5#include <engine/storage.h>
6#include <game/mapitems.h>
7#include <vector>
8
9void Process(IStorage *pStorage, const char *pMapName, const char *pConfigName)
10{
11 CLineReader LineReader;
12 if(!LineReader.OpenFile(File: pStorage->OpenFile(pFilename: pConfigName, Flags: IOFLAG_READ, Type: IStorage::TYPE_ABSOLUTE)))
13 {
14 dbg_msg(sys: "config_store", fmt: "config '%s' not found", pConfigName);
15 return;
16 }
17
18 std::vector<const char *> vpLines;
19 int TotalLength = 0;
20 while(const char *pLine = LineReader.Get())
21 {
22 vpLines.push_back(x: pLine);
23 TotalLength += str_length(str: pLine) + 1;
24 }
25
26 char *pSettings = (char *)malloc(size: maximum(a: 1, b: TotalLength));
27 int Offset = 0;
28 for(const char *pLine : vpLines)
29 {
30 int Length = str_length(str: pLine) + 1;
31 mem_copy(dest: pSettings + Offset, source: pLine, size: Length);
32 Offset += Length;
33 }
34
35 CDataFileReader Reader;
36 Reader.Open(pStorage, pFilename: pMapName, StorageType: IStorage::TYPE_ABSOLUTE);
37
38 CDataFileWriter Writer;
39
40 int SettingsIndex = Reader.NumData();
41 bool FoundInfo = false;
42 for(int i = 0; i < Reader.NumItems(); i++)
43 {
44 int Type, Id;
45 int *pItem = (int *)Reader.GetItem(Index: i, pType: &Type, pId: &Id);
46 int Size = Reader.GetItemSize(Index: i);
47 CMapItemInfoSettings MapInfo;
48 if(Type == MAPITEMTYPE_INFO && Id == 0)
49 {
50 FoundInfo = true;
51 CMapItemInfoSettings *pInfo = (CMapItemInfoSettings *)pItem;
52 if(Size >= (int)sizeof(CMapItemInfoSettings))
53 {
54 MapInfo = *pInfo;
55 pItem = (int *)&MapInfo;
56 Size = sizeof(MapInfo);
57 if(pInfo->m_Settings > -1)
58 {
59 SettingsIndex = pInfo->m_Settings;
60 char *pMapSettings = (char *)Reader.GetData(Index: SettingsIndex);
61 int DataSize = Reader.GetDataSize(Index: SettingsIndex);
62 if(DataSize == TotalLength && mem_comp(a: pSettings, b: pMapSettings, size: DataSize) == 0)
63 {
64 dbg_msg(sys: "config_store", fmt: "configs coincide, not updating map");
65 free(ptr: pSettings);
66 return;
67 }
68 Reader.UnloadData(Index: pInfo->m_Settings);
69 }
70 else
71 {
72 MapInfo = *pInfo;
73 MapInfo.m_Settings = SettingsIndex;
74 pItem = (int *)&MapInfo;
75 Size = sizeof(MapInfo);
76 }
77 }
78 else
79 {
80 *(CMapItemInfo *)&MapInfo = *(CMapItemInfo *)pInfo;
81 MapInfo.m_Settings = SettingsIndex;
82 pItem = (int *)&MapInfo;
83 Size = sizeof(MapInfo);
84 }
85 }
86 Writer.AddItem(Type, Id, Size, pData: pItem);
87 }
88
89 if(!FoundInfo)
90 {
91 CMapItemInfoSettings Info;
92 Info.m_Version = 1;
93 Info.m_Author = -1;
94 Info.m_MapVersion = -1;
95 Info.m_Credits = -1;
96 Info.m_License = -1;
97 Info.m_Settings = SettingsIndex;
98 Writer.AddItem(Type: MAPITEMTYPE_INFO, Id: 0, Size: sizeof(Info), pData: &Info);
99 }
100
101 for(int i = 0; i < Reader.NumData() || i == SettingsIndex; i++)
102 {
103 if(i == SettingsIndex)
104 {
105 Writer.AddData(Size: TotalLength, pData: pSettings);
106 continue;
107 }
108 unsigned char *pData = (unsigned char *)Reader.GetData(Index: i);
109 int Size = Reader.GetDataSize(Index: i);
110 Writer.AddData(Size, pData);
111 Reader.UnloadData(Index: i);
112 }
113
114 free(ptr: pSettings);
115 Reader.Close();
116 if(!Writer.Open(pStorage, pFilename: pMapName))
117 {
118 dbg_msg(sys: "config_store", fmt: "couldn't open map file '%s' for writing", pMapName);
119 return;
120 }
121 Writer.Finish();
122 dbg_msg(sys: "config_store", fmt: "imported settings");
123}
124#include "config_common.h"
125