initial commit, lordsawar source, slightly modified
[lordsawar] / src / Configuration.cpp
1 //  Copyright (C) 2002, 2003 Michael Bartl
2 //  Copyright (C) 2003, 2004, 2005, 2006 Ulf Lorenz
3 //  Copyright (C) 2004, 2005, 2006 Andrea Paternesi
4 //  Copyright (C) 2005 Josef Spillner
5 //  Copyright (C) 2006, 2007, 2008 Ben Asselstine
6 //  Copyright (C) 2007 Ole Laursen
7 //
8 //  This program is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License as published by
10 //  the Free Software Foundation; either version 3 of the License, or
11 //  (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU Library General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
21 //  02110-1301, USA.
22
23 #include <stdlib.h>
24 #include <fstream>
25 #include <iostream>
26 #include <sys/stat.h>
27 #include <sigc++/functors/mem_fun.h>
28
29 #include "Configuration.h"
30
31 #include "xmlhelper.h"
32 #include "defs.h"
33 #include "File.h"
34
35 using namespace std;
36
37 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
38 #define debug(x)
39
40 // define static variables
41
42 bool Configuration::s_showNextPlayer = true;
43 #ifndef __WIN32__
44 string Configuration::configuration_file_path = string(getenv("HOME")) + "/.lordsawarrc";
45 string Configuration::s_dataPath = LORDSAWAR_DATADIR;
46 string Configuration::s_savePath = string(getenv("HOME"))+string("/.lordsawar/");
47 #else
48 string Configuration::configuration_file_path = "/.lordsawarrc";
49 string Configuration::s_dataPath = "./data/";
50 string Configuration::s_savePath = "./saves/";
51 #endif
52 string Configuration::s_lang = "";
53 int Configuration::s_displaySpeedDelay = 300000;
54 int Configuration::s_displayFightRoundDelayFast = 250;
55 int Configuration::s_displayFightRoundDelaySlow = 500;
56 bool Configuration::s_displayCommentator = true;
57 guint32 Configuration::s_cacheSize = 1000000;
58 bool Configuration::s_zipfiles = false;
59 int Configuration::s_autosave_policy = 1;
60 bool Configuration::s_musicenable = true;
61 guint32 Configuration::s_musicvolume = 64;
62 guint32 Configuration::s_musiccache = 10000000;
63 string Configuration::s_filename = "";
64 bool Configuration::s_see_opponents_stacks = false;
65 bool Configuration::s_see_opponents_production = false;
66 GameParameters::QuestPolicy Configuration::s_play_with_quests = GameParameters::ONE_QUEST_PER_PLAYER;
67 bool Configuration::s_hidden_map = false;
68 bool Configuration::s_diplomacy = false;
69 GameParameters::NeutralCities Configuration::s_neutral_cities = GameParameters::AVERAGE;
70 GameParameters::RazingCities Configuration::s_razing_cities = GameParameters::ALWAYS;
71 bool Configuration::s_intense_combat = false;
72 bool Configuration::s_military_advisor = false;
73 bool Configuration::s_random_turns = false;
74 GameParameters::QuickStartPolicy Configuration::s_quick_start = GameParameters::NO_QUICK_START;
75 bool Configuration::s_cusp_of_war = false;
76 bool Configuration::s_decorated = true;
77 bool Configuration::s_remember_recent_games = true;
78 guint32 Configuration::s_double_click_threshold = 400; //milliseconds
79
80 Configuration::Configuration()
81 {
82     char *s = setlocale(LC_ALL, "");
83     if (s)
84         Configuration::s_lang = s;
85 }
86
87 Configuration::~Configuration()
88 {
89 }
90
91 // check if file exists and parse it
92
93 bool Configuration::loadConfigurationFile(string fileName)
94 {
95     debug("loadConfiguration()");
96     s_filename=fileName;
97      
98     ifstream in(fileName.c_str());
99     if (in)
100     {
101         //cout << _("Found configuration file: ") << fileName << endl;
102
103         //parse the file
104         XML_Helper helper(fileName.c_str(), ios::in, false);
105         helper.registerTag(
106             "lordsawarrc",
107             sigc::mem_fun(*this, &Configuration::parseConfiguration));
108     
109         return helper.parse();
110     }
111     else return false;
112 }
113
114 bool Configuration::saveConfigurationFile(string filename)
115 {
116     bool retval = true;
117
118     XML_Helper helper(filename, ios::out, Configuration::s_zipfiles);
119
120     //start writing
121     retval &= helper.begin(LORDSAWAR_CONFIG_VERSION);
122     retval &= helper.openTag("lordsawarrc");
123     
124     //save the values 
125     retval &= helper.saveData("datapath",s_dataPath);
126     retval &= helper.saveData("savepath", s_savePath);
127     retval &= helper.saveData("lang", s_lang);
128     retval &= helper.saveData("cachesize", s_cacheSize);
129     retval &= helper.saveData("zipfiles", s_zipfiles);
130     std::string autosave_policy_str = savingPolicyToString(SavingPolicy(s_autosave_policy));
131     retval &= helper.saveData("autosave_policy", autosave_policy_str);
132     retval &= helper.saveData("speeddelay", s_displaySpeedDelay);
133     retval &= helper.saveData("fightrounddelayfast", s_displayFightRoundDelayFast);
134     retval &= helper.saveData("fightrounddelayslow", s_displayFightRoundDelaySlow);
135     retval &= helper.saveData("commentator", s_displayCommentator);
136     retval &= helper.saveData("shownextplayer", s_showNextPlayer);
137     retval &= helper.saveData("musicenable", s_musicenable);
138     retval &= helper.saveData("musicvolume", s_musicvolume);
139     retval &= helper.saveData("musiccache", s_musiccache);
140     retval &= helper.saveData("view_enemies", s_see_opponents_stacks);
141     retval &= helper.saveData("view_production", s_see_opponents_production);
142     std::string quest_policy_str = questPolicyToString(GameParameters::QuestPolicy(s_play_with_quests));
143     retval &= helper.saveData("quests", quest_policy_str);
144     retval &= helper.saveData("hidden_map", s_hidden_map);
145     retval &= helper.saveData("diplomacy", s_diplomacy);
146     std::string neutral_cities_str = neutralCitiesToString(GameParameters::NeutralCities(s_neutral_cities));
147     retval &= helper.saveData("neutral_cities", neutral_cities_str);
148     std::string razing_cities_str = razingCitiesToString(GameParameters::RazingCities(s_razing_cities));
149     retval &= helper.saveData("razing_cities", razing_cities_str);
150     retval &= helper.saveData("intense_combat", s_intense_combat);
151     retval &= helper.saveData("military_advisor", s_military_advisor);
152     retval &= helper.saveData("random_turns", s_random_turns);
153     std::string quick_start_str = quickStartPolicyToString(GameParameters::QuickStartPolicy(s_quick_start));
154     retval &= helper.saveData("quick_start", quick_start_str);
155     retval &= helper.saveData("cusp_of_war", s_cusp_of_war);
156     retval &= helper.saveData("decorated", s_decorated);
157     retval &= helper.saveData("remember_recent_games", s_remember_recent_games);
158     retval &= helper.saveData("double_click_threshold", 
159                               s_double_click_threshold);
160     retval &= helper.closeTag();
161     
162     if (!retval)
163     {
164         std::cerr << "Configuration: Something went wrong while saving.\n";
165         return false;
166     }
167     
168     //    retval &= helper.closeTag();
169     helper.close();
170
171     return true;
172 }
173
174 // parse the configuration file and set the variables
175
176 bool Configuration::parseConfiguration(string tag, XML_Helper* helper)
177 {
178     debug("parseConfiguration()");
179     
180     string temp;
181     bool retval,zipping;
182     
183     if (helper->getVersion() != LORDSAWAR_CONFIG_VERSION)
184     {
185             cerr <<_("Configuration file has wrong version, we want ");
186             std::cerr <<LORDSAWAR_SAVEGAME_VERSION <<",\n";
187             cerr <<_("Configuration file offers ") << helper->getVersion() <<".\n";
188
189             string orig = s_filename;
190             string dest = s_filename+".OLD";
191             //#ifndef __WIN32__
192             //            string orig = "./"+s_filename;
193             //            string dest = "./"+s_filename+".OLD";
194             //#else
195             //            string orig = string(getenv("HOME"))+s_filename;
196             //            string dest = string(getenv("HOME"))+s_filename+".OLD";
197             //#endif
198             cerr << "I make a backup copy from " << orig << " to " << dest << endl;
199
200             ofstream ofs(dest.c_str());
201             ifstream ifs(orig.c_str());
202             ofs << ifs.rdbuf();
203             ofs.close();
204
205             //int ret= system(command.c_str());
206
207             //if (ret == -1)
208             //{
209             //     cerr << _("An error occurred while executing command : ") << command << endl;
210             //     exit(-1);
211             //}
212             return false;
213     }
214    
215     //get the paths
216     retval = helper->getData(temp, "datapath");
217     if (retval)
218     {
219         s_dataPath = temp;
220     }
221         
222     retval = helper->getData(temp, "savepath");
223     if (retval)
224     {
225         s_savePath = temp;
226     }
227
228     if (helper->getData(temp, "lang"))
229         s_lang = temp;
230     
231     //parse cache size
232     retval = helper->getData(temp, "cachesize");
233     if (retval)
234         s_cacheSize = atoi(temp.c_str());
235
236     //parse if savefiles should be zipped
237     retval = helper->getData(zipping, "zipfiles");
238     if (retval)
239         s_zipfiles = zipping;
240
241     //parse when and how to save autosave files
242     std::string autosave_policy_str;
243     helper->getData(autosave_policy_str, "autosave_policy");
244     s_autosave_policy = savingPolicyFromString(autosave_policy_str);
245
246     //parse the speed delays
247     helper->getData(s_displaySpeedDelay, "speeddelay");
248     helper->getData(s_displayFightRoundDelayFast, "fightrounddelayfast");
249     helper->getData(s_displayFightRoundDelaySlow, "fightrounddelayslow");
250
251     //parse whether or not the commentator should be shown
252     helper->getData(s_displayCommentator, "commentator");
253
254     //parse if nextplayer dialog should be enabled
255     helper->getData(s_showNextPlayer, "shownextplayer");
256
257     // parse musicsettings
258     helper->getData(s_musicenable, "musicenable");
259     helper->getData(s_musicvolume, "musicvolume");
260     helper->getData(s_musiccache, "musiccache");
261     
262     helper->getData(s_see_opponents_stacks, "view_enemies");
263     helper->getData(s_see_opponents_production, "view_production");
264     std::string quest_policy_str;
265     helper->getData(quest_policy_str, "quests");
266     s_play_with_quests = questPolicyFromString(quest_policy_str);
267     helper->getData(s_hidden_map, "hidden_map");
268     helper->getData(s_diplomacy, "diplomacy");
269     std::string neutral_cities_str;
270     helper->getData(neutral_cities_str, "neutral_cities");
271     s_neutral_cities = neutralCitiesFromString(neutral_cities_str);
272     std::string razing_cities_str;
273     helper->getData(razing_cities_str, "razing_cities");
274     s_razing_cities = razingCitiesFromString(razing_cities_str);
275     helper->getData(s_intense_combat, "intense_combat");
276     helper->getData(s_military_advisor, "military_advisor");
277     helper->getData(s_random_turns, "random_turns");
278     std::string quick_start_str;
279     helper->getData(quick_start_str, "quick_start");
280     s_quick_start = quickStartPolicyFromString(quick_start_str);
281     helper->getData(s_cusp_of_war, "cusp_of_war");
282     helper->getData(s_decorated, "decorated");
283     helper->getData(s_remember_recent_games, "remember_recent_games");
284     helper->getData(s_double_click_threshold, "double_click_threshold");
285     return true;
286 }
287
288 void initialize_configuration()
289 {
290     Configuration conf;
291
292     bool foundconf = conf.loadConfigurationFile(Configuration::configuration_file_path);
293     if (!foundconf)
294     {
295         bool saveconf = conf.saveConfigurationFile(Configuration::configuration_file_path);
296         if (!saveconf)
297         {
298             std::cerr << "Couldn't save the new configuration file..." << std::endl;
299             std::cerr << "Check permissions of your home directory....aborting!" << std::endl;
300             exit(-1);
301         }
302         else
303             std::cerr << "Created the standard configuration file " << Configuration::configuration_file_path << std::endl;
304     }
305     
306     //Check if the save game directory exists. If not, try to create it.
307
308     if (File::create_dir(Configuration::s_savePath) == false)
309     {
310         std::cerr << "Couldn't create save game directory ";
311         std::cerr << Configuration::s_savePath <<".\n";
312         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
313         exit(-1);
314     }
315     //Check if the personal armyset directory exists. If not, try to create it.
316     if (File::create_dir(File::getUserArmysetDir()) == false)
317     {
318         std::cerr << "Couldn't create personal armyset directory ";
319         std::cerr << File::getUserArmysetDir() <<".\n";
320         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
321         exit(-1);
322     }
323     //Check if the personal tileset directory exists. If not, try to create it.
324     if (File::create_dir(File::getUserTilesetDir()) == false)
325     {
326         std::cerr << "Couldn't create personal tileset directory ";
327         std::cerr << File::getUserTilesetDir() <<".\n";
328         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
329         exit(-1);
330     }
331
332     //Check if the personal maps directory exists. If not, try to create it.
333     if (File::create_dir(File::getUserMapDir()) == false)
334     {
335         std::cerr << "Couldn't create personal map directory ";
336         std::cerr << File::getUserMapDir() <<".\n";
337         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
338         exit(-1);
339     }
340
341     //Check if the personal shieldset directory exists. If not, try to make it.
342     if (File::create_dir(File::getUserShieldsetDir()) == false)
343     {
344         std::cerr << "Couldn't create personal shieldset directory ";
345         std::cerr << File::getUserShieldsetDir() <<".\n";
346         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
347         exit(-1);
348     }
349
350     //Check if the personal cityset directory exists. If not, try to make it.
351     if (File::create_dir(File::getUserCitysetDir()) == false)
352     {
353         std::cerr << "Couldn't create personal cityset directory ";
354         std::cerr << File::getUserCitysetDir() <<".\n";
355         std::cerr << "Check permissions and the entries in your lordsawarrc file!" << std::endl;
356         exit(-1);
357     }
358 }
359
360 std::string Configuration::neutralCitiesToString(const GameParameters::NeutralCities neutrals)
361 {
362   switch (neutrals)
363     {
364       case GameParameters::AVERAGE:
365         return "GameParameters::AVERAGE";
366         break;
367       case GameParameters::STRONG:
368         return "GameParameters::STRONG";
369         break;
370       case GameParameters::ACTIVE:
371         return "GameParameters::ACTIVE";
372         break;
373       case GameParameters::DEFENSIVE:
374         return "GameParameters::DEFENSIVE";
375         break;
376     }
377   return "GameParameters::AVERAGE";
378 }
379
380 GameParameters::NeutralCities Configuration::neutralCitiesFromString(std::string str)
381 {
382   if (str.size() > 0 && isdigit(str.c_str()[0]))
383     return GameParameters::NeutralCities(atoi(str.c_str()));
384   if (str == "GameParameters::AVERAGE")
385     return GameParameters::AVERAGE;
386   else if (str == "GameParameters::STRONG")
387     return GameParameters::STRONG;
388   else if (str == "GameParameters::ACTIVE")
389     return GameParameters::ACTIVE;
390   else if (str == "GameParameters::DEFENSIVE")
391     return GameParameters::DEFENSIVE;
392     
393   return GameParameters::AVERAGE;
394 }
395
396 std::string Configuration::razingCitiesToString(const GameParameters::RazingCities razing)
397 {
398   switch (razing)
399     {
400       case GameParameters::NEVER:
401         return "GameParameters::NEVER";
402         break;
403       case GameParameters::ON_CAPTURE:
404         return "GameParameters::ON_CAPTURE";
405         break;
406       case GameParameters::ALWAYS:
407         return "GameParameters::ALWAYS";
408         break;
409     }
410   return "GameParameters::ALWAYS";
411 }
412
413 GameParameters::RazingCities Configuration::razingCitiesFromString(std::string str)
414 {
415   if (str.size() > 0 && isdigit(str.c_str()[0]))
416     return GameParameters::RazingCities(atoi(str.c_str()));
417   if (str == "GameParameters::NEVER")
418     return GameParameters::NEVER;
419   else if (str == "GameParameters::ON_CAPTURE")
420     return GameParameters::ON_CAPTURE;
421   else if (str == "GameParameters::ALWAYS")
422     return GameParameters::ALWAYS;
423     
424   return GameParameters::ALWAYS;
425 }
426
427 std::string Configuration::savingPolicyToString(const Configuration::SavingPolicy policy)
428 {
429   switch (policy)
430     {
431     case Configuration::NO_SAVING:
432       return "Configuration::NO_SAVING";
433       break;
434     case Configuration::WRITE_UNNUMBERED_AUTOSAVE_FILE:
435       return "Configuration::WRITE_UNNUMBERED_AUTOSAVE_FILE";
436       break;
437     case Configuration::WRITE_NUMBERED_AUTOSAVE_FILE:
438       return "Configuration::WRITE_NUMBERED_AUTOSAVE_FILE";
439       break;
440     }
441   return "Configuration::NO_SAVING";
442 }
443
444 Configuration::SavingPolicy Configuration::savingPolicyFromString(std::string str)
445 {
446   if (str.size() > 0 && isdigit(str.c_str()[0]))
447     return Configuration::SavingPolicy(atoi(str.c_str()));
448   if (str == "Configuration::NO_SAVING")
449     return Configuration::NO_SAVING;
450   else if (str == "Configuration::WRITE_UNNUMBERED_AUTOSAVE_FILE")
451     return Configuration::WRITE_UNNUMBERED_AUTOSAVE_FILE;
452   else if (str == "Configuration::WRITE_NUMBERED_AUTOSAVE_FILE")
453     return Configuration::WRITE_NUMBERED_AUTOSAVE_FILE;
454     
455   return Configuration::WRITE_NUMBERED_AUTOSAVE_FILE;
456 }
457
458 std::string Configuration::quickStartPolicyToString(const GameParameters::QuickStartPolicy policy)
459 {
460   switch (policy)
461     {
462     case GameParameters::NO_QUICK_START:
463       return "GameParameters::NO_QUICK_START";
464       break;
465     case GameParameters::EVENLY_DIVIDED:
466       return "GameParameters::EVENLY_DIVIDED";
467       break;
468     case GameParameters::AI_HEAD_START:
469       return "GameParameters::AI_HEAD_START";
470       break;
471     }
472   return "GameParameters::NO_QUICK_START";
473 }
474
475 GameParameters::QuickStartPolicy Configuration::quickStartPolicyFromString(std::string str)
476 {
477   if (str.size() > 0 && isdigit(str.c_str()[0]))
478     return GameParameters::QuickStartPolicy(atoi(str.c_str()));
479   if (str == "GameParameters::NO_QUICK_START")
480     return GameParameters::NO_QUICK_START;
481   else if (str == "GameParameters::EVENLY_DIVIDED")
482     return GameParameters::EVENLY_DIVIDED;
483   else if (str == "GameParameters::AI_HEAD_START")
484     return GameParameters::AI_HEAD_START;
485     
486   return GameParameters::NO_QUICK_START;
487 }
488
489 std::string Configuration::questPolicyToString(const GameParameters::QuestPolicy quest)
490 {
491   switch (quest)
492     {
493       case GameParameters::NO_QUESTING:
494         return "GameParameters::NO_QUESTING";
495         break;
496       case GameParameters::ONE_QUEST_PER_PLAYER:
497         return "GameParameters::ONE_QUEST_PER_PLAYER";
498         break;
499       case GameParameters::ONE_QUEST_PER_HERO:
500         return "GameParameters::ONE_QUEST_PER_HERO";
501         break;
502     }
503   return "GameParameters::NO_QUESTING";
504 }
505
506 GameParameters::QuestPolicy Configuration::questPolicyFromString(std::string str)
507 {
508   if (str.size() > 0 && isdigit(str.c_str()[0]))
509     return GameParameters::QuestPolicy(atoi(str.c_str()));
510   if (str == "GameParameters::NO_QUESTING")
511     return GameParameters::NO_QUESTING;
512   else if (str == "GameParameters::ONE_QUEST_PER_PLAYER")
513     return GameParameters::ONE_QUEST_PER_PLAYER;
514   else if (str == "GameParameters::ONE_QUEST_PER_HERO")
515     return GameParameters::ONE_QUEST_PER_HERO;
516     
517   return GameParameters::NO_QUESTING;
518 }
519