GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/mapdb.cpp Lines: 5 108 4.6 %
Date: 2021-03-17 Branches: 2 176 1.1 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Aethyra Development Team
4
 *  Copyright (C) 2011-2019  The ManaPlus Developers
5
 *  Copyright (C) 2019-2021  Andrei Karas
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "resources/db/mapdb.h"
24
25
#include "configuration.h"
26
#include "logger.h"
27
28
#include "resources/beingcommon.h"
29
30
#include "debug.h"
31
32
namespace
33
{
34
    bool mLoaded = false;
35
1
    MapDB::Maps mMaps;
36
1
    MapDB::MapInfos mInfos;
37
1
    MapDB::Atlases mAtlases;
38
1
    std::set<std::string> mEmptyTilesets;
39
}  // namespace
40
41
namespace MapDB
42
{
43
    void readMap(XmlNodePtrConst node);
44
    void readAtlas(XmlNodePtrConst node);
45
}  // namespace MapDB
46
47
void MapDB::load()
48
{
49
    if (mLoaded)
50
        unload();
51
52
    logger->log1("Initializing maps database...");
53
    loadRemapXmlFile(paths.getStringValue("mapsRemapFile"),
54
        SkipError_true);
55
    loadRemapXmlFile(paths.getStringValue("mapsRemapPatchFile"),
56
        SkipError_true);
57
    loadXmlDir("mapsRemapPatchDir", loadRemapXmlFile)
58
59
    loadInfo(paths.getStringValue("mapsFile"), SkipError_false);
60
    loadInfo(paths.getStringValue("mapsPatchFile"), SkipError_true);
61
    loadXmlDir("mapsPatchDir", loadInfo)
62
    mLoaded = true;
63
}
64
65
void MapDB::loadRemapXmlFile(const std::string &fileName,
66
                             const SkipError skipError)
67
{
68
    XML::Document *const doc = new XML::Document(fileName,
69
        UseVirtFs_true,
70
        skipError);
71
72
    XmlNodeConstPtrConst root = doc->rootNode();
73
    if (root == nullptr)
74
    {
75
        delete doc;
76
        return;
77
    }
78
79
    for_each_xml_child_node(node, root)
80
    {
81
        if (xmlNameEqual(node, "map"))
82
        {
83
            const std::string name = XML::getProperty(node, "name", "");
84
            if (name.empty())
85
                continue;
86
87
            const std::string value = XML::getProperty(node, "value", "");
88
            if (value.empty())
89
                continue;
90
91
            mMaps[name] = value;
92
        }
93
        else if (xmlNameEqual(node, "include"))
94
        {
95
            const std::string name = XML::getProperty(node, "name", "");
96
            if (!name.empty())
97
                loadRemapXmlFile(name, skipError);
98
            continue;
99
        }
100
    }
101
102
    delete doc;
103
}
104
105
void MapDB::readMap(XmlNodePtrConst node)
106
{
107
    if (node == nullptr)
108
        return;
109
    const std::string map = XML::getProperty(node, "name", "");
110
    if (map.empty())
111
        return;
112
113
    for_each_xml_child_node(childNode, node)
114
    {
115
        if (xmlNameEqual(childNode, "atlas"))
116
        {
117
            const std::string atlas = XML::getProperty(childNode, "name", "");
118
            if (atlas.empty())
119
                continue;
120
            mInfos[map].atlas = atlas;
121
        }
122
    }
123
}
124
125
void MapDB::readAtlas(XmlNodePtrConst node)
126
{
127
    if (node == nullptr)
128
        return;
129
    const std::string atlas = XML::getProperty(node, "name", "");
130
    if (atlas.empty())
131
        return;
132
    for_each_xml_child_node(childNode, node)
133
    {
134
        if (xmlNameEqual(childNode, "file"))
135
        {
136
            const std::string file = XML::getProperty(childNode, "name", "");
137
            if (file.empty())
138
                continue;
139
            mAtlases[atlas].push_back(file);
140
        }
141
    }
142
    if (atlas == paths.getStringValue("emptyAtlasName"))
143
    {
144
        const StringVect *files = &mAtlases[atlas];
145
        FOR_EACHP (StringVectCIter, it, files)
146
        {
147
            mEmptyTilesets.insert(*it);
148
            logger->log("empty tileset: " + *it);
149
        }
150
    }
151
    else if (atlas != "all")
152
    {
153
        const AtlasCIter &allAtlas = mAtlases.find("all");
154
        if (allAtlas != mAtlases.end())
155
        {
156
            FOR_EACH (StringVectCIter, it, (*allAtlas).second)
157
                mAtlases[atlas].push_back(*it);
158
        }
159
    }
160
}
161
162
void MapDB::loadInfo(const std::string &fileName,
163
                     const SkipError skipError)
164
{
165
    XML::Document *doc = new XML::Document(fileName,
166
        UseVirtFs_true,
167
        skipError);
168
    XmlNodeConstPtrConst root = doc->rootNode();
169
    if (root == nullptr)
170
    {
171
        delete doc;
172
        return;
173
    }
174
175
    for_each_xml_child_node(node, root)
176
    {
177
        if (xmlNameEqual(node, "map"))
178
        {
179
            readMap(node);
180
        }
181
        else if (xmlNameEqual(node, "atlas"))
182
        {
183
            readAtlas(node);
184
        }
185
        else if (xmlNameEqual(node, "include"))
186
        {
187
            const std::string name = XML::getProperty(node, "name", "");
188
            if (!name.empty())
189
                loadInfo(name, skipError);
190
            continue;
191
        }
192
    }
193
    delete doc;
194
}
195
196
void MapDB::unload()
197
{
198
    logger->log1("Unloading map database...");
199
200
    mMaps.clear();
201
    mLoaded = false;
202
}
203
204
const std::string MapDB::getMapName(const std::string &name)
205
{
206
    const MapIterator it = mMaps.find(name);
207
208
    if (it != mMaps.end())
209
        return it->second;
210
    return name;
211
}
212
213
const MapInfo *MapDB::getMapAtlas(const std::string &name)
214
{
215
    const MapInfoIter it = mInfos.find(name);
216
    if (it == mInfos.end())
217
        return nullptr;
218
    MapInfo *const info = &(*it).second;
219
    const AtlasCIter it2 = mAtlases.find(info->atlas);
220
    if (it2 == mAtlases.end())
221
        return nullptr;
222
    info->files = &((*it2).second);
223
    return info;
224
}
225
226
const MapInfo *MapDB::getAtlas(const std::string &name)
227
{
228
    const AtlasCIter it = mAtlases.find(name);
229
    if (it == mAtlases.end())
230
        return nullptr;
231
232
    MapInfo *const info = new MapInfo;
233
    info->atlas = name;
234
    info->files = &(*it).second;
235
    return info;
236
}
237
238
bool MapDB::isEmptyTileset(const std::string &name)
239
{
240
    return mEmptyTilesets.find(name) != mEmptyTilesets.end();
241

3
}