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