00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #define GETTEXT_DOMAIN "wesnoth-lib"
00018
00019 #include "config.hpp"
00020 #include "filesystem.hpp"
00021 #include "game_preferences.hpp"
00022 #include "gamestatus.hpp"
00023 #include "gettext.hpp"
00024 #include "hotkeys.hpp"
00025 #include "log.hpp"
00026 #include "network.hpp"
00027 #include "sound.hpp"
00028 #include "settings.hpp"
00029 #include "util.hpp"
00030 #include "video.hpp"
00031 #include "wml_exception.hpp"
00032 #include "serialization/parser.hpp"
00033 #include "serialization/string_utils.hpp"
00034
00035 #include <cstdlib>
00036 #include <iostream>
00037 #include <iterator>
00038 #include <sstream>
00039
00040 namespace {
00041
00042 bool message_private_on = false;
00043
00044 bool haloes = true;
00045
00046 std::set<std::string> encountered_units_set;
00047 std::set<t_translation::t_terrain> encountered_terrains_set;
00048
00049 std::map<std::string, std::vector<std::string> > history_map;
00050 const unsigned max_history_saved = 50;
00051
00052
00053 void add_relation(const std::string nick, const std::string relation) {
00054 std::vector<std::string> r = utils::split(preferences::get(relation));
00055 r.push_back(nick);
00056 preferences::set(relation, utils::join(r));
00057 }
00058
00059
00060 void remove_relation(const std::string nick, const std::string relation) {
00061 std::vector<std::string> r = utils::split(preferences::get(relation));
00062 r.erase(std::remove(r.begin(), r.end(), nick), r.end());
00063 preferences::set(relation, utils::join(r));
00064 }
00065
00066 }
00067
00068 namespace preferences {
00069
00070 manager::manager()
00071 {
00072 set_music_volume(music_volume());
00073 set_sound_volume(sound_volume());
00074
00075 set_show_haloes(utils::string_bool(preferences::get("show_haloes"), true));
00076 if(!utils::string_bool(preferences::get("remember_timer_settings"), false)) {
00077 preferences::erase("mp_countdown_init_time");
00078 preferences::erase("mp_countdown_reservoir_time");
00079 preferences::erase("mp_countdown_turn_bonus");
00080 preferences::erase("mp_countdown_action_bonus");
00081 }
00082
00083 const std::vector<std::string> v = utils::split(preferences::get("encountered_units"));
00084 std::copy(v.begin(), v.end(),
00085 std::inserter(encountered_units_set, encountered_units_set.begin()));
00086
00087 const t_translation::t_list terrain =
00088 t_translation::read_list(preferences::get("encountered_terrain_list"));
00089 std::copy(terrain.begin(), terrain.end(),
00090 std::inserter(encountered_terrains_set, encountered_terrains_set.begin()));
00091
00092 config* history = preferences::get_child("history");
00093 if (history) {
00094 const string_map& history_strings = history->values;
00095 for (string_map::const_iterator iter = history_strings.begin(); iter != history_strings.end(); ++iter) {
00096 std::vector<std::string> current_history = utils::paranthetical_split(iter->second.value(), ',', "(", ")");
00097 std::vector<std::string>* history_ptr = get_history(iter->first);
00098 for (std::vector<std::string>::iterator i = current_history.begin(); i != current_history.end(); ++i) {
00099
00100 history_ptr->push_back(i->substr(1, i->size() - 2));
00101 }
00102 }
00103 }
00104
00105 network::ping_timeout = get_ping_timeout();
00106 }
00107
00108 manager::~manager()
00109 {
00110 std::vector<std::string> v;
00111 std::copy(encountered_units_set.begin(), encountered_units_set.end(), std::back_inserter(v));
00112 preferences::set("encountered_units", utils::join(v));
00113 t_translation::t_list terrain;
00114 std::copy(encountered_terrains_set.begin(), encountered_terrains_set.end(),
00115 std::back_inserter(terrain));
00116 preferences::set("encountered_terrain_list", t_translation::write_list(terrain));
00117
00118 config history;
00119 std::map<std::string, std::vector<std::string> >::iterator iter;
00120 for (iter = history_map.begin(); iter != history_map.end(); ++iter) {
00121 std::stringstream history_stream;
00122 std::vector<std::string>::iterator i;
00123 for (i = iter->second.size() < max_history_saved ? iter->second.begin(): iter->second.end() - max_history_saved; i != iter->second.end(); ++i) {
00124 history_stream << "(" << *i << ")";
00125 if (i + 1 != iter->second.end()) {
00126 history_stream << ",";
00127 }
00128 }
00129 history[iter->first] = history_stream.str();
00130 }
00131
00132 preferences::set_child("history", history);
00133
00134 history_map.clear();
00135 encountered_units_set.clear();
00136 encountered_terrains_set.clear();
00137 set_ping_timeout(network::ping_timeout);
00138 }
00139
00140 std::string get_friends() {
00141 return preferences::get("friends");
00142 }
00143
00144 std::string get_ignores() {
00145 return preferences::get("ignores");
00146 }
00147
00148 bool add_friend(const std::string nick) {
00149 if (!utils::isvalid_username(nick)) return false;
00150 add_relation(nick, "friends");
00151 return true;
00152 }
00153
00154 bool add_ignore(const std::string nick) {
00155 if (!utils::isvalid_username(nick)) return false;
00156 add_relation(nick, "ignores");
00157 return true;
00158 }
00159
00160 void remove_friend(const std::string nick) {
00161 remove_relation(nick, "friends");
00162 }
00163
00164 void remove_ignore(const std::string nick) {
00165 remove_relation(nick, "ignores");
00166 }
00167
00168 void clear_friends() {
00169 preferences::set("friends", "");
00170 }
00171
00172 void clear_ignores() {
00173 preferences::set("ignores", "");
00174 }
00175
00176 bool is_friend(const std::string nick) {
00177 const std::vector<std::string>& friends = utils::split(get_friends());
00178 return (std::find(friends.begin(), friends.end(), nick) != friends.end());
00179 }
00180
00181 bool is_ignored(const std::string nick) {
00182 const std::vector<std::string>& ignores = utils::split(get_ignores());
00183 return (std::find(ignores.begin(), ignores.end(), nick) != ignores.end());
00184 }
00185
00186 bool show_lobby_join(const std::string& sender, const std::string& message) {
00187
00188 if (sender != "server" || message.find("has logged into the lobby") == std::string::npos) return true;
00189 if (lobby_joins() == SHOW_NONE) return false;
00190 if (lobby_joins() == SHOW_ALL) return true;
00191 const std::string::const_iterator i =
00192 std::find(message.begin(), message.end(), ' ');
00193 const std::string joiner(message.begin(), i);
00194 if (lobby_joins() == SHOW_FRIENDS && is_friend(joiner)) return true;
00195 return false;
00196 }
00197
00198 int lobby_joins()
00199 {
00200 if(preferences::get("lobby_joins") == "friends") {
00201 return SHOW_FRIENDS;
00202 } else if(preferences::get("lobby_joins") == "all") {
00203 return SHOW_ALL;
00204 } else if(preferences::get("lobby_joins") == "none") {
00205 return SHOW_NONE;
00206 } else {
00207 return SHOW_FRIENDS;
00208 }
00209 }
00210
00211
00212 void _set_lobby_joins(int show)
00213 {
00214 if (show == SHOW_FRIENDS) {
00215 preferences::set("lobby_joins", "friends");
00216 } else if (show == SHOW_ALL) {
00217 preferences::set("lobby_joins", "all");
00218 } else if (show == SHOW_NONE) {
00219 preferences::set("lobby_joins", "none");
00220 }
00221 }
00222
00223 bool sort_list()
00224 {
00225 return utils::string_bool(preferences::get("sort_list"), true);
00226 }
00227
00228
00229 void _set_sort_list(bool sort)
00230 {
00231 preferences::set("sort_list", sort ? "yes" : "no");
00232 }
00233
00234 bool iconize_list()
00235 {
00236 return utils::string_bool(preferences::get("iconize_list"), true);
00237 }
00238
00239 void _set_iconize_list(bool sort)
00240 {
00241 preferences::set("iconize_list", sort ? "yes" : "no");
00242 }
00243
00244 const std::vector<game_config::server_info>& server_list()
00245 {
00246 static std::vector<game_config::server_info> pref_servers;
00247 if(pref_servers.empty()) {
00248 std::vector<game_config::server_info> &game_servers = game_config::server_list;
00249 VALIDATE(game_servers.size() > 0, _("No server has been defined."));
00250 pref_servers.insert(pref_servers.begin(), game_servers.begin(), game_servers.end());
00251 const std::vector<config *> &user_servers = get_prefs()->get_children("server");
00252 std::vector<config *>::const_iterator server;
00253 for(server = user_servers.begin(); server != user_servers.end(); ++server) {
00254 game_config::server_info sinf;
00255 sinf.name = (**server)["name"];
00256 sinf.address = (**server)["address"];
00257 pref_servers.push_back(sinf);
00258 }
00259 }
00260 return pref_servers;
00261 }
00262
00263 const std::string network_host()
00264 {
00265 const std::string res = preferences::get("host");
00266 if(res.empty()) {
00267 return server_list().front().address;
00268 } else {
00269 return res;
00270 }
00271 }
00272
00273 void set_network_host(const std::string& host)
00274 {
00275 preferences::set("host", host);
00276 }
00277
00278 unsigned int get_ping_timeout()
00279 {
00280 return lexical_cast_default<unsigned>(preferences::get("ping_timeout"), 0);
00281 }
00282
00283 void set_ping_timeout(unsigned int timeout)
00284 {
00285 network::ping_timeout = timeout;
00286 preferences::set("ping_timeout", lexical_cast<std::string>(timeout));
00287 }
00288
00289 const std::string campaign_server()
00290 {
00291 if(!preferences::get("campaign_server").empty()) {
00292 return preferences::get("campaign_server");
00293 } else {
00294 return "campaigns.wesnoth.org";
00295 }
00296 }
00297
00298 void set_campaign_server(const std::string& host)
00299 {
00300 preferences::set("campaign_server", host);
00301 }
00302
00303 const std::string login()
00304 {
00305 const std::string res = preferences::get("login");
00306 if(res.empty()) {
00307 char* const login = getenv("USER");
00308 if(login != NULL) {
00309 return login;
00310 }
00311
00312 if(res.empty()) {
00313 return _("player");
00314 }
00315 }
00316
00317 return res;
00318 }
00319
00320 void set_login(const std::string& username)
00321 {
00322 preferences::set("login", username);
00323 }
00324
00325 bool turn_dialog()
00326 {
00327 return utils::string_bool(preferences::get("turn_dialog"), false);
00328 }
00329
00330 void set_turn_dialog(bool ison)
00331 {
00332 preferences::set("turn_dialog", ison ? "yes" : "no");
00333 }
00334
00335 bool show_combat()
00336 {
00337 return utils::string_bool(preferences::get("show_combat"), true);
00338 }
00339
00340 bool allow_observers()
00341 {
00342 return utils::string_bool(preferences::get("allow_observers"), true);
00343 }
00344
00345 void set_allow_observers(bool value)
00346 {
00347 preferences::set("allow_observers", value ? "yes" : "no");
00348 }
00349
00350 bool use_map_settings()
00351 {
00352 return utils::string_bool(preferences::get("mp_use_map_settings"), true);
00353 }
00354
00355 void set_use_map_settings(bool value)
00356 {
00357 preferences::set("mp_use_map_settings", value ? "yes" : "no");
00358 }
00359
00360 bool random_start_time()
00361 {
00362 return settings::use_random_start_time(preferences::get("mp_random_start_time"));
00363 }
00364
00365 void set_random_start_time(bool value)
00366 {
00367 preferences::set("mp_random_start_time", value ? "yes" : "no");
00368 }
00369
00370 bool fog()
00371 {
00372 return settings::use_fog(preferences::get("mp_fog"));
00373 }
00374
00375 void set_fog(bool value)
00376 {
00377 preferences::set("mp_fog", value ? "yes" : "no");
00378 }
00379
00380 bool shroud()
00381 {
00382 return settings::use_shroud(preferences::get("mp_shroud"));
00383 }
00384
00385 void set_shroud(bool value)
00386 {
00387 preferences::set("mp_shroud", value ? "yes" : "no");
00388 }
00389
00390 int turns()
00391 {
00392 return settings::get_turns(preferences::get("mp_turns"));
00393 }
00394
00395 void set_turns(int value)
00396 {
00397 preferences::set("mp_turns", lexical_cast<std::string>(value));
00398 }
00399
00400 bool skip_mp_replay()
00401 {
00402 return utils::string_bool(preferences::get("skip_mp_replay"), false);
00403 }
00404
00405 void set_skip_mp_replay(bool value)
00406 {
00407 preferences::set("skip_mp_replay", value ? "yes" : "no");
00408 }
00409
00410 bool countdown()
00411 {
00412 return utils::string_bool(preferences::get("mp_countdown"), false);
00413 }
00414
00415 void set_countdown(bool value)
00416 {
00417 preferences::set("mp_countdown", value ? "yes" : "no");
00418 }
00419
00420 int countdown_init_time()
00421 {
00422 return lexical_cast_in_range<int>
00423 (preferences::get("mp_countdown_init_time"), 270, 0, 1500);
00424 }
00425
00426 void set_countdown_init_time(int value)
00427 {
00428 preferences::set("mp_countdown_init_time", lexical_cast<std::string>(value));
00429 }
00430
00431 int countdown_reservoir_time()
00432 {
00433 return lexical_cast_in_range<int>(
00434 preferences::get("mp_countdown_reservoir_time"), 330, 30, 1500);
00435 }
00436
00437 void set_countdown_reservoir_time(int value)
00438 {
00439 preferences::set("mp_countdown_reservoir_time", lexical_cast<std::string>(value));
00440 }
00441
00442 int countdown_turn_bonus()
00443 {
00444 return lexical_cast_in_range<int>(
00445 preferences::get("mp_countdown_turn_bonus"), 40, 0, 300);
00446 }
00447
00448 void set_countdown_turn_bonus(int value)
00449 {
00450 preferences::set("mp_countdown_turn_bonus", lexical_cast<std::string>(value));
00451 }
00452
00453 int countdown_action_bonus()
00454 {
00455 return lexical_cast_in_range<int>(
00456 preferences::get("mp_countdown_action_bonus"), 13, 0, 30);
00457 }
00458
00459 void set_countdown_action_bonus(int value)
00460 {
00461 preferences::set("mp_countdown_action_bonus", lexical_cast<std::string>(value));
00462 }
00463
00464 int village_gold()
00465 {
00466 return settings::get_village_gold(preferences::get("mp_village_gold"));
00467 }
00468
00469 void set_village_gold(int value)
00470 {
00471 preferences::set("mp_village_gold", lexical_cast<std::string>(value));
00472 }
00473
00474 int xp_modifier()
00475 {
00476 return settings::get_xp_modifier(preferences::get("mp_xp_modifier"));
00477 }
00478
00479 void set_xp_modifier(int value)
00480 {
00481 preferences::set("mp_xp_modifier", lexical_cast<std::string>(value));
00482 }
00483
00484 int era()
00485 {
00486 return lexical_cast_default<int>(preferences::get("mp_era"), 0);
00487 }
00488
00489 void set_era(int value)
00490 {
00491 preferences::set("mp_era", lexical_cast<std::string>(value));
00492 }
00493
00494 int map()
00495 {
00496 return lexical_cast_default<int>(preferences::get("mp_map"), 0);
00497 }
00498
00499 void set_map(int value)
00500 {
00501 preferences::set("mp_map", lexical_cast<std::string>(value));
00502 }
00503
00504 bool show_ai_moves()
00505 {
00506 return utils::string_bool(preferences::get("show_ai_moves"), true);
00507 }
00508
00509 void set_show_ai_moves(bool value)
00510 {
00511 preferences::set("show_ai_moves", value ? "yes" : "no");
00512 }
00513
00514 void set_show_side_colours(bool value)
00515 {
00516 preferences::set("show_side_colours", value ? "yes" : "no");
00517 }
00518
00519 bool show_side_colours()
00520 {
00521 return utils::string_bool(preferences::get("show_side_colours"), true);
00522 }
00523
00524 void set_save_replays(bool value)
00525 {
00526 preferences::set("save_replays", value ? "yes" : "no");
00527 }
00528
00529 bool save_replays()
00530 {
00531 return utils::string_bool(preferences::get("save_replays"), true);
00532 }
00533
00534 void set_delete_saves(bool value)
00535 {
00536 preferences::set("delete_saves", value ? "yes" : "no");
00537 }
00538
00539 bool delete_saves()
00540 {
00541 return utils::string_bool(preferences::get("delete_saves"), false);
00542 }
00543
00544 void set_ask_delete_saves(bool value)
00545 {
00546 preferences::set("ask_delete", value ? "yes" : "no");
00547 }
00548
00549 bool ask_delete_saves()
00550 {
00551 return utils::string_bool(preferences::get("ask_delete"), true);
00552 }
00553
00554 int autosavemax()
00555 {
00556 return lexical_cast_default<int>(preferences::get("auto_save_max"), 10);
00557 }
00558
00559 void set_autosavemax(int value)
00560 {
00561 preferences::set("auto_save_max", lexical_cast<std::string>(value));
00562 }
00563
00564 std::string client_type()
00565 {
00566 return preferences::get("client_type") == "ai" ? "ai" : "human";
00567 }
00568
00569 std::string clock_format()
00570 {
00571 if(preferences::get("clock_format").size())
00572 return preferences::get("clock_format");
00573 else
00574 preferences::set("clock_format", "%H:%M");
00575 return "%H:%M";
00576 }
00577
00578 const std::string theme()
00579 {
00580 if(non_interactive()) {
00581 static const std::string null_theme = "null";
00582 return null_theme;
00583 }
00584
00585 std::string res = preferences::get("theme");
00586 if(res.empty()) {
00587 return "Default";
00588 }
00589
00590 return res;
00591 }
00592
00593 void set_theme(const std::string& theme)
00594 {
00595 if(theme != "null") {
00596 preferences::set("theme", theme);
00597 }
00598 }
00599
00600 bool show_floating_labels()
00601 {
00602 return utils::string_bool(preferences::get("floating_labels"), true);
00603 }
00604
00605 void set_show_floating_labels(bool value)
00606 {
00607 preferences::set("floating_labels", value ? "yes" : "no");
00608 }
00609
00610 bool message_private()
00611 {
00612 return message_private_on;
00613 }
00614
00615 void set_message_private(bool value)
00616 {
00617 message_private_on = value;
00618 }
00619
00620 bool show_tip_of_day()
00621 {
00622 return utils::string_bool(preferences::get("tip_of_day"), true);
00623 }
00624
00625 bool show_haloes()
00626 {
00627 return haloes;
00628 }
00629
00630 void set_show_haloes(bool value)
00631 {
00632 haloes = value;
00633 preferences::set("show_haloes", value ? "yes" : "no");
00634 }
00635
00636 bool flip_time()
00637 {
00638 return utils::string_bool(preferences::get("flip_time"), false);
00639 }
00640
00641 void set_flip_time(bool value)
00642 {
00643 preferences::set("flip_time", value ? "yes" : "no");
00644 }
00645
00646 bool upload_log()
00647 {
00648 return utils::string_bool(preferences::get("upload_log"), false);
00649 }
00650
00651 void set_upload_log(bool value)
00652 {
00653 preferences::set("upload_log", value ? "yes" : "no");
00654 }
00655
00656 const std::string upload_id()
00657 {
00658
00659
00660 if (preferences::get("upload_id") == "") {
00661 srand(time(NULL));
00662 preferences::set("upload_id",
00663 lexical_cast<std::string>(rand())
00664 + lexical_cast<std::string>(SDL_GetTicks()));
00665 }
00666 return preferences::get("upload_id");
00667 }
00668
00669 bool compress_saves()
00670 {
00671 return utils::string_bool(preferences::get("compress_saves"), true);
00672 }
00673
00674 std::string get_chat_timestamp(const time_t& t) {
00675 if (chat_timestamping()) {
00676 return lg::get_timestamp(t, clock_format()) + " ";
00677 }
00678 return "";
00679 }
00680
00681 bool chat_timestamping() {
00682 return utils::string_bool(preferences::get("chat_timestamp"), false);
00683 }
00684
00685 void set_chat_timestamping(bool value) {
00686 preferences::set("chat_timestamp", value ? "yes" : "no");
00687 }
00688
00689 int chat_lines()
00690 {
00691 return lexical_cast_default<int>(preferences::get("chat_lines"), 6);
00692 }
00693
00694 void set_chat_lines(int lines)
00695 {
00696 preferences::set("chat_lines", lexical_cast<std::string>(lines));
00697 }
00698
00699 std::set<std::string> &encountered_units() {
00700 return encountered_units_set;
00701 }
00702
00703 std::set<t_translation::t_terrain> &encountered_terrains() {
00704 return encountered_terrains_set;
00705 }
00706
00707 std::string custom_command() {
00708 return preferences::get("custom_command");
00709 }
00710
00711 void set_custom_command(const std::string& command) {
00712 return preferences::set("custom_command", command);
00713 }
00714
00715
00716
00717
00718 std::vector<std::string>* get_history(const std::string& id) {
00719 return &history_map[id];
00720 }
00721
00722 bool green_confirm()
00723 {
00724 std::string confirmation = preferences::get("confirm_end_turn");
00725
00726 if (confirmation == "green" || confirmation == "yes")
00727 return true;
00728 return false;
00729 }
00730
00731 bool yellow_confirm()
00732 {
00733 return preferences::get("confirm_end_turn") == "yellow";
00734 }
00735
00736 bool confirm_no_moves()
00737 {
00738
00739 const std::string confirmation = preferences::get("confirm_end_turn");
00740 return confirmation == "no_moves" || confirmation.empty();
00741 }
00742
00743
00744 void encounter_recruitable_units(std::vector<team>& teams){
00745 for (std::vector<team>::iterator help_team_it = teams.begin();
00746 help_team_it != teams.end(); help_team_it++) {
00747 help_team_it->log_recruitable();
00748 std::copy(help_team_it->recruits().begin(), help_team_it->recruits().end(),
00749 std::inserter(encountered_units_set, encountered_units_set.begin()));
00750 }
00751 }
00752
00753 void encounter_start_units(unit_map& units){
00754 for (unit_map::const_iterator help_unit_it = units.begin();
00755 help_unit_it != units.end(); help_unit_it++) {
00756 const std::string name = help_unit_it->second.type_id();
00757 encountered_units_set.insert(name);
00758 }
00759 }
00760
00761 void encounter_recallable_units(game_state& gamestate){
00762 for(std::map<std::string, player_info>::iterator pi = gamestate.players.begin(); pi!=gamestate.players.end(); ++pi) {
00763 for(std::vector<unit>::iterator help_recall_it = pi->second.available_units.begin(); help_recall_it != pi->second.available_units.end(); help_recall_it++) {
00764 encountered_units_set.insert(help_recall_it->type_id());
00765 }
00766 }
00767 }
00768
00769 void encounter_map_terrain(gamemap& map){
00770 for (int map_x = 0; map_x < map.w(); map_x++) {
00771 for (int map_y = 0; map_y < map.h(); map_y++) {
00772 const t_translation::t_terrain t = map.get_terrain(gamemap::location(map_x, map_y));
00773 preferences::encountered_terrains().insert(t);
00774 const t_translation::t_list& underlaying_list = map.underlying_union_terrain(gamemap::location(map_x, map_y));
00775 for (std::vector<t_translation::t_terrain>::const_iterator ut = underlaying_list.begin(); ut != underlaying_list.end(); ut++) {
00776 preferences::encountered_terrains().insert(*ut);
00777 };
00778 }
00779 }
00780 }
00781
00782 }