ManaPlus
client.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "progs/manaplus/client.h"
25 
26 #include "chatlogger.h"
27 #include "configmanager.h"
28 #include "dirs.h"
29 #include "eventsmanager.h"
30 #include "game.h"
31 #include "graphicsmanager.h"
32 #include "main.h"
33 #include "party.h"
34 #include "pincodemanager.h"
35 #include "settings.h"
36 #include "soundmanager.h"
37 #include "spellmanager.h"
38 
39 #include "being/localclan.h"
40 #include "being/localplayer.h"
41 #include "being/playerinfo.h"
42 #include "being/playerrelations.h"
43 
44 #include "const/net/net.h"
45 
47 
48 #include "fs/virtfs/fs.h"
49 #include "fs/virtfs/tools.h"
50 
51 #include "gui/dialogsmanager.h"
52 #include "gui/gui.h"
53 #include "gui/skin.h"
54 #include "gui/popupmanager.h"
55 #include "gui/windowmanager.h"
56 
61 
68 #include "gui/windows/npcdialog.h"
69 #include "gui/windows/okdialog.h"
74 #include "gui/windows/quitdialog.h"
76 
77 #include "gui/widgets/button.h"
79 #include "gui/widgets/desktop.h"
81 
82 #include "input/inputmanager.h"
83 #include "input/joystick.h"
84 #include "input/keyboardconfig.h"
85 
87 
88 #include "net/charserverhandler.h"
89 #include "net/chathandler.h"
90 #include "net/download.h"
91 #include "net/gamehandler.h"
92 #include "net/generalhandler.h"
93 #include "net/guildhandler.h"
94 #include "net/inventoryhandler.h"
95 #include "net/ipc.h"
96 #include "net/loginhandler.h"
97 #include "net/net.h"
99 #include "net/useragent.h"
100 #include "net/packetlimiter.h"
101 #include "net/partyhandler.h"
102 
103 #ifdef TMWA_SUPPORT
104 #include "net/tmwa/guildmanager.h"
105 #endif // TMWA_SUPPORT
106 
107 #include "particle/particleengine.h"
108 
109 #include "resources/dbmanager.h"
110 #include "resources/imagehelper.h"
111 
113 
115 
117 
118 #include "utils/checkutils.h"
119 #include "utils/cpu.h"
120 #include "utils/delete2.h"
121 #include "utils/dumplibs.h"
122 #include "utils/dumpsizes.h"
123 #include "utils/env.h"
124 #include "utils/fuzzer.h"
125 #include "utils/gettext.h"
126 #include "utils/gettexthelper.h"
127 #include "utils/mrand.h"
128 #ifdef ANDROID
129 #include "fs/paths.h"
130 #endif // ANDROID
131 #include "utils/perfstat.h"
132 #include "utils/sdlcheckutils.h"
133 #include "utils/sdlhelper.h"
134 #include "utils/timer.h"
135 
137 
139 #include "listeners/errorlistener.h"
140 
141 #ifdef USE_OPENGL
142 #include "test/testlauncher.h"
143 #include "test/testmain.h"
144 #else // USE_OPENGL
145 #include "configuration.h"
146 #endif // USE_OPENGL
147 
148 #ifdef WIN32
149 PRAGMA48(GCC diagnostic push)
150 PRAGMA48(GCC diagnostic ignored "-Wshadow")
151 #include <SDL_syswm.h>
152 PRAGMA48(GCC diagnostic pop)
153 #include "fs/specialfolder.h"
154 #undef ERROR
155 #endif // WIN32
156 
157 #ifdef ANDROID
158 #ifndef USE_SDL2
159 PRAGMA48(GCC diagnostic push)
160 PRAGMA48(GCC diagnostic ignored "-Wshadow")
161 #include <SDL_screenkeyboard.h>
162 PRAGMA48(GCC diagnostic pop)
163 #include <fstream>
164 #endif // USE_SDL2
165 #endif // ANDROID
166 
167 #include <sys/stat.h>
168 
169 #ifdef USE_MUMBLE
170 #include "mumblemanager.h"
171 #endif // USE_MUMBLE
172 
173 PRAGMA48(GCC diagnostic push)
174 PRAGMA48(GCC diagnostic ignored "-Wshadow")
175 #ifdef USE_SDL2
176 #include <SDL2_framerate.h>
177 #else // USE_SDL2
178 #include <SDL_framerate.h>
179 #endif // USE_SDL2
180 PRAGMA48(GCC diagnostic pop)
181 
182 #include "debug.h"
183 
184 std::string errorMessage;
186 
187 Client *client = nullptr;
188 
189 extern FPSmanager fpsManager;
190 extern int evolPacketOffset;
191 
192 volatile bool runCounters;
193 bool isSafeMode = false;
199 int packetsType = 0;
200 int itemIdLen = 2;
201 bool packets_main = true;
202 bool packets_re = false;
203 bool packets_zero = false;
204 unsigned int tmwServerVersion = 0;
205 time_t start_time;
206 unsigned int mLastHost = 0;
207 unsigned long mSearchHash = 0;
209 volatile bool isTerminate = false;
210 
211 namespace
212 {
214  {
215  public:
217  { }
218 
220 
221  void action(const ActionEvent &event A_UNUSED) override final
222  {
224  }
226 
228  {
229  public:
231  { }
232 
234 
235  void action(const ActionEvent &event A_UNUSED) override final
236  {
238  }
240 } // namespace
241 
242 Client::Client() :
243  ActionListener(),
244  mCurrentServer(),
245  mGame(nullptr),
246  mCurrentDialog(nullptr),
247  mQuitDialog(nullptr),
248  mSetupButton(nullptr),
249  mVideoButton(nullptr),
250  mHelpButton(nullptr),
251  mAboutButton(nullptr),
252  mThemesButton(nullptr),
253  mPerfomanceButton(nullptr),
254 #ifdef ANDROID
255  mCloseButton(nullptr),
256 #endif // ANDROID
257  mState(State::CHOOSE_SERVER),
258  mOldState(State::START),
259  mSkin(nullptr),
260  mButtonPadding(1),
261  mButtonSpacing(3),
262  mPing(0),
263  mConfigAutoSaved(false)
264 {
266 }
267 
268 void Client::testsInit()
269 {
270  if (!settings.options.test.empty() &&
271  settings.options.test != "99")
272  {
273  gameInit();
274  }
275  else
276  {
277  initRand();
278  logger = new Logger;
279  SDL::initLogger();
284  }
285 }
286 
287 void Client::gameInit()
288 {
289  logger = new Logger;
290  SDL::initLogger();
291 
292  initRand();
293 
295  // Load branding information
296  if (!settings.options.brandingPath.empty())
297  {
301  }
303 
306 
307 #ifndef ENABLE_COMMANDLINEPASSWORD
308  if (!settings.options.password.empty())
309  {
310  settings.options.password.clear();
311  logger->log("Command line password parameter disabled.");
312  }
313 #endif
314 
315  // Configure logger
316  if (!settings.options.logFileName.empty())
317  {
319  }
320  else
321  {
323  "manaplus.log");
324  }
325  logger->log("Log file: " + settings.logFileName);
327 
328 #ifdef USE_FUZZER
329  Fuzzer::init();
330 #endif // USE_FUZZER
331 
332  if (settings.options.ipc == true)
333  IPC::start();
334  if (settings.options.test.empty())
335  ConfigManager::backupConfig("config.xml");
337  SDL::setLogLevel(config.getIntValue("sdlLogLevel"));
338  settings.init();
341  initFeatures();
342  initPaths();
343  logger->log("init 4");
344  logger->setDebugLog(config.getBoolValue("debugLog"));
345  logger->setReportUnimplemented(config.getBoolValue("unimplimentedLog"));
346 
347  config.incValue("runcount");
348 
349 #ifndef ANDROID
350  if (settings.options.test.empty())
352 #endif // ANDROID
353 
355  {
356  logger->error(strprintf("%s couldn't be set as home directory! "
357  "Exiting.", settings.localDataDir.c_str()));
358  }
359 
361 
362  chatLogger = new ChatLogger;
363  if (settings.options.chatLogDir.empty())
364  {
366  + std::string("/logs/"));
367  }
368  else
369  {
371  }
372 
373  // Log the client version
375  logger->log("Start configPath: " + config.getConfigPath());
376 
378 
379  updateEnv();
380  SDL::allowScreenSaver(config.getBoolValue("allowscreensaver"));
381  dumpLibs();
382  dumpSizes();
383 
384  // Initialize SDL
385  logger->log1("Initializing SDL...");
386  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
387  {
388  logger->safeError(strprintf("Could not initialize SDL: %s",
389  SDL_GetError()));
390  }
391 #ifndef __SWITCH__
392  atexit(SDL_Quit);
393 #endif
395 #ifndef USE_SDL2
396  SDL_EnableUNICODE(1);
397 #endif // USE_SDL2
398 
402 
403 #ifdef WIN32
405 #endif // WIN32
406 #ifndef USE_SDL2
408 #endif // USE_SDL2
409 
411  logVars();
412  Cpu::detect();
414 #if defined(USE_OPENGL)
415 #if !defined(ANDROID) && !defined(__APPLE__)
416 #if !defined(__native_client__) && !defined(__SWITCH__) && !defined(UNITTESTS)
417  if (!settings.options.safeMode &&
418  settings.options.renderer < 0 &&
419  settings.options.test.empty() &&
421  !config.getBoolValue("videodetected"))
422  {
424  }
425 #endif // !defined(__native_client__) && !defined(__SWITCH__) &&
426  // !defined(UNITTESTS)
427 #endif // !defined(ANDROID) && !defined(__APPLE__) &&
428 #endif // defined(USE_OPENGL)
429 
430  initGraphics();
432 
433  touchManager.init();
434 
435 #ifndef WIN32
438 #endif // WIN32
439 
441 
442  // Add the main data directories to our VirtFs search path
443  if (!settings.options.dataPath.empty())
444  {
446  Append_false);
447  }
448 
449  // Add the local data directory to VirtFs search path
451  Append_false);
454 #ifdef ENABLE_CUSTOMNLS
455  TranslationManager::loadGettextLang();
456 #endif // ENABLE_CUSTOMNLS
457 
458 #ifdef USE_SDL2
460 #endif // USE_SDL2
462 
464 
465  theme = new Theme;
468  touchManager.init();
469 
470  // Initialize the item and emote shortcuts.
471  for (size_t f = 0; f < SHORTCUT_TABS; f ++)
472  itemShortcut[f] = new ItemShortcut(f);
475 
476  gui = new Gui;
480 
482 
483  // Initialize keyboard
484  keyboard.init();
485  inputManager.init();
486 
487  // Initialise player relations
489  Joystick::init();
491 
492  keyboard.update();
493  if (joystick != nullptr)
494  joystick->update();
495 
496  // Initialize default server
499  if (!settings.options.serverType.empty())
500  {
503  }
504 
508  loginData.remember = (serverConfig.getValue("remember", 1) != 0);
509  loginData.registerLogin = false;
510 
511  if (mCurrentServer.hostname.empty())
512  {
513  mCurrentServer.hostname = branding.getValue("defaultServer", "");
515  }
516 
517  if (mCurrentServer.port == 0)
518  {
520  "defaultPort", CAST_S32(DEFAULT_PORT)));
522  branding.getValue("defaultServerType", "tmwathena"));
523  }
524 
526 
527  if (loginData.username.empty() && loginData.remember)
528  loginData.username = serverConfig.getValue("username", "");
529 
530  if (mState != State::ERROR)
532 
533  startTimers();
534 
535  const int fpsLimit = config.getIntValue("fpslimit");
536  settings.limitFps = fpsLimit > 0;
537 
539  WindowManager::setFramerate(fpsLimit);
541 
542  settings.guiAlpha = config.getFloatValue("guialpha");
543  optionChanged("fpslimit");
544 
545  start_time = time(nullptr);
546 
548 
549 #ifdef ANDROID
550 #ifndef USE_SDL2
551  WindowManager::updateScreenKeyboard(SDL_GetScreenKeyboardHeight(nullptr));
552 #endif // USE_SDL2
553 #endif // ANDROID
554 
555 #ifdef USE_MUMBLE
556  if (!mumbleManager)
557  mumbleManager = new MumbleManager;
558 #endif // USE_MUMBLE
559 
560  mSkin = theme->load("windowmenu.xml",
561  "",
562  true,
564  if (mSkin != nullptr)
565  {
567  mButtonSpacing = mSkin->getOption("spacing", 3);
568  }
569  if (settings.options.error)
571 
572  if (settings.options.validate == true)
573  runValidate();
574 }
575 
577 {
579  gameClear();
580  else
581  testsClear();
583 }
584 
586 {
587  config.addListener("fpslimit", this);
588  config.addListener("guialpha", this);
589  config.addListener("gamma", this);
590  config.addListener("enableGamma", this);
591  config.addListener("particleEmitterSkip", this);
592  config.addListener("vsync", this);
593  config.addListener("repeateDelay", this);
594  config.addListener("repeateInterval", this);
595  config.addListener("logInput", this);
596 }
597 
599 {
600  // Initialize sound engine
601  try
602  {
603  if (config.getBoolValue("sound"))
604  soundManager.init();
605 
608  }
609  catch (const char *const err)
610  {
612  errorMessage = err;
613  logger->log("Warning: %s", err);
614  }
616  "loginMusic",
617  "keprohm.ogg"),
619 }
620 
622 {
623 #ifndef USE_SDL2
625 #endif // USE_SDL2
626 
627  runCounters = config.getBoolValue("packetcounters");
628 
630 #ifdef USE_SDL2
632 #endif // USE_SDL2
633 
638 
640 }
641 
642 void Client::testsClear()
643 {
644  if (!settings.options.test.empty())
645  gameClear();
646  else
648 }
649 
650 void Client::gameClear()
651 {
652  if (logger != nullptr)
653  logger->log1("Quitting1");
654  isTerminate = true;
655  config.removeListeners(this);
656 
658 
659  IPC::stop();
662  if (windowContainer != nullptr)
664 
665  stopTimers();
667 
668  if (loginHandler != nullptr)
670 
671  if (chatHandler != nullptr)
672  chatHandler->clear();
673 
674  if (charServerHandler != nullptr)
676 
677  delete2(ipc)
678 
679 #ifdef USE_MUMBLE
680  delete2(mumbleManager)
681 #endif // USE_MUMBLE
682 
684 
685  // Before config.write() since it writes the shortcuts to the config
686  for (unsigned f = 0; f < SHORTCUT_TABS; f ++)
690 
692 
693  if (logger != nullptr)
694  logger->log1("Quitting2");
695 
699  delete2(gui)
700 
701  if (inventoryHandler != nullptr)
703 
704  if (logger != nullptr)
705  logger->log1("Quitting3");
706 
708 
710 
711  if (logger != nullptr)
712  logger->log1("Quitting4");
713 
714  XML::cleanupXML();
715 
716  if (logger != nullptr)
717  logger->log1("Quitting5");
718 
720 
721  // Shutdown sound
723 
724  if (logger != nullptr)
725  logger->log1("Quitting6");
726 
728 
730 
732 
733  if (logger != nullptr)
734  logger->log1("Quitting8");
735 
737 
738  if (logger != nullptr)
739  logger->log1("Quitting9");
740 
742 
743  keyboard.deinit();
744 
745  if (logger != nullptr)
746  logger->log1("Quitting10");
747 
749 
750 #ifdef DEBUG_CONFIG
751  config.enableKeyLogging();
752 #endif // DEBUG_CONFIG
753 
755  config.write();
757 
758  config.clear();
760 
761  if (logger != nullptr)
762  logger->log1("Quitting11");
763 
764 #ifdef USE_PROFILER
766 #endif // USE_PROFILER
767 
768 #ifdef DEBUG_OPENGL_LEAKS
769  if (logger)
770  logger->log("textures left: %d", textures_count);
771 #endif // DEBUG_OPENGL_LEAKS
772 
774 
775  if (logger != nullptr)
776  logger->log1("Quitting12");
777 
780 }
781 
782 int Client::testsExec()
783 {
784 #ifdef USE_OPENGL
785  if (settings.options.test.empty())
786  {
787  TestMain test;
788  return test.exec();
789  }
790  else
791  {
792  TestLauncher launcher(settings.options.test);
793  return launcher.exec();
794  }
795 #else // USE_OPENGL
796 
797  return 0;
798 #endif // USE_OPENGL
799 }
800 
801 #define ADDBUTTON(var, object) var = object; \
802  x -= var->getWidth() + mButtonSpacing; \
803  var->setPosition(x, mButtonPadding); \
804  top->add(var);
805 
807 {
808  if ((gameHandler != nullptr) &&
809  (loginHandler != nullptr) &&
811  {
813  }
814 }
815 
817 {
819  {
823  initTradeFilter();
826 
827  // Initialize the item and emote shortcuts.
828  for (unsigned f = 0; f < SHORTCUT_TABS; f ++)
829  {
830  delete itemShortcut[f];
831  itemShortcut[f] = new ItemShortcut(f);
832  }
833  delete emoteShortcut;
835 
836  // Initialize the drop shortcuts.
837  delete dropShortcut;
839 
840  initFeatures();
844  if (!mCurrentServer.onlineListUrl.empty())
846  else
852  "enableRemoteCommands", 1) != 0);
853 
854  if (settings.options.username.empty())
855  {
856  if (loginData.remember)
857  loginData.username = serverConfig.getValue("username", "");
858  else
859  loginData.username.clear();
860  }
861  else
862  {
864  }
865 #ifdef SAVE_PASSWORD
867  serverConfig.getValue("password", "") : "";
870 #endif
873 
874  loginData.remember = (serverConfig.getValue("remember", 1) != 0);
876 
877 #ifdef USE_MUMBLE
878  if (mumbleManager)
879  mumbleManager->setServer(mCurrentServer.hostname);
880 #endif // USE_MUMBLE
881 
882 #ifdef TMWA_SUPPORT
884 #endif // TMWA_SUPPORT
885 
886  if (!mConfigAutoSaved)
887  {
888  mConfigAutoSaved = true;
889  config.write();
890  }
891  }
892  else if (loginHandler != nullptr &&
894  {
896  }
897 }
898 
900 {
901  if (mOldState == State::UPDATE &&
902  (loginHandler != nullptr))
903  {
904  if (loginHandler->getWorlds().size() < 2)
906  }
907 }
908 
910 {
911  if (gui == nullptr)
912  return;
913 
914  BasicContainer2 *const top = static_cast<BasicContainer2*>(
915  gui->getTop());
916 
917  if (top == nullptr)
918  return;
919 
920  CREATEWIDGETV(desktop, Desktop, nullptr);
921  top->add(desktop);
922  int x = top->getWidth() - mButtonPadding;
924  // TRANSLATORS: setup tab quick button
925  _("Setup"), "Setup", BUTTON_SKIN, this))
927  // TRANSLATORS: perfoamance tab quick button
928  _("Performance"), "Perfomance", BUTTON_SKIN, this))
930  // TRANSLATORS: video tab quick button
931  _("Video"), "Video", BUTTON_SKIN, this))
933  // TRANSLATORS: theme tab quick button
934  _("Theme"), "Themes", BUTTON_SKIN, this))
936  // TRANSLATORS: theme tab quick button
937  _("About"), "about", BUTTON_SKIN, this))
939  // TRANSLATORS: theme tab quick button
940  _("Help"), "help", BUTTON_SKIN, this))
941 #ifdef ANDROID
942  ADDBUTTON(mCloseButton, new Button(desktop,
943  // TRANSLATORS: close quick button
944  _("Close"), "close", BUTTON_SKIN, this))
945 #endif // ANDROID
946 
949 }
950 
952 {
953  if (mOldState == State::GAME &&
954  (gameHandler != nullptr))
955  {
957  }
958 }
959 
960 int Client::gameExec()
961 {
962  int lastTickTime = tick_time;
963 
964  Perf::init();
965 
966  while (mState != State::EXIT)
967  {
968  PROFILER_START();
969  PERF_STAT(0);
971  continue;
972 
973  PERF_STAT(1);
974 
975  BLOCK_START("Client::gameExec 3")
976  if (generalHandler != nullptr)
977  generalHandler->flushNetwork();
979 
980  PERF_STAT(2);
981 
983  if (gui != nullptr)
984  gui->logic();
985 
986  PERF_STAT(3);
987 
988  cur_time = time(nullptr);
989  int k = 0;
990  while (lastTickTime != tick_time &&
991  k < 40)
992  {
993  if (mGame != nullptr)
994  mGame->logic();
995  else if (gui != nullptr)
996  gui->handleInput();
997 
998  ++lastTickTime;
999  k ++;
1000  }
1001 
1002  PERF_STAT(4);
1003 
1004  soundManager.logic();
1005 
1006  PERF_STAT(5);
1007 
1008  logic_count = logic_count + k;
1009  if (gui != nullptr)
1010  gui->slowLogic();
1011 
1012  PERF_STAT(6);
1013 
1014  if (mGame != nullptr)
1015  mGame->slowLogic();
1016 
1017  PERF_STAT(7);
1018 
1019  slowLogic();
1020 
1021  PERF_STAT(8);
1022 
1023  BLOCK_END("Client::gameExec 4")
1024 
1025  // This is done because at some point tick_time will wrap.
1026  lastTickTime = tick_time;
1027 
1029  if (mState == State::CONNECT_GAME)
1030  {
1032  }
1033  else if (mState == State::CONNECT_SERVER)
1034  {
1036  }
1037  else if (mState == State::WORLD_SELECT)
1038  {
1040  }
1041  else if (mOldState == State::START ||
1043  {
1044  stateGame1();
1045  }
1046  else if (mState == State::SWITCH_LOGIN)
1047  {
1049  }
1050  BLOCK_END("Client::gameExec 6")
1051 
1052  PERF_STAT(9);
1053 
1054  if (mState != mOldState)
1055  {
1056  BLOCK_START("Client::gameExec 7")
1058 
1059  if (mOldState == State::GAME)
1060  {
1061  delete2(mGame)
1068  if (guildHandler != nullptr)
1069  guildHandler->clear();
1070  if (partyHandler != nullptr)
1071  partyHandler->clear();
1072  if (chatLogger != nullptr)
1073  chatLogger->clear();
1074  if (!settings.options.dataPath.empty())
1076  else
1080  }
1081  else if (mOldState == State::CHAR_SELECT)
1082  {
1083  if (mState != State::CHANGEPASSWORD &&
1084  charServerHandler != nullptr)
1085  {
1087  }
1088  }
1089 
1090  mOldState = mState;
1091 
1092  // Get rid of the dialog of the previous state
1094 
1095  // State has changed, while the quitDialog was active, it might
1096  // not be correct anymore
1097  if (mQuitDialog != nullptr)
1098  {
1100  mQuitDialog = nullptr;
1101  }
1102  BLOCK_END("Client::gameExec 7")
1103 
1105  switch (mState)
1106  {
1107  case State::CHOOSE_SERVER:
1108  {
1109  BLOCK_START("Client::gameExec STATE_CHOOSE_SERVER")
1110  logger->log1("State: CHOOSE SERVER");
1111  unloadData();
1112  pincodeManager.closeDialogs();
1113 
1114  // Allow changing this using a server choice dialog
1115  // We show the dialog box only if the command-line
1116  // options weren't set.
1117  if (settings.options.serverName.empty() &&
1118  settings.options.serverPort == 0 &&
1119  !branding.getValue("onlineServerList", "a").empty())
1120  {
1121  // Don't allow an alpha opacity
1122  // lower than the default value
1123  theme->setMinimumOpacity(0.8F);
1124 
1126  &mCurrentServer,
1128  }
1129  else
1130  {
1132 
1133  // Reset options so that cancelling or connect
1134  // timeout will show the server dialog.
1135  settings.options.serverName.clear();
1137  }
1138  BLOCK_END("Client::gameExec STATE_CHOOSE_SERVER")
1139  break;
1140  }
1141 
1142  case State::CONNECT_SERVER:
1144  logger->log1("State: CONNECT SERVER");
1145  loginData.updateHosts.clear();
1147  // TRANSLATORS: connection dialog header
1148  _("Connecting to server"),
1149  State::SWITCH_SERVER);
1150  TranslationManager::loadCurrentLang();
1151  TranslationManager::loadDictionaryLang();
1152  pincodeManager.init();
1154  break;
1155 
1156  case State::PRE_LOGIN:
1157  logger->log1("State: PRE_LOGIN");
1158  break;
1159 
1160  case State::LOGIN:
1162  logger->log1("State: LOGIN");
1163  // Don't allow an alpha opacity
1164  // lower than the default value
1165  theme->setMinimumOpacity(0.8F);
1166 
1167  if (packetVersion == 0)
1168  {
1170  if (packetVersion != 0)
1171  {
1173  logger->log("Preconfigured packet version: %d",
1174  packetVersion);
1175  }
1176  }
1177 
1178  loginData.updateType = static_cast<UpdateTypeT>(
1179  serverConfig.getValue("updateType", 0));
1180 
1182  const_cast<char*>(mCurrentServer.hostname.c_str()),
1183  CAST_S32(mCurrentServer.hostname.size()));
1184  if (settings.options.username.empty() ||
1185  settings.options.password.empty())
1186  {
1188  loginData,
1189  &mCurrentServer,
1191  }
1192  else
1193  {
1195  // Clear the password so that when login fails, the
1196  // dialog will show up next time.
1197  settings.options.password.clear();
1198  }
1199  BLOCK_END("Client::gameExec State::LOGIN")
1200  break;
1201 
1202  case State::LOGIN_ATTEMPT:
1204  logger->log1("State: LOGIN ATTEMPT");
1206  // TRANSLATORS: connection dialog header
1207  _("Logging in"),
1208  State::SWITCH_SERVER);
1209  if (loginHandler != nullptr)
1210  loginHandler->loginOrRegister(&loginData);
1212  break;
1213 
1214  case State::WORLD_SELECT:
1216  logger->log1("State: WORLD SELECT");
1217  {
1220  if (loginHandler == nullptr)
1221  {
1222  BLOCK_END("Client::gameExec State::WORLD_SELECT")
1223  break;
1224  }
1225  Worlds worlds = loginHandler->getWorlds();
1226 
1227  if (worlds.empty())
1228  {
1229  // Trust that the netcode knows what it's doing
1231  }
1232  else if (worlds.size() == 1)
1233  {
1237  }
1238  else
1239  {
1241  worlds);
1243  {
1244  static_cast<WorldSelectDialog*>(mCurrentDialog)
1245  ->action(ActionEvent(nullptr, "ok"));
1246  }
1247  }
1248  }
1249  BLOCK_END("Client::gameExec State::WORLD_SELECT")
1250  break;
1251 
1254  logger->log1("State: WORLD SELECT ATTEMPT");
1256  // TRANSLATORS: connection dialog header
1257  _("Entering game world"),
1258  State::WORLD_SELECT);
1260  break;
1261 
1262  case State::UPDATE:
1264  logger->log1("State: UPDATE");
1265 
1266  // Determine which source to use for the update host
1267  if (!settings.options.updateHost.empty())
1268  settings.updateHost = settings.options.updateHost;
1269  else
1270  settings.updateHost = loginData.updateHost;
1271  Dirs::initUpdatesDir();
1272 
1273  if (!settings.oldUpdates.empty())
1274  UpdaterWindow::unloadUpdates(settings.oldUpdates);
1275 
1276  if (settings.options.skipUpdate)
1277  {
1279  settings.oldUpdates.clear();
1281  }
1282  else if ((loginData.updateType & UpdateType::Skip) != 0)
1283  {
1288  }
1289  else
1290  {
1296  settings.options.dataPath.empty(),
1298  }
1299  BLOCK_END("Client::gameExec State::UPDATE")
1300  break;
1301 
1302  case State::LOAD_DATA:
1303  {
1304  BLOCK_START("Client::gameExec State::LOAD_DATA")
1305  logger->log1("State: LOAD DATA");
1306 
1307  loadData();
1308 
1311  break;
1312  }
1313  case State::GET_CHARACTERS:
1315  logger->log1("State: GET CHARACTERS");
1317  // TRANSLATORS: connection dialog header
1318  _("Requesting characters"),
1319  State::SWITCH_SERVER);
1320  if (charServerHandler != nullptr)
1321  charServerHandler->requestCharacters();
1323  break;
1324 
1325  case State::CHAR_SELECT:
1327  logger->log1("State: CHAR SELECT");
1328  // Don't allow an alpha opacity
1329  // lower than the default value
1330  theme->setMinimumOpacity(0.8F);
1331 
1332  settings.login = loginData.username;
1334 
1336  loginData);
1337  pincodeManager.updateState();
1338 
1339  if (!(static_cast<CharSelectDialog*>(mCurrentDialog))
1340  ->selectByName(settings.options.character,
1341  CharSelectDialog::Choose))
1342  {
1343  (static_cast<CharSelectDialog*>(mCurrentDialog))
1344  ->selectByName(
1345  serverConfig.getValue("lastCharacter", ""),
1349  }
1350 
1351  // Choosing character on the command line should work only
1352  // once, clear it so that 'switch character' works.
1353  settings.options.character.clear();
1354  BLOCK_END("Client::gameExec State::CHAR_SELECT")
1355  break;
1356 
1357  case State::CONNECT_GAME:
1359  logger->log1("State: CONNECT GAME");
1361  // TRANSLATORS: connection dialog header
1362  _("Connecting to the game server"),
1363  State::CHOOSE_SERVER);
1364  if (gameHandler != nullptr)
1365  gameHandler->connect();
1367  break;
1368 
1369  case State::CHANGE_MAP:
1371  logger->log1("State: CHANGE_MAP");
1373  // TRANSLATORS: connection dialog header
1374  _("Changing game servers"),
1376  if (gameHandler != nullptr)
1377  gameHandler->connect();
1379  break;
1380 
1381  case State::GAME:
1383  if (localPlayer != nullptr)
1384  {
1385  logger->log("Memorizing selected character %s",
1386  localPlayer->getName().c_str());
1387  serverConfig.setValue("lastCharacter",
1388  localPlayer->getName());
1389 #ifdef USE_MUMBLE
1390  if (mumbleManager)
1391  mumbleManager->setPlayer(localPlayer->getName());
1392 #endif // USE_MUMBLE
1393  Perf::init();
1394  }
1395 
1396  // Fade out logon-music here too to give the desired effect
1397  // of "flowing" into the game.
1398  soundManager.fadeOutMusic(1000);
1399 
1400  // Allow any alpha opacity
1401  theme->setMinimumOpacity(-1.0F);
1402 
1403  if (chatLogger != nullptr)
1405 
1406 #ifdef ANDROID
1407  delete2(mCloseButton)
1408 #endif // ANDROID
1409 
1416  delete2(desktop)
1417 
1418  mCurrentDialog = nullptr;
1419 
1420  logger->log1("State: GAME");
1421  if (generalHandler != nullptr)
1423  mGame = new Game;
1424  BLOCK_END("Client::gameExec State::GAME")
1425  break;
1426 
1427  case State::LOGIN_ERROR:
1429  logger->log1("State: LOGIN ERROR");
1431  // TRANSLATORS: error dialog header
1432  _("Error"),
1433  errorMessage,
1434  // TRANSLATORS: ok dialog button
1435  _("Close"),
1436  DialogType::ERROR,
1437  Modal_true,
1439  nullptr,
1440  260);
1441  mCurrentDialog->addActionListener(&loginListener);
1442  mCurrentDialog = nullptr; // OkDialog deletes itself
1444  break;
1445 
1446  case State::ACCOUNTCHANGE_ERROR:
1448  logger->log1("State: ACCOUNT CHANGE ERROR");
1450  // TRANSLATORS: error dialog header
1451  _("Error"),
1452  errorMessage,
1453  // TRANSLATORS: ok dialog button
1454  _("Close"),
1455  DialogType::ERROR,
1456  Modal_true,
1458  nullptr,
1459  260);
1460  mCurrentDialog->addActionListener(&accountListener);
1461  mCurrentDialog = nullptr; // OkDialog deletes itself
1463  break;
1464 
1465  case State::REGISTER_PREP:
1467  logger->log1("State: REGISTER_PREP");
1469  // TRANSLATORS: connection dialog header
1470  _("Requesting registration details"),
1471  State::LOGIN);
1472  loginHandler->getRegistrationDetails();
1474  break;
1475 
1476  case State::REGISTER:
1477  logger->log1("State: REGISTER");
1479  loginData);
1480  break;
1481 
1482  case State::REGISTER_ATTEMPT:
1484  logger->log("Username is %s", loginData.username.c_str());
1485  if (loginHandler != nullptr)
1486  loginHandler->registerAccount(&loginData);
1488  break;
1489 
1490  case State::CHANGEPASSWORD:
1492  logger->log1("State: CHANGE PASSWORD");
1494  loginData);
1495  mCurrentDialog->setVisible(Visible_true);
1497  break;
1498 
1502  logger->log1("State: CHANGE PASSWORD ATTEMPT");
1503  if (loginHandler != nullptr)
1504  {
1507  }
1508  BLOCK_END("Client::gameExec State::CHANGEPASSWORD_ATTEMPT")
1509  break;
1510 
1514  logger->log1("State: CHANGE PASSWORD SUCCESS");
1516  // TRANSLATORS: password change message header
1517  _("Password Change"),
1518  // TRANSLATORS: password change message text
1519  _("Password changed successfully!"),
1520  // TRANSLATORS: ok dialog button
1521  _("OK"),
1522  DialogType::ERROR,
1523  Modal_true,
1525  nullptr,
1526  260);
1527  mCurrentDialog->addActionListener(&accountListener);
1528  mCurrentDialog = nullptr; // OkDialog deletes itself
1529  loginData.password = loginData.newPassword;
1530  loginData.newPassword.clear();
1532  break;
1533 
1534  case State::CHANGEEMAIL:
1535  logger->log1("State: CHANGE EMAIL");
1538  loginData);
1539  mCurrentDialog->setVisible(Visible_true);
1540  break;
1541 
1542  case State::CHANGEEMAIL_ATTEMPT:
1543  logger->log1("State: CHANGE EMAIL ATTEMPT");
1544  if (loginHandler != nullptr)
1545  loginHandler->changeEmail(loginData.email);
1546  break;
1547 
1548  case State::CHANGEEMAIL_SUCCESS:
1549  logger->log1("State: CHANGE EMAIL SUCCESS");
1551  // TRANSLATORS: email change message header
1552  _("Email Change"),
1553  // TRANSLATORS: email change message text
1554  _("Email changed successfully!"),
1555  // TRANSLATORS: ok dialog button
1556  _("OK"),
1557  DialogType::ERROR,
1558  Modal_true,
1560  nullptr,
1561  260);
1562  mCurrentDialog->addActionListener(&accountListener);
1563  mCurrentDialog = nullptr; // OkDialog deletes itself
1564  break;
1565 
1566  case State::SWITCH_SERVER:
1568  logger->log1("State: SWITCH SERVER");
1569 
1570  if (loginHandler != nullptr)
1572  if (gameHandler != nullptr)
1573  {
1575  gameHandler->clear();
1576  }
1577  settings.serverName.clear();
1578  settings.login.clear();
1580  serverConfig.write();
1581  serverConfig.unload();
1582  if (setupWindow != nullptr)
1584 
1586  BLOCK_END("Client::gameExec State::SWITCH_SERVER")
1587  break;
1588 
1589  case State::SWITCH_LOGIN:
1591  logger->log1("State: SWITCH LOGIN");
1592 
1593  if (loginHandler != nullptr)
1594  {
1595  loginHandler->logout();
1597  }
1598  if (gameHandler != nullptr)
1600  if (loginHandler != nullptr)
1601  loginHandler->connect();
1602 
1603  settings.login.clear();
1605  mState = State::LOGIN;
1606  BLOCK_END("Client::gameExec State::SWITCH_LOGIN")
1607  break;
1608 
1609  case State::SWITCH_CHARACTER:
1611  logger->log1("State: SWITCH CHARACTER");
1612 
1613  // Done with game
1614  if (gameHandler != nullptr)
1616 
1617  settings.login.clear();
1621  break;
1622 
1623  case State::LOGOUT_ATTEMPT:
1624  logger->log1("State: LOGOUT ATTEMPT");
1625  break;
1626 
1627  case State::WAIT:
1628  logger->log1("State: WAIT");
1629  break;
1630 
1631  case State::EXIT:
1633  logger->log1("State: EXIT");
1634  Net::unload();
1636  break;
1637 
1638  case State::FORCE_QUIT:
1640  logger->log1("State: FORCE QUIT");
1641  if (generalHandler != nullptr)
1643  mState = State::EXIT;
1645  break;
1646 
1647  case State::ERROR:
1649  config.write();
1650 #ifdef SAVE_PASSWORD
1651  if (errorMessage == "Wrong password.")
1652  {
1653  serverConfig.setValue("password", "");
1654  serverConfig.write();
1655  }
1656 #endif
1657  if (mOldState == State::GAME)
1658  serverConfig.write();
1659  logger->log1("State: ERROR");
1660  logger->log("Error: %s\n", errorMessage.c_str());
1663  // TRANSLATORS: error message header
1664  _("Error"),
1665  errorMessage,
1666  Modal_true);
1668  mCurrentDialog = nullptr; // OkDialog deletes itself
1670  BLOCK_END("Client::gameExec State::ERROR")
1671  break;
1672 
1674  // ++++++
1675  break;
1676 
1677  case State::START:
1678  default:
1679  mState = State::FORCE_QUIT;
1680  break;
1681  }
1682  BLOCK_END("Client::gameExec 8")
1683  }
1684 
1685  PERF_STAT(10);
1686 
1687  // Update the screen when application is visible, delay otherwise.
1689  {
1690  frame_count = frame_count + 1;
1691  if (gui != nullptr)
1692  gui->draw();
1694  }
1695  else
1696  {
1697  SDL_Delay(100);
1698  }
1699 
1700  PERF_STAT(11);
1701 
1702  BLOCK_START("~Client::SDL_framerateDelay")
1703  if (settings.limitFps)
1706 
1707  PERF_STAT(12);
1708  PERF_NEXTFRAME();
1709  PROFILER_END();
1710  }
1711 
1712  return 0;
1713 }
1714 
1715 void Client::optionChanged(const std::string &name)
1716 {
1717  if (name == "fpslimit")
1718  {
1719  const int fpsLimit = config.getIntValue("fpslimit");
1720  settings.limitFps = fpsLimit > 0;
1721  WindowManager::setFramerate(fpsLimit);
1722  }
1723  else if (name == "guialpha" ||
1724  name == "enableGuiOpacity")
1725  {
1726  const float alpha = config.getFloatValue("guialpha");
1727  settings.guiAlpha = alpha;
1728  ImageHelper::setEnableAlpha(alpha != 1.0F &&
1729  config.getBoolValue("enableGuiOpacity"));
1730  }
1731  else if (name == "gamma" ||
1732  name == "enableGamma")
1733  {
1735  }
1736  else if (name == "particleEmitterSkip")
1737  {
1739  config.getIntValue("particleEmitterSkip") + 1;
1740  }
1741  else if (name == "vsync")
1742  {
1744  }
1745  else if (name == "repeateInterval" ||
1746  name == "repeateDelay")
1747  {
1749  }
1750 }
1751 
1752 void Client::action(const ActionEvent &event)
1753 {
1754  std::string tab;
1755  const std::string &eventId = event.getId();
1756 
1757  if (eventId == "close")
1758  {
1760  return;
1761  }
1762  if (eventId == "Setup")
1763  {
1764  tab.clear();
1765  }
1766  else if (eventId == "help")
1767  {
1769  return;
1770  }
1771  else if (eventId == "about")
1772  {
1774  return;
1775  }
1776  else if (eventId == "Video")
1777  {
1778  tab = "Video";
1779  }
1780  else if (eventId == "Themes")
1781  {
1782  tab = "Theme";
1783  }
1784  else if (eventId == "Perfomance")
1785  {
1786  tab = "Perfomance";
1787  }
1788  else
1789  {
1790  return;
1791  }
1792 
1793  if (setupWindow != nullptr)
1794  {
1798  {
1799  if (!tab.empty())
1800  setupWindow->activateTab(tab);
1802  }
1803  }
1804 }
1805 
1807 {
1808  features.init(paths.getStringValue("featuresFile"),
1810  SkipError_true);
1812  settings.fixDeadAnimation = features.getBoolValue("fixDeadAnimation");
1813 }
1814 
1815 void Client::initPaths()
1816 {
1817  settings.gmCommandSymbol = paths.getStringValue("gmCommandSymbol");
1818  settings.gmCharCommandSymbol = paths.getStringValue("gmCharCommandSymbol");
1819  settings.linkCommandSymbol = paths.getStringValue("linkCommandSymbol");
1820  if (settings.linkCommandSymbol.empty())
1822  settings.overweightPercent = paths.getIntValue("overweightPercent");
1823  settings.fixedInventorySize = paths.getIntValue("fixedInventorySize");
1825  "playerNameOffset");
1827  "playerBadgeAtRightOffset");
1828  settings.unknownSkillsAutoTab = paths.getBoolValue("unknownSkillsAutoTab");
1829  settings.enableNewMailSystem = paths.getBoolValue("enableNewMailSystem");
1830 }
1831 
1833 {
1834  const std::string tradeListName =
1835  settings.serverConfigDir + "/tradefilter.txt";
1836 
1837  std::ofstream tradeFile;
1838  struct stat statbuf;
1839 
1840  if ((stat(tradeListName.c_str(), &statbuf) != 0) ||
1841  !S_ISREG(statbuf.st_mode))
1842  {
1843  tradeFile.open(tradeListName.c_str(),
1844  std::ios::out);
1845  if (tradeFile.is_open())
1846  {
1847  tradeFile << ": sell" << std::endl;
1848  tradeFile << ": buy" << std::endl;
1849  tradeFile << ": trade" << std::endl;
1850  tradeFile << "i sell" << std::endl;
1851  tradeFile << "i buy" << std::endl;
1852  tradeFile << "i trade" << std::endl;
1853  tradeFile << "i trading" << std::endl;
1854  tradeFile << "i am buy" << std::endl;
1855  tradeFile << "i am sell" << std::endl;
1856  tradeFile << "i am trade" << std::endl;
1857  tradeFile << "i am trading" << std::endl;
1858  tradeFile << "i'm buy" << std::endl;
1859  tradeFile << "i'm sell" << std::endl;
1860  tradeFile << "i'm trade" << std::endl;
1861  tradeFile << "i'm trading" << std::endl;
1862  }
1863  else
1864  {
1865  reportAlways("Error opening file for writing: %s",
1866  tradeListName.c_str())
1867  }
1868  tradeFile.close();
1869  }
1870 }
1871 
1872 bool Client::isTmw()
1873 {
1874  const std::string &name = settings.serverName;
1875  if (name == "server.themanaworld.org" ||
1876  name == "themanaworld.org" ||
1877  name == "167.114.129.72")
1878  {
1879  return true;
1880  }
1881  return false;
1882 }
1883 
1884 void Client::moveButtons(const int width)
1885 {
1886  if (mSetupButton != nullptr)
1887  {
1888  int x = width - mSetupButton->getWidth() - mButtonPadding;
1890 #ifndef WIN32
1893 
1896 
1899 
1902 
1905 #ifdef ANDROID
1906  x -= mCloseButton->getWidth() + mButtonSpacing;
1907  mCloseButton->setPosition(x, mButtonPadding);
1908 #endif // ANDROID
1909 #endif // WIN32
1910  }
1911 }
1912 
1913 void Client::windowRemoved(const Window *const window)
1914 {
1915  if (mCurrentDialog == window)
1916  mCurrentDialog = nullptr;
1917 }
1918 
1919 void Client::focusWindow()
1920 {
1921  if (mCurrentDialog != nullptr)
1922  {
1924  }
1925 }
1926 
1928 {
1929  if (mCurrentDialog == nullptr ||
1931  {
1932  return;
1933  }
1934  CharSelectDialog *const dialog =
1935  dynamic_cast<CharSelectDialog*>(mCurrentDialog);
1936  if (dialog != nullptr)
1938 }
1939 
1940 void Client::logVars()
1941 {
1942 #ifdef ANDROID
1943  logger->log("APPDIR: %s", getenv("APPDIR"));
1944  logger->log("DATADIR2: %s", getSdStoragePath().c_str());
1945 #endif // ANDROID
1946 }
1947 
1948 void Client::slowLogic()
1949 {
1950  if ((gameHandler == nullptr) ||
1951  !gameHandler->mustPing())
1952  {
1953  return;
1954  }
1955 
1956  if (get_elapsed_time1(mPing) > 1500)
1957  {
1958  mPing = tick_time;
1959  if (mState == State::UPDATE ||
1960  mState == State::LOGIN ||
1962  mState == State::REGISTER ||
1964  {
1965  if (loginHandler != nullptr)
1966  loginHandler->ping();
1967  if (generalHandler != nullptr)
1969  }
1970  else if (mState == State::CHAR_SELECT)
1971  {
1972  if (charServerHandler != nullptr)
1974  if (generalHandler != nullptr)
1976  }
1977  }
1978 }
1979 
1981 {
1982  // If another data path has been set,
1983  // we don't load any other files...
1984  if (settings.options.dataPath.empty())
1985  {
1986  // Add customdata directory
1988  "customdata/",
1989  "zip",
1990  Append_false);
1991  }
1992 
1994  {
1996  settings.updatesDir + "/local/",
1997  "zip",
1998  Append_false);
1999 
2003  "local/"),
2004  Append_false);
2005  }
2006 
2007  logger->log("Init paths");
2008  paths.init("paths.xml",
2010  SkipError_false);
2012  initPaths();
2013  if (SpriteReference::Empty == nullptr)
2014  {
2016  paths.getStringValue("spriteErrorFile"),
2017  0);
2018  }
2019 
2020  if (BeingInfo::unknown == nullptr)
2022 
2023  initFeatures();
2027 
2030 
2031  delete spellManager;
2032  spellManager = new SpellManager;
2033  delete spellShortcut;
2035 
2037 
2039 
2040  if (desktop != nullptr)
2042 }
2043 
2045 {
2047  mCurrentServer.supportUrl.clear();
2048  settings.supportUrl.clear();
2049  if (settings.options.dataPath.empty())
2050  {
2051  // Add customdata directory
2053  "customdata/",
2054  "zip");
2055  }
2056 
2057  if (!settings.oldUpdates.empty())
2058  {
2060  settings.oldUpdates.clear();
2061  }
2062 
2064  {
2066  pathJoin(settings.updatesDir, "local/"),
2067  "zip");
2068 
2072  "local/"));
2073  }
2074 
2076 
2078  localClan.clear();
2079  serverVersion = 0;
2080  packetVersion = 0;
2081  packetVersionMain = 0;
2082  packetVersionRe = 0;
2083  packetVersionZero = 0;
2084  tmwServerVersion = 0;
2085  evolPacketOffset = 0;
2086 }
2087 
2089 {
2090  loadData();
2092 
2094  unloadData();
2095  delete2(client)
2096  VirtFs::deinit();
2097  exit(0);
2098 }
void SDL_initFramerate(FPSmanager *manager)
Initialize the framerate manager.
Uint32 SDL_framerateDelay(FPSmanager *manager)
Delay execution to maintain a constant framerate and calculate fps.
const bool Append_false
Definition: append.h:30
AssertListener * assertListener
volatile time_t cur_time
Definition: timer.cpp:58
#define fromBool(val, name)
Definition: booldefines.h:49
const std::string BUTTON_SKIN
Definition: button.h:89
#define CAST_U16
Definition: cast.h:29
#define CAST_S32
Definition: cast.h:30
Net::CharServerHandler * charServerHandler
Definition: net.cpp:85
Net::ChatHandler * chatHandler
Definition: net.cpp:86
ChatLogger * chatLogger
Definition: chatlogger.cpp:43
#define reportAlways(...)
Definition: checkutils.h:253
static void load()
static void unload()
static void clear()
Definition: beinginfo.cpp:217
static BeingInfo * unknown
Definition: beinginfo.h:56
const std::string & getName() const
Definition: being.h:232
Definition: button.h:102
void setServerName(const std::string &serverName)
Definition: chatlogger.cpp:176
void clear()
Definition: chatlogger.cpp:228
void setBaseLogDir(const std::string &logDir)
Definition: chatlogger.h:63
Definition: client.h:50
void runValidate() __attribute__((noreturn))
Definition: client.cpp:2088
static void initPaths()
Definition: client.cpp:850
void setState(const StateT state)
Definition: client.h:66
void stateGame1()
Definition: client.cpp:909
void loadData()
Definition: client.cpp:1980
void action(const ActionEvent &event)
Definition: client.cpp:732
StateT mState
Definition: client.h:112
static void initFeatures()
Definition: client.cpp:1806
int mButtonPadding
Definition: client.h:116
void gameInit()
Definition: client.cpp:170
int mButtonSpacing
Definition: client.h:117
Button * mAboutButton
Definition: client.h:105
StateT mOldState
Definition: client.h:113
void initConfigListeners()
Definition: client.cpp:585
static void stateConnectGame1()
Definition: client.cpp:806
Button * mPerfomanceButton
Definition: client.h:107
static int testsExec()
Definition: client.cpp:833
void focusWindow()
Definition: client.cpp:809
void windowRemoved(const Window *const window)
Definition: client.cpp:803
void moveButtons(const int width)
Definition: client.cpp:774
static void initGraphics()
Definition: client.cpp:413
void slowLogic()
Definition: client.cpp:829
void updatePinState()
Definition: client.cpp:817
static void initTradeFilter()
Definition: client.cpp:1832
static void logVars()
Definition: client.cpp:821
int mPing
Definition: client.h:164
Game * mGame
Definition: client.h:145
~Client()
Definition: client.cpp:382
void testsInit()
Definition: client.cpp:161
void stateSwitchLogin1()
Definition: client.cpp:951
void stateConnectServer1()
Definition: client.cpp:816
void stateWorldSelect1()
Definition: client.cpp:899
bool mConfigAutoSaved
Definition: client.h:165
Button * mVideoButton
Definition: client.h:103
void initSoundManager()
Definition: client.cpp:390
void optionChanged(const std::string &name)
Definition: client.cpp:1715
void gameClear()
Definition: client.cpp:435
Button * mHelpButton
Definition: client.h:104
Button * mSetupButton
Definition: client.h:102
int gameExec()
Definition: client.cpp:577
static bool isTmw()
Definition: client.cpp:838
ServerInfo mCurrentServer
Definition: client.h:143
Client()
Definition: client.cpp:140
QuitDialog * mQuitDialog
Definition: client.h:147
Button * mThemesButton
Definition: client.h:106
void testsClear()
Definition: client.cpp:165
Skin * mSkin
Definition: client.h:115
void unloadData()
Definition: client.cpp:2044
Window * mCurrentDialog
Definition: client.h:101
static void initServerConfig(const std::string &serverName)
static void backupConfig(const std::string &name)
static void storeSafeParameters()
static void checkConfigVersion()
static void initConfiguration()
std::string getValue(const std::string &key, const std::string &deflt) const
bool getBoolValue(const std::string &key) const
std::string getStringValue(const std::string &key) const
float getFloatValue(const std::string &key) const
void addListener(const std::string &key, ConfigListener *const listener)
const std::string & getConfigPath() const
void setValue(const std::string &key, const std::string &value)
void incValue(const std::string &key)
void removeListeners(ConfigListener *const listener)
void init(const std::string &filename, const UseVirtFs useResManager, const SkipError skipError)
int getIntValue(const std::string &key) const
void reloadWallpaper()
Definition: desktop.cpp:122
static Window * openErrorDialog(const std::string &header, const std::string &message, const Modal modal)
Definition: dirs.h:30
static void initRootDir()
Definition: dirs.cpp:266
static void initTempDir()
Definition: dirs.cpp:383
static void initConfigDir()
Definition: dirs.cpp:396
static void initHomeDir()
Definition: dirs.cpp:330
static void initLocalDataDir()
Definition: dirs.cpp:337
static void initUsersDir()
Definition: dirs.cpp:599
static void initScreenshotDir()
Definition: dirs.cpp:544
static void extractDataDir()
Definition: dirs.cpp:179
static void mountDataDir()
Definition: dirs.cpp:198
static void updateDataPath()
Definition: dirs.cpp:161
static void initFunctions()
Definition: dyepalette.cpp:253
static void prepareSlotNames()
bool handleEvents() const
Definition: game.h:64
void slowLogic()
Definition: game.cpp:679
static void clearInstance()
Definition: game.h:85
void logic()
Definition: game.cpp:663
static void initLang()
static void deleteRenderers()
virtual void updateScreen()=0
static void cleanUp()
Definition: graphics.cpp:159
virtual void beginDraw()
Definition: graphics.h:441
int getHeight() const
Definition: graphics.cpp:648
virtual void postInit()
Definition: graphics.h:462
int getWidth() const
Definition: graphics.cpp:643
Definition: gui.h:117
Widget * getTop() const
Definition: gui.h:248
void draw()
Definition: gui.cpp:470
void slowLogic()
Definition: gui.cpp:323
void postInit(Graphics *const graphics)
Definition: gui.cpp:151
bool handleInput()
Definition: gui.cpp:388
static void init()
static void clearGuilds()
Definition: guild.cpp:398
static void stop()
Definition: ipc.cpp:154
static void start()
Definition: ipc.cpp:163
static void setEnableAlpha(const bool n)
Definition: imagehelper.h:98
virtual void postInit()
Definition: imagehelper.h:110
void executeAction(const InputActionT keyNum)
static void init()
Definition: joystick.cpp:73
void update()
Definition: joystick.cpp:359
Definition: logger.h:69
void log(const char *const log_text,...)
Definition: logger.cpp:269
void log1(const char *const log_text)
Definition: logger.cpp:238
void safeError(const std::string &error_text) __attribute__((noreturn))
Definition: logger.cpp:435
void setReportUnimplemented(const bool n)
Definition: logger.h:184
void error(const std::string &error_text) __attribute__((noreturn))
Definition: logger.cpp:472
void setDebugLog(const bool n)
Definition: logger.h:181
void setLogFile(const std::string &logFilename)
Definition: logger.cpp:120
std::string registerUrl
Definition: logindata.h:69
int packetVersion
Definition: logindata.h:73
std::string username
Definition: logindata.h:59
std::string password
Definition: logindata.h:60
std::string newPassword
Definition: logindata.h:61
UpdateTypeT updateType
Definition: logindata.h:65
bool remember
Definition: logindata.h:74
void clearUpdateHost()
Definition: logindata.h:96
bool registerLogin
Definition: logindata.h:75
static std::string savedPassword
Definition: logindialog.h:80
virtual void clear() const =0
virtual void ping() const =0
virtual void clear() const =0
static unsigned long adlerBuffer(const char *const buffer, int size)
Definition: download.cpp:147
virtual void disconnect() const =0
virtual bool isConnected() const =0
virtual void clear() const =0
virtual bool mustPing() const =0
virtual void reloadPartially() const =0
virtual void flushSend() const =0
virtual void clear() const =0
virtual void clear() const =0
virtual void chooseServer(unsigned int server, const bool persistentIp) const =0
virtual void logout() const =0
virtual void updatePacketVersion() const =0
virtual void connect() const =0
virtual void disconnect() const =0
virtual void clearWorlds() const =0
virtual void ping() const =0
virtual bool isConnected() const =0
virtual const Worlds & getWorlds() const =0
virtual void changePassword(const std::string &oldPassword, const std::string &newPassword) const =0
virtual void clear() const =0
static void clearDialogs()
Definition: npcdialog.cpp:1217
static int emitterSkip
static void clearParties()
Definition: party.cpp:328
std::string hostname
Definition: serverinfo.h:45
std::vector< std::string > updateMirrors
Definition: serverinfo.h:53
std::string supportUrl
Definition: serverinfo.h:50
uint16_t port
Definition: serverinfo.h:58
std::string onlineListUrl
Definition: serverinfo.h:49
int packetVersion
Definition: serverinfo.h:60
ServerTypeT type
Definition: serverinfo.h:42
bool persistentIp
Definition: serverinfo.h:62
static ServerTypeT parseType(const std::string &serverType)
Definition: serverinfo.h:197
std::string registerUrl
Definition: serverinfo.h:48
std::string onlineListUrl
Definition: settings.h:116
bool fixDeadAnimation
Definition: settings.h:160
unsigned int overweightPercent
Definition: settings.h:147
bool enableNewMailSystem
Definition: settings.h:165
std::string gmCharCommandSymbol
Definition: settings.h:126
bool persistentIp
Definition: settings.h:153
std::string localDataDir
Definition: settings.h:112
std::string oldUpdates
Definition: settings.h:109
bool limitFps
Definition: settings.h:154
bool enableRemoteCommands
Definition: settings.h:162
std::string linkCommandSymbol
Definition: settings.h:127
float guiAlpha
Definition: settings.h:131
std::string gmCommandSymbol
Definition: settings.h:125
int playerNameOffset
Definition: settings.h:149
std::string serverName
Definition: settings.h:114
Options options
Definition: settings.h:130
int playerBadgeAtRightOffset
Definition: settings.h:150
std::string updatesDir
Definition: settings.h:110
std::vector< std::string > updateMirrors
Definition: settings.h:129
bool unknownSkillsAutoTab
Definition: settings.h:164
std::string configDir
Definition: settings.h:111
std::string logFileName
Definition: settings.h:122
std::string supportUrl
Definition: settings.h:121
void init()
Definition: settings.cpp:34
unsigned int fixedInventorySize
Definition: settings.h:148
std::string serverConfigDir
Definition: settings.h:117
std::string updateHost
Definition: settings.h:107
std::string login
Definition: settings.h:108
void setVisible(Visible visible)
void activateTab(const std::string &name)
void externalUnload()
int getOption(const std::string &name) const
Definition: skin.h:106
int getPadding() const
Definition: skin.h:100
void playMusic(const std::string &fileName, const SkipError skipError)
void fadeOutMusic(const int ms)
void setSfxVolume(const int volume)
void setMusicVolume(const int volume)
int exec(const bool testAudio=true)
Definition: testmain.cpp:78
Definition: theme.h:55
static std::string getThemePath()
Definition: theme.h:67
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
void setMinimumOpacity(const float minimumOpacity)
Definition: theme.cpp:272
static void selectSkin()
Definition: theme.cpp:598
static void loadCurrentLang()
static void loadDictionaryLang()
static void loadLocalUpdates(const std::string &dir)
static void loadDirMods(const std::string &dir)
static void unloadUpdates(const std::string &dir)
static void unloadMods(const std::string &dir)
void setSize(const int width, const int height)
Definition: widget.cpp:367
virtual void requestMoveToTop()
Definition: widget.cpp:213
virtual void requestFocus()
Definition: widget.cpp:204
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
void setPosition(const int x, const int y)
Definition: widget.cpp:161
int getWidth() const
Definition: widget.h:221
Definition: window.h:102
bool isWindowVisible() const
Definition: window.h:484
virtual void scheduleDelete()
Definition: window.cpp:831
Configuration config
Configuration features
Configuration paths
Configuration serverConfig
Configuration branding
const unsigned int SHORTCUT_TABS
Definition: itemshortcut.h:28
static const uint16_t DEFAULT_PORT
Definition: net.h:32
#define CREATEWIDGETV(var, type,...)
Definition: createwidget.h:25
void setFeaturesDefaults(Configuration &cfg)
Definition: defaults.cpp:752
void setPathsDefaults(Configuration &cfg)
Definition: defaults.cpp:550
void setConfigDefaults2(Configuration &cfg)
Definition: defaults.cpp:443
void setBrandingDefaults(Configuration &cfg)
Definition: defaults.cpp:490
#define delete2(var)
Definition: delete2.h:25
Desktop * desktop
Definition: desktop.cpp:49
DialogsManager * dialogsManager
DropShortcut * dropShortcut
void dumpLibs()
Definition: dumplibs.cpp:116
void dumpSizes()
Definition: dumpsizes.cpp:33
Client * client
Definition: client.cpp:118
int textures_count
Definition: client.cpp:138
bool packets_zero
Definition: client.cpp:133
unsigned int tmwServerVersion
Definition: client.cpp:134
volatile bool runCounters
Definition: client.cpp:122
unsigned int mLastHost
Definition: client.cpp:136
int packetsType
Definition: client.cpp:129
unsigned long mSearchHash
Definition: client.cpp:137
std::string errorMessage
Definition: client.cpp:116
FPSmanager fpsManager
bool isSafeMode
Definition: client.cpp:123
int serverVersion
Definition: client.cpp:124
bool packets_re
Definition: client.cpp:132
int itemIdLen
Definition: client.cpp:130
time_t start_time
Definition: client.cpp:135
int packetVersionRe
Definition: client.cpp:127
bool packets_main
Definition: client.cpp:131
int packetVersionMain
Definition: client.cpp:126
int packetVersionZero
Definition: client.cpp:128
int packetVersion
Definition: client.cpp:125
EmoteShortcut * emoteShortcut
void updateEnv()
Definition: env.cpp:30
ErrorListener errorListener
EventsManager eventsManager
Net::GameHandler * gameHandler
Definition: net.cpp:91
Net::GeneralHandler * generalHandler
Definition: net.cpp:88
#define _(s)
Definition: gettext.h:35
Graphics * mainGraphics
Definition: graphics.cpp:109
if(!vert) return
const Image *restrict const top
GraphicsManager graphicsManager
Gui * gui
Definition: gui.cpp:111
Net::GuildHandler * guildHandler
Definition: net.cpp:92
ImageHelper * imageHelper
Definition: imagehelper.cpp:44
InputManager inputManager
Net::InventoryHandler * inventoryHandler
Definition: net.cpp:89
IPC * ipc
Definition: ipc.cpp:37
ItemShortcut * itemShortcut[SHORTCUT_TABS]
Joystick * joystick
Definition: joystick.cpp:43
KeyboardConfig keyboard
LocalClan localClan
Definition: localclan.cpp:26
#define override
Definition: localconsts.h:47
#define final
Definition: localconsts.h:46
#define PRAGMA48(str)
Definition: localconsts.h:199
#define A_DELETE_COPY(func)
Definition: localconsts.h:53
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
#define CHECKLISTENERS
Definition: localconsts.h:277
LocalPlayer * localPlayer
Logger * logger
Definition: logger.cpp:89
Net::LoginHandler * loginHandler
Definition: net.cpp:90
#define FULL_VERSION
Definition: main.h:164
volatile bool isTerminate
Definition: client.cpp:209
#define ADDBUTTON(var, object)
Definition: client.cpp:801
LoginData loginData
Definition: client.cpp:185
int evolPacketOffset
Definition: net.cpp:40
volatile int tick_time
Definition: timer.cpp:53
const bool Modal_true
Definition: modal.h:30
void initRand()
Definition: mrand.cpp:35
bool disconnect(InputEvent &event)
Definition: actions.cpp:75
void detect()
Definition: cpu.cpp:46
void loadDb()
Definition: dbmanager.cpp:63
void unloadDb()
Definition: dbmanager.cpp:106
void connectToServer(const ServerInfo &server)
Definition: net.cpp:130
void unload()
Definition: net.cpp:180
void loadIgnorePackets()
Definition: net.cpp:194
void initPacketLimiter()
void init()
Definition: perfstat.cpp:41
void stateChange(const StateT state)
Definition: playerinfo.cpp:470
void loadData()
Definition: playerinfo.cpp:445
void init()
Definition: playerinfo.cpp:434
void clear()
Definition: playerinfo.cpp:452
void deinit()
Definition: playerinfo.cpp:438
bool cleanOrphans(const bool always)
void initLogger()
Definition: sdlhelper.cpp:187
void setLogLevel(const int level)
Definition: sdlhelper.cpp:191
void allowScreenSaver(const bool allow)
Definition: sdlhelper.cpp:210
Definition: state.h:33
@ REGISTER_PREP
Definition: state.h:53
@ CHANGE_MAP
Definition: state.h:50
@ CHANGEPASSWORD
Definition: state.h:56
@ START
Definition: state.h:36
@ CHANGEEMAIL_ATTEMPT
Definition: state.h:60
@ REGISTER_ATTEMPT
Definition: state.h:55
@ CHAR_SELECT
Definition: state.h:47
@ LOGIN_ERROR
Definition: state.h:51
@ ACCOUNTCHANGE_ERROR
Definition: state.h:52
@ CHOOSE_SERVER
Definition: state.h:37
@ WORLD_SELECT_ATTEMPT
Definition: state.h:43
@ GAME
Definition: state.h:49
@ UPDATE
Definition: state.h:44
@ LOGIN_ATTEMPT
Definition: state.h:41
@ FORCE_QUIT
Definition: state.h:68
@ LOGOUT_ATTEMPT
Definition: state.h:65
@ CHANGEEMAIL_SUCCESS
Definition: state.h:61
@ SWITCH_SERVER
Definition: state.h:62
@ WORLD_SELECT
Definition: state.h:42
@ CONNECT_GAME
Definition: state.h:48
@ GET_CHARACTERS
Definition: state.h:46
@ LOAD_DATA
Definition: state.h:45
@ PRE_LOGIN
Definition: state.h:39
@ CHANGEEMAIL
Definition: state.h:59
@ SWITCH_LOGIN
Definition: state.h:63
@ CHANGEPASSWORD_ATTEMPT
Definition: state.h:57
@ SWITCH_CHARACTER
Definition: state.h:64
@ ERROR
Definition: state.h:35
@ CONNECT_SERVER
Definition: state.h:38
@ AUTORECONNECT_SERVER
Definition: state.h:69
@ EXIT
Definition: state.h:67
@ LOGIN
Definition: state.h:40
@ REGISTER
Definition: state.h:54
@ CHANGEPASSWORD_SUCCESS
Definition: state.h:58
void update()
Definition: useragent.cpp:32
bool deinit()
Definition: fs.cpp:785
int64_t write(File *const file, const void *const buffer, const uint32_t objSize, const uint32_t objCount)
Definition: fs.cpp:826
bool unmountDirSilent(std::string oldDir)
Definition: fs.cpp:554
void searchAndAddArchives(const std::string &path, const std::string &ext, const Append append)
Definition: tools.cpp:41
bool setWriteDir(const std::string &newDir)
Definition: fs.cpp:331
bool mountDir(std::string newDir, const Append append)
Definition: fs.cpp:393
void searchAndRemoveArchives(const std::string &path, const std::string &ext)
Definition: tools.cpp:62
void setFramerate(const unsigned int fpsLimit)
void deleteValidateWindows()
void updateScreenKeyboard(const int height)
void createValidateWindows()
void cleanupXML()
Definition: libxml.cpp:315
anonymous_namespace{client.cpp}::AccountListener accountListener
anonymous_namespace{client.cpp}::LoginListener loginListener
Net::PartyHandler * partyHandler
Definition: net.cpp:94
#define PROFILER_END()
Definition: perfomance.h:78
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
#define PROFILER_START()
Definition: perfomance.h:77
PincodeManager pincodeManager
PlayerRelationsManager playerRelations
std::string empty
Definition: podict.cpp:26
PopupManager * popupManager
Settings settings
Definition: settings.cpp:32
SetupWindow * setupWindow
Definition: setupwindow.cpp:64
const bool ShowCenter_true
Definition: showcenter.h:30
const bool SkipError_false
Definition: skiperror.h:30
const bool SkipError_true
Definition: skiperror.h:30
SoundManager soundManager
SpellManager * spellManager
SpellShortcut * spellShortcut
std::string strprintf(const char *const format,...)
std::string pathJoin(std::string str1, const std::string &str2)
Structure holding the state and timing information of the framerate controller.
void clear()
Definition: localclan.h:48
bool validate
Definition: options.h:103
std::string brandingPath
Definition: options.h:79
bool safeMode
Definition: options.h:98
std::string chatLogDir
Definition: options.h:84
std::string test
Definition: options.h:88
bool skipUpdate
Definition: options.h:95
bool chooseDefault
Definition: options.h:96
std::string updateHost
Definition: options.h:80
bool ipc
Definition: options.h:100
uint16_t serverPort
Definition: options.h:92
std::string character
Definition: options.h:78
bool error
Definition: options.h:102
std::string dataPath
Definition: options.h:81
std::string logFileName
Definition: options.h:83
std::string password
Definition: options.h:77
int renderer
Definition: options.h:91
std::string serverType
Definition: options.h:90
bool testMode
Definition: options.h:99
std::string serverName
Definition: options.h:89
std::string username
Definition: options.h:76
static SpriteReference * Empty
Theme * theme
Definition: theme.cpp:62
void startTimers()
Definition: timer.cpp:113
volatile int logic_count
Definition: timer.cpp:57
int get_elapsed_time1(const int startTime)
Definition: timer.cpp:105
volatile int frame_count
Definition: timer.cpp:56
void stopTimers()
Definition: timer.cpp:121
TouchManager touchManager
UpdateType ::T UpdateTypeT
Definition: updatetype.h:36
const bool UseVirtFs_false
Definition: usevirtfs.h:30
const bool UseVirtFs_true
Definition: usevirtfs.h:30
#define PERF_STAT(n)
Definition: perfstat.h:59
#define PERF_NEXTFRAME()
Definition: perfstat.h:62
bool Visible
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30
WindowContainer * windowContainer
std::vector< WorldInfo * > Worlds
Definition: worldinfo.h:59