Add infos into target window
[ryzomcore.git] / ryzom / server / src / server_share / primitive_cfg.cpp
blob9a7362e03e02af2b155defbf0434dfdffb86f356
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "stdpch.h"
20 #include "primitive_cfg.h"
21 #include "nel/misc/config_file.h"
22 #include "nel/misc/path.h"
24 using namespace NLMISC;
25 using namespace std;
27 // std::vector<std::string> CPrimitiveCfg::_AllPrimitives;
28 std::vector<std::string> CPrimitiveCfg::_MapNames;
29 std::map<std::string, std::vector<std::string> > CPrimitiveCfg::_Maps;
30 std::map<std::string, std::vector<std::string> > CPrimitiveCfg::_ContinentFiles;
32 void CPrimitiveCfg::addPrimitive(std::vector<std::string> &vectorlist, const std::string &str)
34 for (uint32 i=0;i<vectorlist.size();i++)
35 if (vectorlist[i]==str)
36 return;
38 vectorlist.push_back(str);
42 std::string CPrimitiveCfg::getContinentNameOf(const std::string &fileName)
44 CPrimitiveCfg::readPrimitiveCfg();
45 string name = CFile::getFilename(fileName);
47 std::map<std::string, std::vector<std::string> >::iterator first(_ContinentFiles.begin()), last(_ContinentFiles.end());
48 for (; first != last; ++first)
49 if (find(first->second.begin(),first->second.end(), name) != first->second.end())
50 return first->first;
52 return std::string();
55 // dumb routine to simplify repetitive text parsing code
56 inline bool isWhiteSpace(char c)
58 return (c==' ' || c=='\t');
61 // -- stringToWordAndTail() --
62 // The following routine splits a text string into a keyword and a tail.
63 // A white space is used as separator between keyword and tail
64 // All leading and trailing ' ' and '\t' round keyword and tail characters are stripped
65 // If no keyword is found routine retuns false (keyword and tail retain previous content)
66 inline bool stringToWordAndTail(const std::string &input,std::string &word, std::string &tail)
68 uint i=0, j;
70 // skip white space
71 while (i<input.size() && isWhiteSpace(input[i])) ++i; // i points to start of word
73 // look for the end of the word
74 for (j=i;j<input.size() && !isWhiteSpace(input[j]);) ++j; // j points to next character after word
76 // if no word found then give up
77 if (j==i) return false;
79 // copy out the word
80 word=input.substr(i,j-i);
82 // find the end of the tail text
83 for (i=(uint)input.size();i>j && isWhiteSpace(input[i-1]);) --i; // i points to character after end of tail text
85 // find start of tail text
86 do { ++j; } while(j<i && isWhiteSpace(input[j])); // j points to start of tail text
88 // copy out the tail (or clear if no tail found in input)
89 if (j<i)
90 tail=input.substr(j,i-j);
91 else
92 tail.clear();
94 return true;
97 void CPrimitiveCfg::readPrimitiveCfg(bool forceReload)
99 if ( !forceReload
100 && !_MapNames.empty())
101 return;
103 // _AllPrimitives.clear();
104 _MapNames.clear();
105 _Maps.clear();
107 std::string filename = CPath::lookup("primitives.cfg");
108 if (filename.empty())
110 nlwarning("Can't find the primitive configuration file 'primitives.cfg'");
111 return;
116 CConfigFile cfg;
117 cfg.load(filename.c_str());
119 CConfigFile::CVar var = cfg.getVar("PrimitiveFiles");
121 std::vector<std::string> CurrentMapNames;
122 set<string> mapNames;
124 std::vector<std::string> *_CurrentContinentFiles=NULL;
126 for (uint32 i=0;i<var.size();++i)
128 // uint32 j,k;
130 // get the next string from the config file entry and make sure its not empty
131 const std::string s=var.asString(i);
133 std::string keyword;
134 std::string tail;
136 if (s.empty())
137 continue;
138 stringToWordAndTail(s, keyword, tail);
142 // // skip opening white space and make sure there's not just white space
143 // for (j=0;j<s.size() && (s[j]==' ' || s[j]=='\t');++j);
144 // if (j>=s.size())
145 // continue;
146 // // separate the first word (we need it to know what to do next)
147 // for (k=j;k<s.size() && s[k]!=' ' && s[k]!='\t';++k);
148 // std::string keyword=s.substr(j,k-j);
150 // // separate out the tail, pruning trailing blanks
151 // // ignore leading blanks
152 // for (j=k;j<s.size() && (s[j]==' ' || s[j]=='\t');++j);
153 // // ignore trailing spaces
154 // for (k=s.size()-1;s[k]==' '||s[k]=='\t';--k);
155 // // if we found some non-blank text take a copy in a 'tail' variable
156 // std::string tail;
157 // if (k>=j) tail=s.substr(j,k-j+1);
160 // do something depending on the keyword found earlier
161 if (nlstricmp(keyword,"MAPEND")==0)
163 // remove the last map entry
164 CurrentMapNames.pop_back();
166 else if (nlstricmp(keyword,"CONTINENT")==0)
168 _CurrentContinentFiles=&_ContinentFiles[tail];
170 else if (nlstricmp(keyword,"MAP")==0)
172 // store the map name for use later
173 CurrentMapNames.push_back(tail);
174 mapNames.insert(tail);
175 _Maps.insert(make_pair(tail, vector<string>()));
176 if (_CurrentContinentFiles)
177 addPrimitive(*_CurrentContinentFiles, tail); // bad but not too ..
179 else if (nlstricmp(keyword,"FILE")==0)
181 // if our file name is > 0 characters long then add it to the vector
182 // if (j<=k)
184 string filename = tail; //s.substr(j,k-j+1);
185 if (CFile::getExtension(filename).empty())
186 filename+=".primitive";
188 for (uint32 mapInd=0;mapInd<CurrentMapNames.size();mapInd++)
189 addPrimitive(_Maps[CurrentMapNames[mapInd]], filename);
191 if (_CurrentContinentFiles)
192 addPrimitive(*_CurrentContinentFiles, filename);
193 // else
194 // nlwarning("Not Continents specified for %s",filename.c_str());
198 else if (nlstricmp(keyword,"INCLUDE")==0)
200 // if our file name is > 0 characters long then add it to the vector
201 // if (j<=k)
203 string includeName = tail; //s.substr(j,k-j+1);
205 if (_Maps.find(includeName)==_Maps.end())
207 nlwarning("PrimitiveCfg: Include %s failed, not defined.",includeName.c_str());
209 else
211 std::vector<std::string> &vectorlist=_Maps[includeName];
212 for (uint32 primInd=0;primInd<vectorlist.size();primInd++)
214 const string &primitiveFileName=vectorlist[primInd];
216 for (uint32 mapInd=0;mapInd<CurrentMapNames.size();mapInd++)
217 addPrimitive(_Maps[CurrentMapNames[mapInd]], primitiveFileName);
218 if (_CurrentContinentFiles)
219 addPrimitive(*_CurrentContinentFiles, primitiveFileName);
220 else
221 nlwarning("Not Continents specified for %s",includeName.c_str());
229 else
230 nlwarning("Unknown keyword in PrimitiveFiles at line: '%s'",s.c_str());
232 // fill the maps names vector
233 _MapNames.insert(_MapNames.begin(), mapNames.begin(), mapNames.end());
235 catch(...)
237 nlwarning("Error reading or parsing the primitive configuration file '%s'", filename.c_str());