The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
game_launcher.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "game_launcher.hpp"
16 #include "global.hpp" // for false_, bool_
17 
18 #include "about.hpp" //for show_about
19 #include "commandline_options.hpp" // for commandline_options
20 #include "config.hpp" // for config, etc
21 #include "config_assign.hpp"
22 #include "construct_dialog.hpp" // for dialog
23 #include "cursor.hpp" // for set, CURSOR_TYPE::NORMAL
24 #include "exceptions.hpp" // for error
25 #include "filesystem.hpp" // for get_user_config_dir, etc
26 #include "game_classification.hpp" // for game_classification, etc
27 #include "game_config.hpp" // for path, no_delay, revision, etc
28 #include "game_config_manager.hpp" // for game_config_manager
29 #include "game_end_exceptions.hpp" // for LEVEL_RESULT, etc
30 #include "generators/map_generator.hpp" // for mapgen_exception
31 #include "gettext.hpp" // for _
32 #include "gui/dialogs/language_selection.hpp" // for tlanguage_selection
34 #include "gui/dialogs/message.hpp" //for show error message
35 #include "gui/dialogs/multiplayer/mp_host_game_prompt.hpp" //for host game prompt
37 #include "gui/dialogs/transient_message.hpp" // for show_transient_message
38 #include "gui/dialogs/title_screen.hpp" // for show_debug_clock_button
39 #include "gui/widgets/settings.hpp" // for new_widgets
40 #include "gui/widgets/window.hpp" // for twindow, etc
41 #include "intro.hpp"
42 #include "language.hpp" // for language_def, etc
43 #include "log.hpp" // for LOG_STREAM, logger, general, etc
44 #include "map/exception.hpp"
45 #include "game_initialization/multiplayer.hpp" // for start_client, etc
47 #include "game_initialization/playcampaign.hpp" // for play_game, etc
48 #include "preferences.hpp" // for disable_preferences_save, etc
49 #include "savegame.hpp" // for clean_saves, etc
51 #include "sdl/utils.hpp" // for surface
52 #include "serialization/compression.hpp" // for format::NONE
53 #include "serialization/string_utils.hpp" // for split
54 #include "game_initialization/singleplayer.hpp" // for sp_create_mode
55 #include "statistics.hpp"
56 #include "tstring.hpp" // for operator==, operator!=
57 #include "util.hpp" // for lexical_cast_default
58 #include "video.hpp" // for CVideo
60 #include "wml_exception.hpp" // for twml_exception
61 
62 #include <algorithm> // for copy, max, min, stable_sort
63 #include <boost/optional.hpp> // for optional
64 #include <boost/tuple/tuple.hpp> // for tuple
65 #include <cstdlib> // for system
66 #include <iostream> // for operator<<, basic_ostream, etc
67 #include <utility> // for pair
68 #include <SDL.h> // for SDL_INIT_JOYSTICK, etc
69 #include <SDL_events.h> // for SDL_ENABLE
70 #include <SDL_joystick.h> // for SDL_JoystickEventState, etc
71 #include <SDL_timer.h> // for SDL_Delay
72 #include <SDL_video.h> // for SDL_WM_SetCaption, etc
73 
74 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
75 #include "gui/widgets/debug.hpp"
76 #endif
77 
78 // For wesnothd launch code.
79 #ifdef _WIN32
80 
81 #define WIN32_LEAN_AND_MEAN
82 #include <windows.h>
83 
84 #endif // _WIN32
85 
87 
88 static lg::log_domain log_config("config");
89 #define ERR_CONFIG LOG_STREAM(err, log_config)
90 #define WRN_CONFIG LOG_STREAM(warn, log_config)
91 #define LOG_CONFIG LOG_STREAM(info, log_config)
92 
93 #define LOG_GENERAL LOG_STREAM(info, lg::general())
94 #define WRN_GENERAL LOG_STREAM(warn, lg::general())
95 #define DBG_GENERAL LOG_STREAM(debug, lg::general())
96 
97 static lg::log_domain log_mp_create("mp/create");
98 #define DBG_MP LOG_STREAM(debug, log_mp_create)
99 
100 static lg::log_domain log_network("network");
101 #define ERR_NET LOG_STREAM(err, log_network)
102 
103 static lg::log_domain log_enginerefac("enginerefac");
104 #define LOG_RG LOG_STREAM(info, log_enginerefac)
105 
106 game_launcher::game_launcher(const commandline_options& cmdline_opts, const char *appname) :
107  cmdline_opts_(cmdline_opts),
108  video_(new CVideo()),
109  font_manager_(),
110  prefs_manager_(),
111  image_manager_(),
112  main_event_context_(),
113  hotkey_manager_(),
114  music_thinker_(),
115  test_scenario_("test"),
116  screenshot_map_(),
117  screenshot_filename_(),
118  state_(),
119  play_replay_(false),
120  multiplayer_server_(),
121  jump_to_multiplayer_(false),
122  jump_to_campaign_(false, -1, "", ""),
123  jump_to_editor_(false)
124 {
125  bool no_music = false;
126  bool no_sound = false;
127 
128  // The path can be hardcoded and it might be a relative path.
129  if(!game_config::path.empty() &&
130 #ifdef _WIN32
131  // use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string
132  game_config::path.c_str()[1] != ':'
133 #else
134  game_config::path[0] != '/'
135 #endif
136  )
137  {
140  }
141 
142  const std::string app_basename = filesystem::base_name(appname);
143  jump_to_editor_ = app_basename.find("editor") != std::string::npos;
144 
145  if (cmdline_opts_.core_id) {
147  }
148  if (cmdline_opts_.campaign) {
149  jump_to_campaign_.jump_ = true;
151  std::cerr << "selected campaign id: [" << jump_to_campaign_.campaign_id_ << "]\n";
152 
155  std::cerr << "selected difficulty: [" << jump_to_campaign_.difficulty_ << "]\n";
156  }
157  else
158  jump_to_campaign_.difficulty_ = -1; // let the user choose the difficulty
159 
162  std::cerr << "selected scenario id: [" << jump_to_campaign_.scenario_id_ << "]\n";
163  }
164  }
165  if (cmdline_opts_.clock)
167  if (cmdline_opts_.debug) {
168  game_config::debug = true;
169  game_config::mp_debug = true;
170  }
171 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
172  if (cmdline_opts_.debug_dot_domain)
173  gui2::tdebug_layout_graph::set_domain (*cmdline_opts_.debug_dot_domain);
174  if (cmdline_opts_.debug_dot_level)
176 #endif
177  if (cmdline_opts_.editor)
178  {
179  jump_to_editor_ = true;
180  if(!cmdline_opts_.editor->empty())
182  }
183  if (cmdline_opts_.fps)
186  video().set_fullscreen(true);
187  if (cmdline_opts_.load)
189  if (cmdline_opts_.max_fps) {
190  int fps;
191  //FIXME: remove the next line once the weird util.cpp specialized template lexical_cast_default() linking issue is solved
192  fps = lexical_cast_default<int>("", 50);
193  fps = *cmdline_opts_.max_fps;
194  fps = std::min<int>(fps, 1000);
195  fps = std::max<int>(fps, 1);
196  fps = 1000 / fps;
197  // increase the delay to avoid going above the maximum
198  if(1000 % fps != 0) {
199  ++fps;
200  }
202  }
204  no_sound = true;
206  }
208  gui2::new_widgets = true;
210  game_config::no_delay = true;
212  no_music = true;
214  no_sound = true;
216  const int xres = cmdline_opts_.resolution->get<0>();
217  const int yres = cmdline_opts_.resolution->get<1>();
218  if(xres > 0 && yres > 0) {
219  preferences::_set_resolution(std::make_pair(xres, yres));
221  }
222  }
224  //TODO it could be simplified to use cmdline_opts_ directly if there is no other way to enter screenshot mode
227  no_sound = true;
229  }
230  if (cmdline_opts_.server){
231  jump_to_multiplayer_ = true;
232  //Do we have any server specified ?
233  if (!cmdline_opts_.server->empty())
235  else //Pick the first server in config
236  {
239  else
240  multiplayer_server_ = "";
241  }
242  }
243  if (cmdline_opts_.username) {
245  preferences::set_login(*cmdline_opts_.username);
246  }
247  if (cmdline_opts_.password) {
249  preferences::set_password(*cmdline_opts_.password);
250  }
251  if (cmdline_opts_.test)
252  {
253  if (!cmdline_opts_.test->empty())
254  test_scenario_ = *cmdline_opts_.test;
255  }
256  if (cmdline_opts_.unit_test)
257  {
258  if (!cmdline_opts_.unit_test->empty()) {
259  test_scenario_ = *cmdline_opts_.unit_test;
260  }
261 
262  }
263  if (cmdline_opts_.windowed)
264  video().set_fullscreen(false);
265  if (cmdline_opts_.with_replay)
267 
268  std::cerr
269  << "\nData directory: " << game_config::path
270  << "\nUser configuration directory: " << filesystem::get_user_config_dir()
271  << "\nUser data directory: " << filesystem::get_user_data_dir()
272  << "\nCache directory: " << filesystem::get_cache_dir()
273  << '\n';
274  std::cerr << '\n';
275 
276  // disable sound in nosound mode, or when sound engine failed to initialize
277  if (no_sound || ((preferences::sound_on() || preferences::music_on() ||
279  !sound::init_sound())) {
280  preferences::set_sound(false);
281  preferences::set_music(false);
284  }
285  else if (no_music) { // else disable the music in nomusic mode
286  preferences::set_music(false);
287  }
288 }
289 
291 {
293  return false;
294 
295  if(SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
296  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
297  return false;
298 
299  int joysticks = SDL_NumJoysticks();
300  if (joysticks == 0) return false;
301 
302  SDL_JoystickEventState(SDL_ENABLE);
303 
304  bool joystick_found = false;
305  for (int i = 0; i<joysticks; i++) {
306 
307  if (SDL_JoystickOpen(i))
308  joystick_found = true;
309  }
310  return joystick_found;
311 }
312 
314 {
315  if(!::load_language_list())
316  return false;
317 
318  language_def locale;
319  if(cmdline_opts_.language) {
320  std::vector<language_def> langs = get_languages();
321  for(const language_def & def : langs) {
322  if(def.localename == *cmdline_opts_.language) {
323  locale = def;
324  break;
325  }
326  }
327  if(locale.localename.empty()) {
328  std::cerr << "Language symbol '" << *cmdline_opts_.language << "' not found.\n";
329  return false;
330  }
331  } else {
332  locale = get_locale();
333  }
334  ::set_language(locale);
335 
336  return true;
337 }
338 
340 {
341  // Handle special commandline launch flags
344  std::cerr << "--nogui flag is only valid with --multiplayer or --screenshot or --plugin flags\n";
345  return false;
346  }
347  video().make_fake();
348  game_config::no_delay = true;
349  return true;
350  }
351 
352  // Initialize a new window
353  video().init_window();
354 
355  // Set window title and icon
357 
358 #if !(defined(__APPLE__))
359  surface icon(image::get_image("icons/icon-game.png", image::UNSCALED));
360  if(icon != nullptr) {
361 
362  video().set_window_icon(icon);
363  }
364 #endif
365  return true;
366 }
367 
369 {
370  bool error = false;
371 
372  std::cerr << "Checking lua scripts... ";
373 
375  plugins_manager::get()->get_kernel_base()->load_package(); //load the "package" package, so that scripts can get what packages they want
376  }
377 
378  // get the application lua kernel, load and execute script file, if script file is present
380  {
382 
383  if (!sf->fail()) {
384  /* Cancel all "jumps" to editor / campaign / multiplayer */
385  jump_to_multiplayer_ = false;
386  jump_to_editor_ = false;
387  jump_to_campaign_.jump_ = false;
388 
389  std::string full_script((std::istreambuf_iterator<char>(*sf)), std::istreambuf_iterator<char>());
390 
391  std::cerr << "\nRunning lua script: " << *cmdline_opts_.script_file << std::endl;
392 
393  plugins_manager::get()->get_kernel_base()->run(full_script.c_str());
394  } else {
395  std::cerr << "Encountered failure when opening script '" << *cmdline_opts_.script_file << "'\n";
396  error = true;
397  }
398  }
399 
401  {
403 
404  std::cerr << "Loading a plugin file'" << filename << "'...\n";
405 
407 
408  try {
409  if (sf->fail()) {
410  throw std::runtime_error("failed to open plugin file");
411  }
412 
413  /* Cancel all "jumps" to editor / campaign / multiplayer */
414  jump_to_multiplayer_ = false;
415  jump_to_editor_ = false;
416  jump_to_campaign_.jump_ = false;
417 
418  std::string full_plugin((std::istreambuf_iterator<char>(*sf)), std::istreambuf_iterator<char>());
419 
421 
422  size_t i = pm.add_plugin(filename, full_plugin);
423 
424  for (size_t j = 0 ; j < pm.size(); ++j) {
425  std::cerr << j << ": " << pm.get_name(j) << " -- " << pm.get_detailed_status(j) << std::endl;
426  }
427 
428  std::cerr << "Starting a plugin...\n";
429  pm.start_plugin(i);
430 
431  for (size_t j = 0 ; j < pm.size(); ++j) {
432  std::cerr << j << ": " << pm.get_name(j) << " -- " << pm.get_detailed_status(j) << std::endl;
433  }
434 
435  plugins_context pc("init");
436 
437  for (size_t repeat = 0; repeat < 5; ++repeat) {
438  std::cerr << "Playing a slice...\n";
439  pc.play_slice();
440 
441  for (size_t j = 0 ; j < pm.size(); ++j) {
442  std::cerr << j << ": " << pm.get_name(j) << " -- " << pm.get_detailed_status(j) << std::endl;
443  }
444  }
445 
446  return true;
447  } catch (std::exception & e) {
448  gui2::show_error_message(video(), std::string("When loading a plugin, error:\n") + e.what());
449  error = true;
450  }
451  }
452 
453  if (!error) {
454  std::cerr << "ok\n";
455  }
456 
457  return !error;
458 }
459 
461 {
462  static bool first_time = true;
463 
464  if(!cmdline_opts_.test) {
465  return true;
466  }
467  if(!first_time)
468  return false;
469 
470  first_time = false;
471 
472  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::TEST;
474 
475  state_.mp_settings().mp_era = "era_default";
476  state_.mp_settings().show_connect = false;
477 
479  config_of("next_scenario", test_scenario_)
480  );
481 
482 
483 
485  load_game_config_for_game(state_.classification());
486 
487  try {
489  ccontroller.play_game();
490  } catch (game::load_game_exception &) {
491  return true;
492  }
493 
494  return false;
495 }
496 
497 // Same as play_test except that we return the results of play_game.
499 {
500  static bool first_time_unit = true;
501 
502  if(!cmdline_opts_.unit_test) {
503  return 0;
504  }
505  if(!first_time_unit)
506  return 0;
507 
508  first_time_unit = false;
509 
510  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::TEST;
513  config_of("next_scenario", test_scenario_)
514  );
515 
516 
518  load_game_config_for_game(state_.classification());
519 
520  try {
521  campaign_controller ccontroller(video(), state_, game_config_manager::get()->game_config(), game_config_manager::get()->terrain_types(), true);
522  LEVEL_RESULT res = ccontroller.play_game();
523  if (!(res == LEVEL_RESULT::VICTORY) || lg::broke_strict()) {
524  return 1;
525  }
526  } catch (game::load_game_exception &) {
527  std::cerr << "Load_game_exception encountered while loading the unit test!" << std::endl;
528  return 1; //failed to load the unit test scenario
529  } catch(twml_exception& e) {
530  std::cerr << "Caught WML Exception:" << e.dev_message << std::endl;
531  return 1;
532  }
533 
535 
537  return 0; //we passed, huzzah!
538 
540  save.save_game_automatic(video(), false, "unit_test_replay"); //false means don't check for overwrite
541 
543 
544  //game::load_game_exception::game = *cmdline_opts_.load
545  game::load_game_exception::game = "unit_test_replay";
546  // game::load_game_exception::game = "Unit_test_" + test_scenario_ + "_replay";
547 
550 
551  if (!load_game()) {
552  std::cerr << "Failed to load the replay!" << std::endl;
553  return 3; //failed to load replay
554  }
555 
556  try {
557  campaign_controller ccontroller(video(), state_, game_config_manager::get()->game_config(), game_config_manager::get()->terrain_types(), true);
558  LEVEL_RESULT res = ccontroller.play_replay();
559  if (!(res == LEVEL_RESULT::VICTORY)) {
560  std::cerr << "Observed failure on replay" << std::endl;
561  return 4;
562  }
564  } catch (game::load_game_exception &) {
565  std::cerr << "Load_game_exception encountered during play_replay!" << std::endl;
566  return 3; //failed to load replay
567  } catch(twml_exception& e) {
568  std::cerr << "WML Exception while playing replay: " << e.dev_message << std::endl;
569  return 4; //failed with an error during the replay
570  }
571 
572  return 0; //we passed, huzzah!
573 }
574 
576 {
578  return true;
579  }
580 
582 
584 
587  return false;
588 }
589 
591 {
593  return true;
594  }
595 
596  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::MULTIPLAYER;
597  DBG_GENERAL << "Current campaign type: " << state_.classification().campaign_type << std::endl;
598 
599  try {
601  load_game_config_for_game(state_.classification());
602  } catch(config::error& e) {
603  std::cerr << "Error loading game config: " << e.what() << std::endl;
604  return false;
605  }
606 
607  // A default output filename
608  std::string outfile = "wesnoth_image.bmp";
609 
610  // If a output path was given as an argument, use that instead
612  outfile = *cmdline_opts_.render_image_dst;
613  }
614 
615  if (!image::save_image(*cmdline_opts_.render_image, outfile)) {
616  exit(1);
617  }
618 
619  return false;
620 }
621 
623 {
624  return !game::load_game_exception::game.empty();
625 }
626 
628 {
629  assert(game_config_manager::get());
630 
631  DBG_GENERAL << "Current campaign type: " << state_.classification().campaign_type << std::endl;
632 
634  state_);
635 
636  try {
639  return false;
640  }
641 
642  try {
644  load_game_config_for_game(state_.classification());
645  } catch(config::error&) {
646  return false;
647  }
648 
649  load.set_gamestate();
650 
651  } catch(config::error& e) {
652  if(e.message.empty()) {
653  gui2::show_error_message(video(), _("The file you have tried to load is corrupt"));
654  }
655  else {
656  gui2::show_error_message(video(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
657  }
658  return false;
659  } catch(twml_exception& e) {
660  e.show(video());
661  return false;
662  } catch(filesystem::io_exception& e) {
663  if(e.message.empty()) {
664  gui2::show_error_message(video(), _("File I/O Error while reading the game"));
665  } else {
666  gui2::show_error_message(video(), _("File I/O Error while reading the game: '") + e.message + '\'');
667  }
668  return false;
669  } catch(game::error& e) {
670  if(e.message.empty()) {
671  gui2::show_error_message(video(), _("The file you have tried to load is corrupt"));
672  }
673  else {
674  gui2::show_error_message(video(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
675  }
676  return false;
677  }
678 
679  play_replay_ = load.show_replay();
680  LOG_CONFIG << "is middle game savefile: " << (state_.is_mid_game_save() ? "yes" : "no") << "\n";
681  LOG_CONFIG << "show replay: " << (play_replay_ ? "yes" : "no") << "\n";
682  // in case load.show_replay() && !state_.is_mid_game_save()
683  // there won't be any turns to replay, but the
684  // user gets to watch the intro sequence again ...
685 
686  if(state_.is_mid_game_save() && load.show_replay())
687  {
689  }
690 
691  if(state_.classification().campaign_type == game_classification::CAMPAIGN_TYPE::MULTIPLAYER) {
693  }
694 
695  if (load.cancel_orders()) {
697  }
698 
699  return true;
700 }
701 
703 {
704  state_ = saved_game();
705  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::TUTORIAL;
706  state_.classification().campaign_define = "TUTORIAL";
707  state_.mp_settings().mp_era = "era_default";
708  state_.mp_settings().show_connect = false;
710  config_of("next_scenario", "tutorial")
711  );
712 
713 }
714 
715 void game_launcher::mark_completed_campaigns(std::vector<config> &campaigns)
716 {
717  for (config &campaign : campaigns) {
718  campaign["completed"] = preferences::is_campaign_completed(campaign["id"]);
719  }
720 }
721 
723 {
724  state_ = saved_game();
726  state_.mp_settings().show_connect = false;
727  play_replay_ = false;
728 
730  state_, jump_to_campaign_, true);
731 }
732 
734 {
736 }
737 
739 {
741  if(new_campaign()) {
742  jump_to_campaign_.jump_ = false;
744  }else{
745  jump_to_campaign_.jump_ = false;
746  return false;
747  }
748  }
749  return true;
750 }
751 
753 {
755  jump_to_multiplayer_ = false;
756  if(play_multiplayer()){
757  ;
758  }else{
759  return false;
760  }
761  }
762  return true;
763 }
764 
766 {
767  if(jump_to_editor_){
768  jump_to_editor_ = false;
771  {
772  return false;
773  }
775  }
776  return true;
777 }
778 
780 {
781  const std::string wesnothd_program =
784 
785  std::string config = filesystem::get_user_config_dir() + "/lan_server.cfg";
786  if (!filesystem::file_exists(config)) {
787  // copy file if it isn't created yet
789  }
790 
791 #ifndef _WIN32
792  std::string command = "\"" + wesnothd_program +"\" -c \"" + config + "\" -d -t 2 -T 5";
793 #else
794  // start wesnoth as background job
795  std::string command = "cmd /C start \"wesnoth server\" /B \"" + wesnothd_program + "\" -c \"" + config + "\" -t 2 -T 5";
796  // Make sure wesnothd's console output is visible on the console window by
797  // disabling SDL's stdio redirection code for this and future child
798  // processes. No need to bother cleaning this up because it's only
799  // meaningful to SDL applications during pre-main initialization.
800  SetEnvironmentVariableA("SDL_STDIO_REDIRECT", "0");
801 #endif
802  LOG_GENERAL << "Starting wesnothd: "<< command << "\n";
803  if (std::system(command.c_str()) == 0) {
804  // Give server a moment to start up
805  SDL_Delay(50);
806  return;
807  }
809 
810  // Couldn't start server so throw error
811  WRN_GENERAL << "Failed to run server start script" << std::endl;
812  throw game::mp_server_error("Starting MP server failed!");
813 }
814 
816 {
817  int res;
818 
819  state_ = saved_game();
820  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::MULTIPLAYER;
821 
822  //Print Gui only if the user hasn't specified any server
823  if( multiplayer_server_.empty() ){
824 
825  int start_server;
826  do {
827  start_server = 0;
828 
830 
831  dlg.show(video());
832 
833  if(dlg.get_retval() == gui2::twindow::OK) {
834  res = dlg.get_choice();
835  } else {
836  return false;
837 
838  }
839 
840  if (res == 2 && preferences::mp_server_warning_disabled() < 2) {
841  start_server = !gui2::tmp_host_game_prompt::execute(video());
842  }
843  } while (start_server);
844  if (res < 0) {
845  return false;
846  }
847 
848  }else{
849  res = 4;
850  }
851 
852  try {
853  if (res == 2)
854  {
855  try {
856  start_wesnothd();
857  } catch(game::mp_server_error&)
858  {
860 
861  try {
862  start_wesnothd();
863  } catch(game::mp_server_error&)
864  {
865  return false;
866  }
867  }
868 
869 
870  }
871  //create_engine already calls game_config_manager::get()->load_config but maybe its better to have MULTIPLAYER defined while we are in the lobby.
873 
874  events::discard_input(); // prevent the "keylogger" effect
876 
877  if(res == 3) {
880  } else if((res >= 0 && res <= 2) || res == 4) {
881  std::string host;
882  if(res == 0) {
883  host = preferences::server_list().front().address;
884  }else if(res == 2) {
885  host = "localhost";
886  }else if(res == 4){
887  host = multiplayer_server_;
888  multiplayer_server_ = "";
889  }
891  state_, host);
892  }
893 
894  } catch(game::mp_server_error& e) {
895  gui2::show_error_message(video(), _("Error while starting server: ") + e.message);
896  } catch(game::load_game_failed& e) {
897  gui2::show_error_message(video(), _("The game could not be loaded: ") + e.message);
898  } catch(game::game_error& e) {
899  gui2::show_error_message(video(), _("Error while playing the game: ") + e.message);
900  } catch (mapgen_exception& e) {
901  gui2::show_error_message(video(), std::string(_("Map generator error: ") + e.message));
902  } catch(wesnothd_error& e) {
903  if(e.message != "") {
904  ERR_NET << "caught network error: " << e.message << std::endl;
906  , ""
907  , translation::gettext(e.message.c_str()));
908  } else {
909  ERR_NET << "caught network error" << std::endl;
910  }
911  } catch(config::error& e) {
912  if(e.message != "") {
913  ERR_CONFIG << "caught config::error: " << e.message << std::endl;
915  } else {
916  ERR_CONFIG << "caught config::error" << std::endl;
917  }
918  } catch(incorrect_map_format_error& e) {
919  gui2::show_error_message(video(), std::string(_("The game map could not be loaded: ")) + e.message);
920  } catch (game::load_game_exception &) {
921  //this will make it so next time through the title screen loop, this game is loaded
922  } catch(twml_exception& e) {
923  e.show(video());
924  } catch (game::error & e) {
925  std::cerr << "caught game::error...\n";
926  gui2::show_error_message(video(), _("Error: ") + e.message);
927  }
928 
929  return false;
930 }
931 
933 {
935  return true;
936  }
937 
938  DBG_MP << "starting multiplayer game from the commandline" << std::endl;
939 
940  // These are all the relevant lines taken literally from play_multiplayer() above
941  state_ = saved_game();
942  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::MULTIPLAYER;
943 
945  load_game_config_for_game(state_.classification());
946 
947  events::discard_input(); // prevent the "keylogger" effect
949 
952 
953  return false;
954 }
955 
957 {
959  dlg.show(video());
960  if (dlg.get_retval() != gui2::twindow::OK) return false;
961 
964  }
965 
966  return true;
967 }
968 
970 {
973 }
974 
976 {
977  if(play_replay_)
978  {
979  play_replay();
980  return;
981  }
982 
983  gui2::tloadscreen::display(video(), [this, reload]() {
984 
985  gui2::tloadscreen::progress("load data");
986  if(reload == RELOAD_DATA) {
987  try {
989  load_game_config_for_game(state_.classification());
990  } catch(config::error&) {
991  return;
992  }
993  }
994  });
995 
996  try {
998  LEVEL_RESULT result = ccontroller.play_game();
999  // don't show The End for multiplayer scenario
1000  // change this if MP campaigns are implemented
1001  if(result == LEVEL_RESULT::VICTORY && !state_.classification().is_normal_mp_game()) {
1006  }
1007  }
1008 
1010  } catch (game::load_game_exception &) {
1011  //this will make it so next time through the title screen loop, this game is loaded
1012  } catch(twml_exception& e) {
1013  e.show(video());
1014  }
1015 }
1016 
1018 {
1019  try {
1021  ccontroller.play_replay();
1022 
1024  } catch (game::load_game_exception &) {
1025  //this will make it so next time through the title screen loop, this game is loaded
1026  } catch(twml_exception& e) {
1027  e.show(video());
1028  }
1029 }
1030 
1032 {
1033  while(true){
1035 
1037 
1039  game_config_manager::get()->game_config(), video(), filename);
1040 
1041  if(res != editor::EXIT_RELOAD_DATA)
1042  return res;
1043 
1046  }
1047  return editor::EXIT_ERROR; // not supposed to happen
1048 }
1049 
1051 {
1052  try {
1055  } catch (...) {}
1056 }
boost::optional< std::string > core_id
Non-empty if –core was given on the command line. Chooses the core to be loaded. ...
void show_about(CVideo &video, const std::string &campaign)
Show credits with list of contributors.
Definition: about.cpp:208
-file gamestatus.hpp
CVideo & video()
boost::optional< std::string > script_file
File to load lua script from.
An error occured during when trying to coommunicate with the wesnothd server.
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:40
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
void set_password(const std::string &password)
unsigned int end_text_duration
for how long the end-of-campaign text is shown
void set_window_icon(surface &icon)
Sets the icon of the main window.
Definition: video.cpp:556
bool set_sound(bool ison)
void close_sound()
Definition: sound.cpp:362
std::string get_program_invocation(const std::string &program_name)
Returns the appropriate invocation for a Wesnoth-related binary, assuming that it is located in the s...
LEVEL_RESULT play_replay()
bool load_game()
Load a game without providing any information.
Definition: savegame.cpp:152
static lg::log_domain log_mp_create("mp/create")
void show_error_message(CVideo &video, const std::string &message, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:198
bool turn_bell()
void discard_input()
Discards all input events.
Definition: events.cpp:657
void _set_resolution(const std::pair< int, int > &res)
void show_wesnothd_server_search(CVideo &video)
bool end_credits
whether to show the standard credits at the end
LEVEL_RESULT play_game()
bool nogui
True if –nogui was given on the command line. Disables GUI.
static std::string game
Definition: game_errors.hpp:89
bool cancel_orders() const
Definition: savegame.hpp:62
The class for loading a savefile.
Definition: savegame.hpp:36
bool script_unsafe_mode
Whether to load the "package" package for the scripting environment. (This allows to load arbitrary l...
int get_retval() const
Definition: dialog.hpp:161
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:154
void _set_maximized(bool ison)
std::string label
Name of the game (e.g.
void disable_preferences_save()
size_t add_plugin(const std::string &name, const std::string &prog)
Definition: manager.cpp:121
const char * what() const
Definition: exceptions.hpp:35
void set_gamestate()
Generate the gamestate out of the loaded game config.
Definition: savegame.cpp:284
void start_client(CVideo &video, const config &game_config, saved_game &state, const std::string &host)
Starts a multiplayer game in client mode.
static bool skip_version_check
Definition: game_errors.hpp:94
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define DBG_MP
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
Error used when game loading fails.
Definition: game_errors.hpp:30
void show_preferences()
Definition: video.hpp:58
bool is_campaign_completed(const std::string &campaign_id)
This file contains the window object, this object is a top level container which has the event manage...
std::string network_host()
void unify_controllers()
Definition: saved_game.cpp:583
const language_def & get_locale()
Definition: language.cpp:253
void show(CVideo &video)
Shows the error in a dialog.
void set_login(const std::string &username)
void mark_completed_campaigns(std::vector< config > &campaigns)
boost::optional< std::string > campaign_scenario
Non-empty if –campaign-scenario was given on the command line. Chooses starting scenario in the camp...
std::string get_default_title_string()
boost::optional< int > max_fps
Max FPS specified by –max-fps option.
bool fps
True if –fps was given on the command line. Shows number of fps.
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
bool change_language()
bool is_mid_game_save()
Definition: saved_game.hpp:88
static bool execute(CVideo &video)
The execute function see tdialog for more information.
bool noreplaycheck
True if –noreplaycheck was given on the comand line. Dependent on –unit.
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
void the_end(CVideo &video, std::string text, unsigned int duration)
Displays a simple fading screen with any user-provided text.
Definition: intro.cpp:31
-file util.hpp
Definitions for the interface to Wesnoth Markup Language (WML).
void set_language(const std::string &slocale, const std::vector< std::string > *alternates)
Definition: gettext.cpp:126
boost::optional< std::string > plugin_file
File to load a lua plugin (similar to a script) from. Experimental / may replace script.
bool sound_on()
#define DBG_GENERAL
jump_to_campaign_info jump_to_campaign_
boost::optional< std::string > load
Non-empty if –load was given on the command line. Savegame specified to load after start...
bool save_image(const locator &i_locator, const std::string &filename)
Definition: image.cpp:1249
void flush_cache()
Definition: image.cpp:191
bool init_sound()
Definition: sound.cpp:314
static lg::log_domain log_config("config")
bool broke_strict()
Definition: log.cpp:170
std::string get_cwd()
void set_mp_server_program_name(const std::string &path)
void set_window_title(const std::string &title)
Sets the title of the main window.
Definition: video.cpp:550
bool play_render_image_mode()
bool headless_unit_test
True if –unit is used and –showgui is not present.
static game_config_manager * get()
void make_fake()
Definition: video.cpp:355
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
#define ERR_CONFIG
bool joystick_support_enabled()
GLuint64EXT * result
Definition: glew.h:10727
Dialog is closed with ok button.
Definition: window.hpp:125
static lg::log_domain log_enginerefac("enginerefac")
This file contains the settings handling of the widget library.
bool nodelay
True if –nodelay was given on the command line.
std::string get_user_data_dir()
std::string normalize_path(const std::string &path)
Returns the absolute path of a file.
void write_file(const std::string &fname, const std::string &data)
Throws io_exception if an error occurs.
void show_preferences_dialog(CVideo &video, const config &game_cfg, const DIALOG_OPEN_TO initial_view)
static lg::log_domain log_network("network")
std::string multiplayer_server_
std::string campaign_define
If there is a define the campaign uses to customize data.
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
editor::EXIT_STATUS start_editor()
std::istream * istream_file(const std::string &fname, bool treat_failure_as_error=true)
bool init_window()
Initializes a new window, taking into account any preiously saved states.
Definition: video.cpp:390
std::string localename
Definition: language.hpp:46
void load_package()
Loads the "package" package into the Lua environment.
std::string dev_message
The message for developers telling which problem was triggered, this shouldn't be translated...
boost::optional< std::string > editor
Non-empty if –editor was given on the command line. Goes directly into editor. If string is longer t...
void set_show_fps(bool value)
const std::vector< game_config::server_info > & server_list()
std::string end_text
end-of-campaign text
void set_core_id(const std::string &core_id)
std::string path
boost::optional< std::string > test
Non-empty if –test was given on the command line. Goes directly into test mode, into a scenario...
void init_textdomains(const config &cfg)
Initializes the list of textdomains from a configuration object.
Definition: language.cpp:293
bool multiplayer
True if –multiplayer was given on the command line. Goes directly into multiplayer mode...
bool UI_sound_on()
game_launcher(const commandline_options &cmdline_opts, const char *appname)
std::string campaign
the campaign being played
bool clock
True if –clock was given on the command line. Enables.
static UNUSEDNOWARN std::string gettext(const char *str)
Definition: gettext.hpp:64
Error used for any general game error, e.g.
Definition: game_errors.hpp:46
Templates and utility-routines for strings and numbers.
static void display(CVideo &video, std::function< void()> f)
Definition: loadscreen.cpp:181
bool enter_create_mode(CVideo &video, const config &game_config, saved_game &state, jump_to_campaign_info jump_to_campaign, bool local_players_only)
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
std::string screenshot_map_
#define LOG_CONFIG
void set_draw_delay(int value)
boost::optional< std::string > render_image
Image path to render. First parameter after –render-image.
void set_level(const std::string &value)
boost::optional< int > campaign_difficulty
Non-empty if –campaign-difficulty was given on the command line. Numerical difficulty of the campaig...
void load_game_config_for_create(bool is_mp)
bool nomusic
True if –nomusic was given on the command line. Disables music.
void run(char const *prog, int nArgs=0)
Runs a plain script.
std::string get_detailed_status(size_t idx)
Definition: manager.cpp:86
void update_font_path() const
Updates the font path, when initialized it sets the fontpath to game_config::path.
Definition: font.cpp:386
std::string get_cache_dir()
GLuint res
Definition: glew.h:9258
static void progress(const char *stage_name=nullptr)
Definition: loadscreen.cpp:128
int mp_server_warning_disabled()
#define WRN_GENERAL
std::string jump_to_campaign_id() const
bool debug
True if –debug was given on the command line. Enables debug mode.
std::string get_mp_server_program_name()
boost::optional< std::string > screenshot_map_file
Map file to make a screenshot of. First parameter given after –screenshot.
std::string get_wml_location(const std::string &filename, const std::string &current_dir=std::string())
Returns a complete path to the actual WML file or directory or an empty string if the file isn't pres...
void clean_saves(const std::string &label)
Delete all autosaves of a certain scenario.
Definition: savegame.cpp:71
Game configuration data as global variables.
Definition: build_info.cpp:38
bool new_widgets
True if –new-widgets was given on the command line. Hidden option to enable the new widget toolkit...
bool play_multiplayer()
#define ERR_NET
An exception object used when an IO error occurs.
Definition: filesystem.hpp:40
Exception used to signal that the user has decided to abort a game, and to load another game instead...
Definition: game_errors.hpp:62
bool music_on()
void add_completed_campaign(const std::string &campaign_id, const std::string &difficulty_level)
bool load_language_list()
Definition: language.cpp:94
size_t i
Definition: function.cpp:1057
language_list get_languages()
Definition: language.cpp:118
void set_fullscreen(bool ison)
Definition: video.cpp:670
bool set_UI_sound(bool ison)
bool goto_multiplayer()
Declarations for File-IO.
bool show_replay() const
Definition: savegame.hpp:61
static void save(LexState *ls, int c)
Definition: llex.cpp:51
void launch_game(RELOAD_GAME_DATA reload=RELOAD_DATA)
Class for replay saves (either manually or automatically).
Definition: savegame.hpp:206
-file mapgen.hpp
std::string get_name(size_t idx)
Definition: manager.cpp:97
std::string difficulty
The difficulty level the game is being played on.
boost::optional< std::string > render_image_dst
Output file to put rendered image path in. Optional second parameter after –render-image.
std::string get_user_config_dir()
GLsizeiptr size
Definition: glew.h:1649
bool screenshot
True if –screenshot was given on the command line. Starts Wesnoth in screenshot mode.
void cancel_orders()
Definition: saved_game.cpp:567
boost::optional< std::string > unit_test
Non-empty if –unit was given on the command line. Goes directly into unit test mode, into a scenario, if specified.
const commandline_options & cmdline_opts_
void start_local_game_commandline(CVideo &video, const config &game_config, saved_game &state, const commandline_options &cmdline_opts)
Starts a multiplayer game in single-user mode.
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
void start_plugin(size_t idx)
Definition: manager.cpp:104
game_classification & classification()
Definition: saved_game.hpp:54
std::string screenshot_filename_
void set_carryover_sides_start(config carryover_sides_start)
Definition: saved_game.cpp:113
saved_game state_
CALLABLE_WRAPPER_INPUT_END if(key=="terrain")
bool show_debug_clock_button
Do we wish to show the button for the debug clock.
bool set_music(bool ison)
Standard logging facilities (interface).
bool is_loading() const
boost::optional< std::string > screenshot_output_file
Output file to put screenshot in. Second parameter given after –screenshot.
bool set_turn_bell(bool ison)
void clear_loaded_game()
std::string message
Definition: exceptions.hpp:29
bool fullscreen
True if –fullscreen was given on the command line. Starts Wesnoth in fullscreen mode.
boost::optional< std::string > language
Non-empty if –language was given on the command line. Sets the language for this session...
#define e
std::string test_scenario_
bool nosound
True if –nosound was given on the command line. Disables sound.
bool play_screenshot_mode()
lua_kernel_base * get_kernel_base()
Definition: manager.cpp:66
boost::optional< std::string > campaign
Non-empty if –campaign was given on the command line. ID of the campaign we want to start...
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
Helper class, don't construct this directly.
void clear_current_scenario()
Definition: statistics.cpp:623
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
Definition: saved_game.hpp:58
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
bool save_game_automatic(CVideo &video, bool ask_for_overwrite=false, const std::string &filename="")
Saves a game without user interaction, unless the file exists and it should be asked to overwrite it...
Definition: savegame.cpp:350
const font::manager font_manager_
bool init_lua_script()
std::vector< server_info > server_list
boost::optional< std::string > server
Non-empty if –server was given on the command line. Connects Wesnoth to specified server...
bool play_multiplayer_commandline()
static std::string difficulty
Definition: game_errors.hpp:93
boost::optional< boost::tuple< int, int > > resolution
Pair of AxB values specified after –resolution. Changes Wesnoth resolution.
static plugins_manager * get()
Definition: manager.cpp:61
void play_slice()
Definition: context.cpp:104
EXIT_STATUS start(const config &game_conf, CVideo &video, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Definition: editor_main.cpp:28
#define LOG_GENERAL
static void delete_empty_menu()
Explicit freeing of class static resources.
void start_local_game(CVideo &video, const config &game_config, saved_game &state)
Starts a multiplayer game in single-user mode.