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 | 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 | |