Guest User

Untitled

a guest
Jul 17th, 2013
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 229.08 KB | None | 0 0
  1. // This file is part of Glest (www.glest.org)
  2. //
  3. // Copyright (C) 2001-2008 MartiƱo Figueroa
  4. //
  5. // You can redistribute this code and/or modify it under
  6. // the terms of the GNU General Public License as published
  7. // by the Free Software Foundation; either version 2 of the
  8. // License, or (at your option) any later version
  9. // ==============================================================
  10.  
  11. #ifdef WIN32
  12. #include <winsock2.h>
  13. #include <winsock.h>
  14. #include <process.h>
  15. #include <io.h>
  16. #endif
  17.  
  18. #ifdef HAVE_GOOGLE_BREAKPAD
  19. #include "handler/exception_handler.h"
  20. #endif
  21.  
  22. #include "math_wrapper.h"
  23. #include "main.h"
  24.  
  25. #include <string>
  26. #include <cstdlib>
  27.  
  28. #include "game.h"
  29. #include "main_menu.h"
  30. #include "program.h"
  31. #include "config.h"
  32. #include "metrics.h"
  33. #include "game_util.h"
  34. #include "platform_util.h"
  35. #include "platform_main.h"
  36. #include "network_interface.h"
  37. #include "ImageReaders.h"
  38. #include "renderer.h"
  39. #include "simple_threads.h"
  40. #include <memory>
  41. #include "font.h"
  42. #include <curl/curl.h>
  43. #include "menu_state_masterserver.h"
  44. #include "checksum.h"
  45. #include <algorithm>
  46. #include "sound_renderer.h"
  47. #include "font_gl.h"
  48. #include "FileReader.h"
  49. #include "cache_manager.h"
  50. #include <iterator>
  51. #include "core_data.h"
  52. #include "font_text.h"
  53. #include <locale.h>
  54. #include "string_utils.h"
  55. #include "auto_test.h"
  56. #include "lua_script.h"
  57.  
  58. // To handle signal catching
  59. #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
  60. #include <signal.h>
  61. #endif
  62.  
  63. #if defined WIN32 && !defined(HAVE_GOOGLE_BREAKPAD)
  64. #if defined(__WIN32__) && !defined(__GNUC__)
  65. #include <eh.h>
  66. #endif
  67. #include <dbghelp.h>
  68. #endif
  69.  
  70. #ifndef WIN32
  71. #include <poll.h>
  72.  
  73. #define stricmp strcasecmp
  74. #define strnicmp strncasecmp
  75. #define _strnicmp strncasecmp
  76. #endif
  77.  
  78. #include <stdlib.h>
  79.  
  80. #include "network_message.h"
  81. #include "network_protocol.h"
  82. #include "conversion.h"
  83. #include "gen_uuid.h"
  84. #include "leak_dumper.h"
  85.  
  86. //#if defined(WIN32) && !defined(HAVE_GOOGLE_BREAKPAD)
  87. #if defined(WIN32)
  88. #ifndef _DEBUG
  89. #ifndef __GNUC__
  90.  
  91. #define WIN32_STACK_TRACE
  92.  
  93. #endif
  94. #endif
  95. #endif
  96.  
  97. using namespace std;
  98. using namespace Shared::Platform;
  99. using namespace Shared::Util;
  100. using namespace Shared::Graphics;
  101. using namespace Shared::Graphics::Gl;
  102. using namespace Shared::Xml;
  103. using namespace Shared;
  104.  
  105. namespace Glest { namespace Game {
  106.  
  107. static string mg_app_name = "";
  108. static string mailStringSupport = "";
  109. static bool sdl_quitCalled = false;
  110.  
  111. static bool disableheadless_console = false;
  112. static bool disableBacktrace = false;
  113. static bool gameInitialized = false;
  114.  
  115. static Program *mainProgram = NULL;
  116. static FileCRCPreCacheThread *preCacheThread = NULL;
  117. #ifdef WIN32
  118. static string runtimeErrorMsg = "";
  119. #endif
  120.  
  121. #ifdef HAVE_GOOGLE_BREAKPAD
  122. std::auto_ptr<google_breakpad::ExceptionHandler> errorHandlerPtr;
  123. #endif
  124.  
  125. class NavtiveLanguageNameListCacheGenerator : public SimpleTaskCallbackInterface {
  126. virtual void simpleTask(BaseThread *callingThread) {
  127. Lang &lang = Lang::getInstance();
  128. lang.getDiscoveredLanguageList(true);
  129. }
  130. };
  131.  
  132. // =====================================================
  133. // class ExceptionHandler
  134. // =====================================================
  135. class ExceptionHandler: public PlatformExceptionHandler{
  136. public:
  137.  
  138. #if defined(__WIN32__) && !defined(__GNUC__)
  139. virtual void handle(LPEXCEPTION_POINTERS pointers);
  140. #endif
  141.  
  142. virtual void handle();
  143.  
  144. static void logError(const char *msg, bool confirmToConsole);
  145. static void handleRuntimeError(const megaglest_runtime_error &ex);
  146. static void handleRuntimeError(const char *msg, bool getStackTraceString);
  147. static int DisplayMessage(const char *msg, bool exitApp);
  148. };
  149.  
  150. void cleanupCRCThread() {
  151. if(preCacheThread != NULL) {
  152. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  153.  
  154. const double MAX_THREAD_WAIT = 60;
  155. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("START - shutting down crc threads\n");
  156. time_t elapsed = time(NULL);
  157. preCacheThread->signalQuit();
  158. for(;preCacheThread->canShutdown(false) == false &&
  159. difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT;) {
  160. //sleep(150);
  161. }
  162. if(difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT) {
  163. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("B - shutting down crc threads\n");
  164.  
  165. for(;preCacheThread->shutdownAndWait() == false &&
  166. difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT;) {
  167. }
  168. if(preCacheThread->getRunningStatus() == false) {
  169. delete preCacheThread;
  170. preCacheThread=NULL;
  171. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("C - shutting down crc threads\n");
  172. }
  173. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  174. }
  175. else {
  176. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("D - shutting down crc threads\n");
  177.  
  178. if(preCacheThread->canShutdown(false) == true) {
  179. if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  180. delete preCacheThread;
  181. preCacheThread=NULL;
  182.  
  183. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("E - shutting down crc threads\n");
  184. //printf("Stopping broadcast thread [%p] - C\n",broadCastThread);
  185. }
  186. }
  187. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("F - shutting down crc threads\n");
  188. preCacheThread = NULL;
  189. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  190. }
  191. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  192. }
  193.  
  194. static void cleanupProcessObjects() {
  195. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  196.  
  197. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  198. showCursor(true);
  199. restoreVideoMode(true);
  200. }
  201.  
  202. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 IRCCLient Cache SHUTDOWN\n");
  203. IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(GameConstants::ircClientCacheLookupKey);
  204. //printf("In main IRCThreadcheck [%p]...\n",ircClient);
  205. if(ircClient != NULL) {
  206. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 IRCCLient Cache SHUTDOWN\n");
  207. if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  208.  
  209. //printf("Closing IRC CLient %d\n",__LINE__);
  210. ircClient->disconnect();
  211. ircClient->signalQuit();
  212. ircClient = NULL;
  213. sleep(0);
  214.  
  215. /*
  216. ircClient->setCallbackObj(NULL);
  217.  
  218. //printf("In main IRCThreadcheck [%p] signalled quit...\n",ircClient);
  219. printf("Closing IRC CLient %d\n",__LINE__);
  220. ircClient->signalQuit();
  221. if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  222.  
  223. ircClient->disconnect();
  224. ircClient = NULL;
  225.  
  226. printf("Closing IRC CLient %d\n",__LINE__);
  227. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#3 IRCCLient Cache SHUTDOWN\n");
  228. */
  229. }
  230. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#4 IRCCLient Cache SHUTDOWN\n");
  231.  
  232. //printf("Closing IRC CLient %d\n",__LINE__);
  233.  
  234. cleanupCRCThread();
  235. //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  236. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  237.  
  238. //printf("Closing IRC CLient %d\n",__LINE__);
  239. if(Renderer::isEnded() == false) {
  240. Renderer::getInstance().end();
  241. CoreData &coreData= CoreData::getInstance();
  242. coreData.cleanup();
  243. }
  244.  
  245. //printf("Closing IRC CLient %d\n",__LINE__);
  246.  
  247. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  248.  
  249. SystemFlags::Close();
  250. SystemFlags::SHUTDOWN_PROGRAM_MODE=true;
  251.  
  252. //printf("Closing IRC CLient %d\n",__LINE__);
  253.  
  254. Thread::shutdownThreads();
  255.  
  256. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("start running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size());
  257. time_t elapsed = time(NULL);
  258. int lastLazyThreadDump = 0;
  259. for(;Thread::getThreadList().size() > 0 &&
  260. difftime((long int)time(NULL),elapsed) <= 10;) {
  261. //sleep(0);
  262.  
  263. if(difftime((long int)time(NULL),elapsed) > 1) {
  264. if(lastLazyThreadDump != (int)difftime((long int)time(NULL),elapsed)) {
  265. lastLazyThreadDump = difftime((long int)time(NULL),elapsed);
  266.  
  267. printf("Waiting for the following threads to exit [" MG_SIZE_T_SPECIFIER "]:\n",Thread::getThreadList().size());
  268.  
  269. for(int i = 0; i < Thread::getThreadList().size(); ++i) {
  270. BaseThread *baseThread = dynamic_cast<BaseThread *>(Thread::getThreadList()[i]);
  271. printf("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n",i,baseThread,(baseThread != NULL),(baseThread != NULL ? baseThread->getUniqueID().c_str() : "<na>"));
  272. }
  273. }
  274. }
  275. }
  276. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("end running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size());
  277.  
  278. Thread::shutdownThreads();
  279.  
  280. std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
  281. //deleteMapValues(crcPlayerTextureCache.begin(),crcPlayerTextureCache.end());
  282. crcPlayerTextureCache.clear();
  283.  
  284. std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
  285. //deleteMapValues(crcFactionPreviewTextureCache.begin(),crcFactionPreviewTextureCache.end());
  286. crcFactionPreviewTextureCache.clear();
  287.  
  288. std::map<string, vector<FileReader<Pixmap2D> const * >* > &list2d = FileReader<Pixmap2D>::getFileReadersMap();
  289. //printf("list2d = " MG_SIZE_T_SPECIFIER "\n",list2d.size());
  290. deleteMapValues(list2d.begin(),list2d.end());
  291. std::map<string, vector<FileReader<Pixmap3D> const * >* > &list3d = FileReader<Pixmap3D>::getFileReadersMap();
  292. //printf("list3d = " MG_SIZE_T_SPECIFIER "\n",list3d.size());
  293. deleteMapValues(list3d.begin(),list3d.end());
  294.  
  295. XmlIo::getInstance().cleanup();
  296.  
  297. //printf("Closing IRC CLient %d\n",__LINE__);
  298.  
  299. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  300.  
  301.  
  302. SystemFlags::globalCleanupHTTP();
  303.  
  304. //printf("Closing IRC CLient %d\n",__LINE__);
  305.  
  306. CacheManager::cleanupMutexes();
  307.  
  308. //printf("Closing IRC CLient %d\n",__LINE__);
  309. }
  310.  
  311. #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__)
  312. void fatal(const char *s, ...) // failure exit
  313. {
  314. static int errors = 0;
  315. errors++;
  316.  
  317. if(errors <= 5) { // print up to two extra recursive errors
  318. defvformatstring(msg,s,s);
  319. string errText = string(msg) + " [" + runtimeErrorMsg + "]";
  320. //puts(msg);
  321. string sErr = string(mg_app_name) + " fatal error";
  322. SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",errText.c_str());
  323. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",errText.c_str());
  324.  
  325. if(errors <= 1) { // avoid recursion
  326. if(SDL_WasInit(SDL_INIT_VIDEO)) {
  327. SDL_ShowCursor(1);
  328. SDL_WM_GrabInput(SDL_GRAB_OFF);
  329. //SDL_SetGamma(1, 1, 1);
  330. }
  331. #ifdef WIN32
  332. LPWSTR wstr = Ansi2WideString(errText.c_str());
  333. LPWSTR wstr1 = Ansi2WideString(sErr.c_str());
  334.  
  335. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  336. MessageBox(NULL, wstr, wstr1, MB_OK|MB_SYSTEMMODAL);
  337. }
  338.  
  339. if(wstr) delete [] wstr;
  340. if(wstr1) delete [] wstr1;
  341. #endif
  342. //SDL_Quit();
  343. }
  344. }
  345.  
  346. // Now try to shutdown threads if possible
  347. delete mainProgram;
  348. mainProgram = NULL;
  349. // END
  350.  
  351. if(sdl_quitCalled == false) {
  352. sdl_quitCalled = true;
  353. SDL_Quit();
  354. }
  355. exit(EXIT_FAILURE);
  356. }
  357.  
  358. std::string get_module_path(HMODULE module = 0) {
  359. char path_name[MAX_PATH] = {};
  360. DWORD size = GetModuleFileNameA(module, path_name, MAX_PATH);
  361. return std::string(path_name, size);
  362. }
  363. void write_module_name(string &out, HANDLE process, DWORD64 program_counter) {
  364. DWORD64 module_base = SymGetModuleBase64(process, program_counter);
  365. if (module_base) {
  366. std::string module_name = get_module_path(reinterpret_cast<HMODULE>(module_base));
  367. if (!module_name.empty())
  368. out += module_name + "|";
  369. else
  370. out += "Unknown module|";
  371. } else {
  372. out += "Unknown module|";
  373. }
  374. }
  375.  
  376. void write_function_name(string &out, HANDLE process, DWORD64 program_counter) {
  377. SYMBOL_INFO_PACKAGE sym = { sizeof(sym) };
  378. sym.si.MaxNameLen = MAX_SYM_NAME;
  379. if (SymFromAddr(process, program_counter, 0, &sym.si)) {
  380. out += string(sym.si.Name) + "()";
  381. } else {
  382. out += "Unknown function";
  383. }
  384. }
  385.  
  386. void write_file_and_line(string & out, HANDLE process, DWORD64 program_counter) {
  387. IMAGEHLP_LINE64 ih_line = { sizeof(IMAGEHLP_LINE64) };
  388. DWORD dummy = 0;
  389. if (SymGetLineFromAddr64(process, program_counter, &dummy, &ih_line)) {
  390. out += string("|") + string(ih_line.FileName) + ":" + intToStr(ih_line.LineNumber);
  391. }
  392. }
  393. void generate_stack_trace(string &out, CONTEXT ctx, int skip) {
  394. STACKFRAME64 sf = {};
  395. sf.AddrPC.Offset = ctx.Eip;
  396. sf.AddrPC.Mode = AddrModeFlat;
  397. sf.AddrStack.Offset = ctx.Esp;
  398. sf.AddrStack.Mode = AddrModeFlat;
  399. sf.AddrFrame.Offset = ctx.Ebp;
  400. sf.AddrFrame.Mode = AddrModeFlat;
  401.  
  402. HANDLE process = GetCurrentProcess();
  403. HANDLE thread = GetCurrentThread();
  404.  
  405. bool tryThreadContext = true;
  406. CONTEXT threadContext;
  407. memset(&threadContext, 0, sizeof(CONTEXT));
  408. threadContext.ContextFlags = CONTEXT_FULL;
  409.  
  410. for (;;) {
  411. SetLastError(0);
  412. BOOL stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_I386, process, thread, &sf,
  413. (tryThreadContext == false ? &threadContext : &ctx), 0, &SymFunctionTableAccess64,
  414. &SymGetModuleBase64, 0);
  415. if (!stack_walk_ok || !sf.AddrFrame.Offset) {
  416. if(tryThreadContext == true) {
  417. tryThreadContext = false;
  418. if(GetThreadContext(thread, &threadContext) != 0) {
  419. sf.AddrPC.Offset = threadContext.Eip;
  420. sf.AddrPC.Mode = AddrModeFlat;
  421. sf.AddrStack.Offset = threadContext.Esp;
  422. sf.AddrStack.Mode = AddrModeFlat;
  423. sf.AddrFrame.Offset = threadContext.Ebp;
  424. sf.AddrFrame.Mode = AddrModeFlat;
  425. }
  426. else {
  427. return;
  428. }
  429. }
  430. else {
  431. return;
  432. }
  433. }
  434.  
  435. if (skip) {
  436. --skip;
  437. }
  438. else {
  439. // write the address
  440. //out += reinterpret_cast<void *>(sf.AddrPC.Offset) + "|";
  441. out += intToStr(sf.AddrPC.Offset) + "|";
  442.  
  443. write_module_name(out, process, sf.AddrPC.Offset);
  444. write_function_name(out, process, sf.AddrPC.Offset);
  445. write_file_and_line(out, process, sf.AddrPC.Offset);
  446.  
  447. out += "\n";
  448. }
  449. }
  450. }
  451.  
  452. struct UntypedException {
  453. UntypedException(const EXCEPTION_RECORD & er)
  454. : exception_object(reinterpret_cast<void *>(er.ExceptionInformation[1])),
  455. type_array(reinterpret_cast<_ThrowInfo *>(er.ExceptionInformation[2])->pCatchableTypeArray)
  456. {}
  457. void * exception_object;
  458. _CatchableTypeArray * type_array;
  459. };
  460.  
  461. void * exception_cast_worker(const UntypedException & e, const type_info & ti) {
  462. for (int i = 0; i < e.type_array->nCatchableTypes; ++i) {
  463. _CatchableType & type_i = *e.type_array->arrayOfCatchableTypes[i];
  464. const std::type_info & ti_i = *reinterpret_cast<std::type_info *>(type_i.pType);
  465. if (ti_i == ti) {
  466. char * base_address = reinterpret_cast<char *>(e.exception_object);
  467. base_address += type_i.thisDisplacement.mdisp;
  468. return base_address;
  469. }
  470. }
  471. return 0;
  472. }
  473.  
  474. template <typename T>
  475. T * exception_cast(const UntypedException & e) {
  476. const std::type_info & ti = typeid(T);
  477. return reinterpret_cast<T *>(exception_cast_worker(e, ti));
  478. }
  479. void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep, bool fatalExit) {
  480. #ifdef HAVE_GOOGLE_BREAKPAD
  481. if(errorHandlerPtr.get() != NULL) {
  482. errorHandlerPtr->WriteMinidump();
  483. }
  484. #endif
  485. if(!ep) {
  486. fatal("unknown type");
  487. return;
  488. }
  489. EXCEPTION_RECORD *er = ep->ExceptionRecord;
  490. CONTEXT *context = ep->ContextRecord;
  491. string out="";
  492. int skip = 0;
  493.  
  494. switch (er->ExceptionCode) {
  495. case 0xE06D7363: { // C++ exception
  496. UntypedException ue(*er);
  497. if (std::exception * e = exception_cast<std::exception>(ue)) {
  498. const std::type_info & ti = typeid(*e);
  499. out += string(ti.name()) + ":" + string(e->what());
  500. }
  501. else {
  502. out += "Unknown C++ exception thrown.";
  503. }
  504. skip = 2; // skip RaiseException and _CxxThrowException
  505. } break;
  506. case EXCEPTION_ACCESS_VIOLATION: {
  507. out += string("Access violation. Illegal ")
  508. + (er->ExceptionInformation[0] ? "write" : "read")
  509. + string(" by ")
  510. + intToStr((int)er->ExceptionAddress)
  511. + string(" at ")
  512. //+ reinterpret_cast<void *>(er->ExceptionInformation[1]);
  513. + intToStr(er->ExceptionInformation[1]);
  514. } break;
  515. default: {
  516. out += "SEH exception thrown. Exception code: "
  517. + er->ExceptionCode
  518. + string(" at ")
  519. + intToStr((int)er->ExceptionAddress);
  520. }
  521. }
  522.  
  523. generate_stack_trace(out, *context, skip);
  524.  
  525. if(fatalExit == true) {
  526. fatal(out.c_str());
  527. }
  528. else {
  529. ExceptionHandler::logError(out.c_str(), true);
  530. }
  531. }
  532. #endif
  533.  
  534. // =====================================================
  535. // class ExceptionHandler
  536. // =====================================================
  537. #if defined(WIN32) && !defined(__GNUC__)
  538. void ExceptionHandler::handle(LPEXCEPTION_POINTERS pointers) {
  539. string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to: " + string(mailString);
  540. msg += ", attaching the generated " + getCrashDumpFileName()+ " file.";
  541.  
  542. SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",msg.c_str());
  543. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg.c_str());
  544.  
  545. stackdumper(0, pointers, false);
  546.  
  547. if(mainProgram && gameInitialized == true) {
  548. mainProgram->showMessage(msg.c_str());
  549. }
  550.  
  551. message(msg.c_str());
  552. }
  553. #endif
  554.  
  555. void ExceptionHandler::handle() {
  556. string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to: " + string(mailString);
  557. #ifdef WIN32
  558. msg += ", attaching the generated " + getCrashDumpFileName()+ " file.";
  559. #endif
  560. SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",msg.c_str());
  561. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg.c_str());
  562.  
  563. if(mainProgram && gameInitialized == true) {
  564. mainProgram->showMessage(msg.c_str());
  565. }
  566.  
  567. message(msg.c_str());
  568. }
  569.  
  570. void ExceptionHandler::logError(const char *msg, bool confirmToConsole) {
  571. string errorLogFile = "error.log";
  572. if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  573. errorLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + errorLogFile;
  574. }
  575. else {
  576. string userData = Config::getInstance().getString("UserData_Root","");
  577. if(userData != "") {
  578. endPathWithSlash(userData);
  579. }
  580. errorLogFile = userData + errorLogFile;
  581. }
  582.  
  583. //printf("Attempting to write error to file [%s]\n",errorLogFile.c_str());
  584.  
  585. #if defined(WIN32) && !defined(__MINGW32__)
  586. FILE *fp = _wfopen(utf8_decode(errorLogFile).c_str(), L"w");
  587. std::ofstream logFile(fp);
  588. #else
  589. std::ofstream logFile;
  590. logFile.open(errorLogFile.c_str(), ios_base::out | ios_base::trunc);
  591. #endif
  592.  
  593. if(logFile.is_open() == true) {
  594. time_t curtime = time (NULL);
  595. struct tm *loctime = localtime (&curtime);
  596. char szBuf2[100]="";
  597. strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime);
  598.  
  599. logFile << "[" << szBuf2 << "] Runtime Error information:" << std::endl;
  600. logFile << "======================================================" << std::endl;
  601. logFile << (msg != NULL ? msg : "null") << std::endl;
  602. logFile.close();
  603.  
  604. #if defined(WIN32) && !defined(__MINGW32__)
  605. if(fp) {
  606. fclose(fp);
  607. }
  608. #endif
  609. if(confirmToConsole == true) {
  610. printf("Error saved to logfile [%s]\n",errorLogFile.c_str());
  611. fflush(stdout);
  612. }
  613. }
  614. else {
  615. if(confirmToConsole == true) {
  616. printf("COULD NOT SAVE TO ERROR logfile [%s]\n",errorLogFile.c_str());
  617. fflush(stdout);
  618. }
  619. }
  620. }
  621.  
  622. void ExceptionHandler::handleRuntimeError(const megaglest_runtime_error &ex) {
  623. const char *msg = ex.what();
  624. handleRuntimeError(msg,false);
  625. }
  626.  
  627. void ExceptionHandler::handleRuntimeError(const char *msg, bool getStackTraceString) {
  628. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  629.  
  630. static bool inErrorNow = false;
  631. if(inErrorNow == true) {
  632. printf("\n=====================================\n");
  633. printf("\n** Already in error handler aborting, msg [%s]\n",msg);
  634. fflush(stdout);
  635. abort();
  636. return;
  637. }
  638. inErrorNow = true;
  639.  
  640. logError(msg,true);
  641.  
  642. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n",__FILE__,__FUNCTION__,__LINE__,mainProgram,gameInitialized,msg);
  643. SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,mainProgram);
  644. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,mainProgram);
  645.  
  646. string errMsg = (msg != NULL ? msg : "null");
  647.  
  648. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  649.  
  650. bool gotStackTrace = false;
  651. if(getStackTraceString == true && disableBacktrace == false && sdl_quitCalled == false) {
  652. string stackTrace = getStackTrace();
  653. errMsg += stackTrace;
  654. gotStackTrace = true;
  655. }
  656.  
  657. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  658.  
  659. logError(errMsg.c_str(),false);
  660.  
  661. if(gotStackTrace == true) {
  662. SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str());
  663. }
  664. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str());
  665.  
  666. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  667.  
  668. //abort();
  669.  
  670. if(mainProgram && gameInitialized == true) {
  671. //printf("\nprogram->getState() [%p]\n",program->getState());
  672. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  673.  
  674. if(mainProgram->getState() != NULL) {
  675. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  676. mainProgram->showMessage(errMsg.c_str());
  677. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  678.  
  679. if(glActiveTexture != NULL) {
  680. for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && mainProgram->isMessageShowing();) {
  681. //program->getState()->render();
  682. Shared::Platform::Window::handleEvent();
  683. try {
  684. mainProgram->loop();
  685. }
  686. catch(const exception &e) {
  687. printf("\n=====================================\n");
  688. printf("\n** Already in error handler exiting errror rendering, msg [%s]\n",e.what());
  689. fflush(stdout);
  690. //abort();
  691. break;
  692. }
  693. }
  694. }
  695. }
  696. else {
  697. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  698. mainProgram->showMessage(errMsg.c_str());
  699. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  700.  
  701. if(glActiveTexture != NULL) {
  702. for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && mainProgram->isMessageShowing();) {
  703. //program->renderProgramMsgBox();
  704. Shared::Platform::Window::handleEvent();
  705. try {
  706. mainProgram->loop();
  707. }
  708. catch(const exception &e) {
  709. printf("\n=====================================\n");
  710. printf("\n** Already in error handler exiting errror rendering, msg [%s]\n",e.what());
  711. fflush(stdout);
  712. //abort();
  713. break;
  714. }
  715. }
  716. }
  717. }
  718. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  719. }
  720. else {
  721. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  722.  
  723. string err = "#2 An error occurred and ";
  724. if(sdl_quitCalled == false) {
  725. err += mg_app_name;
  726. }
  727. err += " will close.\nError msg = [" + errMsg + "]\n\nPlease report this bug to ";
  728. if(sdl_quitCalled == false) {
  729. err += mailStringSupport;
  730. }
  731. #ifdef WIN32
  732. err += string(", attaching the generated ") + getCrashDumpFileName() + string(" file.");
  733. #endif
  734. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  735.  
  736. message(err);
  737. }
  738.  
  739. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  740.  
  741. // Now try to shutdown threads if possible
  742. delete mainProgram;
  743. mainProgram = NULL;
  744. // END
  745.  
  746. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  747.  
  748. #ifdef WIN32
  749.  
  750. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  751. showCursor(true);
  752. restoreVideoMode(true);
  753. }
  754.  
  755. runtimeErrorMsg = errMsg;
  756. inErrorNow = false;
  757. throw runtimeErrorMsg;
  758. #endif
  759. //printf("In [%s::%s Line: %d] [%s] gameInitialized = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized);
  760.  
  761. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  762.  
  763. cleanupProcessObjects();
  764.  
  765. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  766.  
  767. if(sdl_quitCalled == false) {
  768. sdl_quitCalled = true;
  769. SDL_Quit();
  770. }
  771.  
  772. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  773.  
  774. inErrorNow = false;
  775.  
  776. abort();
  777. }
  778.  
  779. int ExceptionHandler::DisplayMessage(const char *msg, bool exitApp) {
  780. //printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  781. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  782. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  783.  
  784. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  785.  
  786. if(mainProgram && gameInitialized == true) {
  787. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  788. mainProgram->showMessage(msg);
  789. }
  790. else {
  791. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  792. message(msg);
  793. }
  794.  
  795. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  796.  
  797. if(exitApp == true) {
  798. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg);
  799.  
  800. // Now try to shutdown threads if possible
  801. delete mainProgram;
  802. mainProgram = NULL;
  803. // END
  804.  
  805. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  806. cleanupProcessObjects();
  807.  
  808. if(sdl_quitCalled == false) {
  809. sdl_quitCalled = true;
  810. SDL_Quit();
  811. }
  812. exit(-1);
  813. }
  814.  
  815. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp);
  816. return 0;
  817. }
  818.  
  819. // =====================================================
  820. // class MainWindow
  821. // =====================================================
  822.  
  823. MainWindow::MainWindow(Program *program) : WindowGl() {
  824. this->program= program;
  825. this->popupMenu.setEnabled(false);
  826. this->popupMenu.setVisible(false);
  827. this->triggerLanguageToggle = false;
  828. this->triggerLanguage = "";
  829. this->cancelLanguageSelection = -1;
  830. }
  831.  
  832. MainWindow::~MainWindow(){
  833. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  834. delete program;
  835. program = NULL;
  836. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  837. }
  838.  
  839. void MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton){
  840. const Metrics &metrics = Metrics::getInstance();
  841. int vx = metrics.toVirtualX(x);
  842. int vy = metrics.toVirtualY(getH() - y);
  843.  
  844. if(program == NULL) {
  845. throw megaglest_runtime_error("In [MainWindow::eventMouseDown] ERROR, program == NULL!");
  846. }
  847.  
  848. //printf("eventMouseDown popupMenu.getVisible() = %d\n",popupMenu.getVisible());
  849. if(popupMenu.getVisible() == true && popupMenu.mouseClick(vx, vy)) {
  850. std::pair<int,string> result = popupMenu.mouseClickedMenuItem(vx, vy);
  851. //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first);
  852.  
  853. popupMenu.setEnabled(false);
  854. popupMenu.setVisible(false);
  855.  
  856. //printf("result.first = %d [%s] cancelLanguageSelection = %d\n",result.first,result.second.c_str(),cancelLanguageSelection);
  857.  
  858. // Exit game
  859. if(result.first != cancelLanguageSelection) {
  860. //toggleLanguage(result.second);
  861. this->triggerLanguageToggle = true;
  862. this->triggerLanguage = result.second;
  863. }
  864.  
  865. return;
  866. }
  867. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  868.  
  869. switch(mouseButton) {
  870. case mbLeft:
  871. program->mouseDownLeft(vx, vy);
  872. break;
  873. case mbRight:
  874. //program->mouseDownRight(vx, vy);
  875. break;
  876. case mbCenter:
  877. //program->mouseDownCenter(vx, vy);
  878. break;
  879. default:
  880. break;
  881. }
  882.  
  883. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  884.  
  885. ProgramState *programState = program->getState();
  886. if(programState != NULL) {
  887. switch(mouseButton) {
  888. case mbLeft:
  889. programState->mouseDownLeft(vx, vy);
  890. break;
  891. case mbRight:
  892. programState->mouseDownRight(vx, vy);
  893. break;
  894. case mbCenter:
  895. programState->mouseDownCenter(vx, vy);
  896. break;
  897. default:
  898. break;
  899. }
  900. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  901. }
  902. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  903. }
  904.  
  905. void MainWindow::eventMouseUp(int x, int y, MouseButton mouseButton){
  906. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  907.  
  908. const Metrics &metrics = Metrics::getInstance();
  909. int vx = metrics.toVirtualX(x);
  910. int vy = metrics.toVirtualY(getH() - y);
  911.  
  912. if(program == NULL) {
  913. throw megaglest_runtime_error("In [MainWindow::eventMouseUp] ERROR, program == NULL!");
  914. }
  915.  
  916. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  917.  
  918. ProgramState *programState = program->getState();
  919.  
  920. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  921.  
  922. if(programState != NULL) {
  923. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  924.  
  925. switch(mouseButton) {
  926. case mbLeft:
  927. programState->mouseUpLeft(vx, vy);
  928. break;
  929. case mbRight:
  930. programState->mouseUpRight(vx, vy);
  931. break;
  932. case mbCenter:
  933. programState->mouseUpCenter(vx, vy);
  934. break;
  935. default:
  936. break;
  937. }
  938. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  939. }
  940. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  941. }
  942.  
  943. void MainWindow::eventMouseDoubleClick(int x, int y, MouseButton mouseButton) {
  944. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  945.  
  946. const Metrics &metrics= Metrics::getInstance();
  947. int vx = metrics.toVirtualX(x);
  948. int vy = metrics.toVirtualY(getH() - y);
  949.  
  950. if(program == NULL) {
  951. throw megaglest_runtime_error("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!");
  952. }
  953.  
  954. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  955.  
  956. ProgramState *programState = program->getState();
  957.  
  958. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  959.  
  960. if(programState != NULL) {
  961. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  962.  
  963. switch(mouseButton){
  964. case mbLeft:
  965. programState->mouseDoubleClickLeft(vx, vy);
  966. break;
  967. case mbRight:
  968. programState->mouseDoubleClickRight(vx, vy);
  969. break;
  970. case mbCenter:
  971. programState->mouseDoubleClickCenter(vx, vy);
  972. break;
  973. default:
  974. break;
  975. }
  976.  
  977. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  978. }
  979. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  980. }
  981.  
  982. void MainWindow::eventMouseMove(int x, int y, const MouseState *ms){
  983.  
  984. const Metrics &metrics= Metrics::getInstance();
  985. int vx = metrics.toVirtualX(x);
  986. int vy = metrics.toVirtualY(getH() - y);
  987.  
  988. if(program == NULL) {
  989. throw megaglest_runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
  990. }
  991.  
  992. program->eventMouseMove(vx, vy, ms);
  993.  
  994. ProgramState *programState = program->getState();
  995. if(programState != NULL) {
  996. programState->mouseMove(vx, vy, ms);
  997. }
  998. }
  999.  
  1000. void MainWindow::eventMouseWheel(int x, int y, int zDelta) {
  1001.  
  1002. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1003.  
  1004. const Metrics &metrics= Metrics::getInstance();
  1005. int vx = metrics.toVirtualX(x);
  1006. int vy = metrics.toVirtualY(getH() - y);
  1007.  
  1008. if(program == NULL) {
  1009. throw megaglest_runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!");
  1010. }
  1011.  
  1012. ProgramState *programState = program->getState();
  1013.  
  1014. if(programState != NULL) {
  1015. programState->eventMouseWheel(vx, vy, zDelta);
  1016. }
  1017.  
  1018. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1019. }
  1020.  
  1021. void MainWindow::render() {
  1022. if(popupMenu.getVisible() == true) {
  1023. Renderer &renderer= Renderer::getInstance();
  1024. renderer.renderPopupMenu(&popupMenu);
  1025.  
  1026. //printf("Render lang popup\n");
  1027. }
  1028. }
  1029.  
  1030. void MainWindow::showLanguages() {
  1031. Lang &lang= Lang::getInstance();
  1032. //PopupMenu popupMenu;
  1033. std::vector<string> menuItems;
  1034.  
  1035. vector<string> langResults;
  1036. string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
  1037.  
  1038. string userDataPath = getGameCustomCoreDataPath(data_path, "");
  1039. findAll(userDataPath + "data/lang/*.lng", langResults, true, false);
  1040. for(unsigned int i = 0; i < langResults.size(); ++i) {
  1041. string testLanguage = langResults[i];
  1042. menuItems.push_back(testLanguage);
  1043. }
  1044.  
  1045. vector<string> langResults2;
  1046. findAll(data_path + "data/lang/*.lng", langResults2, true);
  1047. if(langResults2.empty() && langResults.empty()) {
  1048. throw megaglest_runtime_error("There are no lang files");
  1049. }
  1050. for(unsigned int i = 0; i < langResults2.size(); ++i) {
  1051. string testLanguage = langResults2[i];
  1052. if(std::find(menuItems.begin(),menuItems.end(),testLanguage) == menuItems.end()) {
  1053. menuItems.push_back(testLanguage);
  1054. }
  1055. }
  1056. menuItems.push_back(lang.get("Exit"));
  1057. cancelLanguageSelection = menuItems.size()-1;
  1058.  
  1059. popupMenu.setW(100);
  1060. popupMenu.setH(100);
  1061. popupMenu.init(lang.get("GameMenuTitle"),menuItems);
  1062. popupMenu.setEnabled(true);
  1063. popupMenu.setVisible(true);
  1064. }
  1065.  
  1066. void MainWindow::toggleLanguage(string language) {
  1067. popupMenu.setEnabled(false);
  1068. popupMenu.setVisible(false);
  1069. this->triggerLanguageToggle = false;
  1070. this->triggerLanguage = "";
  1071.  
  1072. Lang &lang= Lang::getInstance();
  1073. string currentLanguage = lang.getLanguage();
  1074.  
  1075. string newLanguageSelected = language;
  1076. if(language == "") {
  1077. newLanguageSelected = currentLanguage;
  1078.  
  1079. vector<string> langResults;
  1080. string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
  1081.  
  1082. string userDataPath = getGameCustomCoreDataPath(data_path, "");
  1083. findAll(userDataPath + "data/lang/*.lng", langResults, true, false);
  1084.  
  1085. vector<string> langResults2;
  1086. findAll(data_path + "data/lang/*.lng", langResults2, true);
  1087. if(langResults2.empty() && langResults.empty()) {
  1088. throw megaglest_runtime_error("There are no lang files");
  1089. }
  1090. for(unsigned int i = 0; i < langResults2.size(); ++i) {
  1091. string testLanguage = langResults2[i];
  1092. if(std::find(langResults.begin(),langResults.end(),testLanguage) == langResults.end()) {
  1093. langResults.push_back(testLanguage);
  1094. }
  1095. }
  1096.  
  1097. for(unsigned int i = 0; i < langResults.size(); ++i) {
  1098. string testLanguage = langResults[i];
  1099. if(testLanguage == currentLanguage) {
  1100. if( i+1 < langResults.size()) {
  1101. newLanguageSelected = langResults[i+1];
  1102. }
  1103. else {
  1104. newLanguageSelected = langResults[0];
  1105. }
  1106. break;
  1107. }
  1108. }
  1109. }
  1110. if(newLanguageSelected != currentLanguage) {
  1111. lang.loadStrings(newLanguageSelected);
  1112. program->reloadUI();
  1113. program->consoleAddLine(lang.get("Language") + " " + newLanguageSelected);
  1114. }
  1115. }
  1116.  
  1117. void MainWindow::eventKeyDown(SDL_KeyboardEvent key) {
  1118. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym);
  1119.  
  1120. //SDL_keysym keystate = Window::getKeystate();
  1121. SDL_keysym keystate = key.keysym;
  1122. //printf("keystate.mod = %d key = %d lalt [%d] ralt [%d] alt [%d]\n",keystate.mod,key.keysym.unicode,(keystate.mod & KMOD_LALT),(keystate.mod & KMOD_RALT),(keystate.mod & KMOD_ALT));
  1123.  
  1124. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c][%d]\n",__FILE__,__FUNCTION__,__LINE__,key,key);
  1125.  
  1126. if(program == NULL) {
  1127. throw megaglest_runtime_error("In [MainWindow::eventKeyDown] ERROR, program == NULL!");
  1128. }
  1129.  
  1130. if(popupMenu.getVisible() == true && isKeyPressed(SDLK_ESCAPE,key) == true) {
  1131. this->popupMenu.setEnabled(false);
  1132. this->popupMenu.setVisible(false);
  1133. return;
  1134. }
  1135.  
  1136. //{
  1137. //Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
  1138. //printf("----------------------- key [%d] CameraModeLeft [%d]\n",key,configKeys.getCharKey("CameraModeLeft"));
  1139. //}
  1140.  
  1141. program->keyDown(key);
  1142.  
  1143. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1144.  
  1145. if(keystate.mod & (KMOD_LALT | KMOD_RALT)) {
  1146. //if(key == vkReturn) {
  1147. if(isKeyPressed(SDLK_RETURN,key) == true) {
  1148. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ALT-ENTER pressed\n",__FILE__,__FUNCTION__,__LINE__);
  1149.  
  1150. // This stupidity only required in win32.
  1151. // We reload the textures so that the canvas paints textures properly
  1152. #ifdef WIN32
  1153. if(Window::getAllowAltEnterFullscreenToggle() == true) {
  1154. Renderer &renderer= Renderer::getInstance();
  1155. renderer.reinitAll();
  1156. }
  1157. #endif
  1158.  
  1159. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1160. }
  1161. }
  1162.  
  1163. if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) {
  1164. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1165.  
  1166. vector<int> modifiersToCheck;
  1167. modifiersToCheck.push_back(KMOD_LCTRL);
  1168. modifiersToCheck.push_back(KMOD_RCTRL);
  1169. modifiersToCheck.push_back(KMOD_LALT);
  1170. modifiersToCheck.push_back(KMOD_RALT);
  1171. modifiersToCheck.push_back(KMOD_LSHIFT);
  1172. modifiersToCheck.push_back(KMOD_RSHIFT);
  1173.  
  1174. Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
  1175. //if(key == configKeys.getCharKey("HotKeyShowDebug")) {
  1176. if(isKeyPressed(configKeys.getSDLKey("HotKeyShowDebug"),key) == true) {
  1177. //printf("debug key pressed keystate.mod = %d [%d]\n",keystate.mod,keystate.mod & (KMOD_LALT | KMOD_RALT));
  1178.  
  1179. Renderer &renderer= Renderer::getInstance();
  1180. //if(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
  1181. if(keystate.mod & (KMOD_LALT | KMOD_RALT)) {
  1182. renderer.cycleShowDebugUILevel();
  1183. }
  1184. else {
  1185. bool showDebugUI = renderer.getShowDebugUI();
  1186. renderer.setShowDebugUI(!showDebugUI);
  1187. }
  1188. }
  1189. else if((keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) &&
  1190. isKeyPressed(configKeys.getSDLKey("SwitchLanguage"),key) == true) {
  1191. if((keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) {
  1192. //toggleLanguage("");
  1193. this->triggerLanguageToggle = true;
  1194. this->triggerLanguage = "";
  1195. }
  1196. else {
  1197. showLanguages();
  1198. }
  1199. }
  1200. //else if(key == configKeys.getCharKey("ReloadINI")) {
  1201. else if(isKeyPressed(configKeys.getSDLKey("ReloadINI"),key,modifiersToCheck) == true) {
  1202. Config &config = Config::getInstance();
  1203. config.reload();
  1204. }
  1205. //else if(key == configKeys.getCharKey("Screenshot")) {
  1206. else if(isKeyPressed(configKeys.getSDLKey("Screenshot"),key,modifiersToCheck) == true) {
  1207. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot key pressed\n");
  1208.  
  1209. string userData = Config::getInstance().getString("UserData_Root","");
  1210. if(userData != "") {
  1211. endPathWithSlash(userData);
  1212. }
  1213.  
  1214. string path = userData + GameConstants::folder_path_screenshots;
  1215. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot checking path [%s]\n",path.c_str());
  1216.  
  1217. if(isdir(path.c_str()) == false) {
  1218. createDirectoryPaths(path);
  1219. }
  1220.  
  1221. if(isdir(path.c_str()) == true) {
  1222. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot path [%s]\n",path.c_str());
  1223.  
  1224. Config &config= Config::getInstance();
  1225. string fileFormat = config.getString("ScreenShotFileType","jpg");
  1226.  
  1227. unsigned int queueSize = Renderer::getInstance().getSaveScreenQueueSize();
  1228.  
  1229. for(int i=0; i < 5000; ++i) {
  1230. path = userData + GameConstants::folder_path_screenshots;
  1231. path += string("screen") + intToStr(i + queueSize) + string(".") + fileFormat;
  1232. #ifdef WIN32
  1233. FILE *f= _wfopen(utf8_decode(path).c_str(), L"rb");
  1234. #else
  1235. FILE *f= fopen(path.c_str(), "rb");
  1236. #endif
  1237. if(f == NULL) {
  1238. Lang &lang= Lang::getInstance();
  1239. char szBuf[8096]="";
  1240. if(lang.get("ScreenshotSavedTo").length() > 0 && lang.get("ScreenshotSavedTo")[0] != '?') {
  1241. snprintf(szBuf,8096,lang.get("ScreenshotSavedTo").c_str(),path.c_str());
  1242. }
  1243. else {
  1244. snprintf(szBuf,8096,"Screenshot will be saved to: %s",path.c_str());
  1245. }
  1246.  
  1247. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf);
  1248.  
  1249. bool showScreenshotSavedMsg = Config::getInstance().getBool("DisableScreenshotConsoleText","false");
  1250. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot console showScreenshotSavedMsg = %d\n",showScreenshotSavedMsg);
  1251.  
  1252. if(showScreenshotSavedMsg == false) {
  1253. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot console [%s]\n",szBuf);
  1254. program->consoleAddLine(szBuf);
  1255. }
  1256.  
  1257. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot save to [%s]\n",path.c_str());
  1258. Renderer::getInstance().saveScreen(path);
  1259. break;
  1260. }
  1261. else {
  1262. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CANNOT save Screenshot [%s]\n",path.c_str());
  1263. fclose(f);
  1264. }
  1265. }
  1266. }
  1267. }
  1268. }
  1269.  
  1270. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1271. }
  1272.  
  1273. void MainWindow::eventKeyUp(SDL_KeyboardEvent key) {
  1274. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key);
  1275. if(program == NULL) {
  1276. throw megaglest_runtime_error("In [MainWindow::eventKeyUp] ERROR, program == NULL!");
  1277. }
  1278.  
  1279. program->keyUp(key);
  1280. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key);
  1281. }
  1282.  
  1283. void MainWindow::eventKeyPress(SDL_KeyboardEvent c) {
  1284. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c);
  1285. if(program == NULL) {
  1286. throw megaglest_runtime_error("In [MainWindow::eventKeyPress] ERROR, program == NULL!");
  1287. }
  1288.  
  1289. program->keyPress(c);
  1290.  
  1291. if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) {
  1292. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1293.  
  1294. Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
  1295. //if(c == configKeys.getCharKey("HotKeyToggleOSMouseEnabled")) {
  1296. if(isKeyPressed(configKeys.getSDLKey("HotKeyToggleOSMouseEnabled"),c) == true) {
  1297. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  1298.  
  1299. bool showCursorState = false;
  1300. int state = SDL_ShowCursor(SDL_QUERY);
  1301. if(state == SDL_DISABLE) {
  1302. showCursorState = true;
  1303. }
  1304.  
  1305. showCursor(showCursorState);
  1306. Renderer &renderer= Renderer::getInstance();
  1307. renderer.setNo2DMouseRendering(showCursorState);
  1308.  
  1309. Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY);
  1310. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState);
  1311. }
  1312. }
  1313. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c);
  1314. }
  1315.  
  1316. void MainWindow::eventActivate(bool active) {
  1317. if(!active){
  1318. //minimize();
  1319. }
  1320. }
  1321.  
  1322. void MainWindow::eventResize(SizeState sizeState) {
  1323. if(program == NULL) {
  1324. throw megaglest_runtime_error("In [MainWindow::eventResize] ERROR, program == NULL!");
  1325. }
  1326.  
  1327. program->resize(sizeState);
  1328. }
  1329.  
  1330. void MainWindow::eventClose(){
  1331. delete program;
  1332. program= NULL;
  1333. }
  1334.  
  1335. void MainWindow::setProgram(Program *program) {
  1336. this->program= program;
  1337. }
  1338.  
  1339. // =====================================================
  1340. // Main
  1341. // =====================================================
  1342. SystemFlags debugger;
  1343.  
  1344. void print_SDL_version(const char *preamble, SDL_version *v) {
  1345. printf("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch);
  1346. }
  1347.  
  1348. int setupGameItemPaths(int argc, char** argv, Config *config) {
  1349. // Setup path cache for files and folders used in the game
  1350. std::map<string,string> &pathCache = CacheManager::getCachedItem< std::map<string,string> >(GameConstants::pathCacheLookupKey);
  1351.  
  1352. //GAME_ARG_DATA_PATH
  1353. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DATA_PATH]) == true) {
  1354. int foundParamIndIndex = -1;
  1355. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]) + string("="),&foundParamIndIndex);
  1356. if(foundParamIndIndex < 0) {
  1357. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]),&foundParamIndIndex);
  1358. }
  1359. string customPath = argv[foundParamIndIndex];
  1360. vector<string> paramPartTokens;
  1361. Tokenize(customPath,paramPartTokens,"=");
  1362. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  1363. string customPathValue = paramPartTokens[1];
  1364. Properties::applyTagsToValue(customPathValue);
  1365. if(customPathValue != "") {
  1366. endPathWithSlash(customPathValue);
  1367. }
  1368. pathCache[GameConstants::path_data_CacheLookupKey]=customPathValue;
  1369. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom data path [%s]\n",customPathValue.c_str());
  1370. }
  1371. else {
  1372.  
  1373. printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  1374. printParameterHelp(argv[0],false);
  1375. return 1;
  1376. }
  1377. }
  1378. else if(config != NULL) {
  1379. if(config->getString("DataPath","") != "") {
  1380. string customPathValue = config->getString("DataPath","");
  1381. if(customPathValue != "") {
  1382. endPathWithSlash(customPathValue);
  1383. }
  1384. pathCache[GameConstants::path_data_CacheLookupKey] = config->getString("DataPath","");
  1385. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified data path [%s]\n",config->getString("DataPath","").c_str());
  1386. }
  1387. }
  1388.  
  1389. //GAME_ARG_INI_PATH
  1390. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_INI_PATH]) == true) {
  1391. int foundParamIndIndex = -1;
  1392. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]) + string("="),&foundParamIndIndex);
  1393. if(foundParamIndIndex < 0) {
  1394. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]),&foundParamIndIndex);
  1395. }
  1396. string customPath = argv[foundParamIndIndex];
  1397. vector<string> paramPartTokens;
  1398. Tokenize(customPath,paramPartTokens,"=");
  1399. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  1400. string customPathValue = paramPartTokens[1];
  1401. Properties::applyTagsToValue(customPathValue);
  1402. pathCache[GameConstants::path_ini_CacheLookupKey]=customPathValue;
  1403. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom ini path [%s]\n",customPathValue.c_str());
  1404. }
  1405. else {
  1406.  
  1407. printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  1408. printParameterHelp(argv[0],false);
  1409. return 1;
  1410. }
  1411. }
  1412.  
  1413. //GAME_ARG_LOG_PATH
  1414. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LOG_PATH]) == true) {
  1415. int foundParamIndIndex = -1;
  1416. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]) + string("="),&foundParamIndIndex);
  1417. if(foundParamIndIndex < 0) {
  1418. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]),&foundParamIndIndex);
  1419. }
  1420. string customPath = argv[foundParamIndIndex];
  1421. vector<string> paramPartTokens;
  1422. Tokenize(customPath,paramPartTokens,"=");
  1423. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  1424. string customPathValue = paramPartTokens[1];
  1425. Properties::applyTagsToValue(customPathValue);
  1426. pathCache[GameConstants::path_logs_CacheLookupKey]=customPathValue;
  1427. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom logs path [%s]\n",customPathValue.c_str());
  1428. }
  1429. else {
  1430.  
  1431. printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  1432. printParameterHelp(argv[0],false);
  1433. return 1;
  1434. }
  1435. }
  1436. else if(config != NULL) {
  1437. if(config->getString("LogPath","") != "") {
  1438. pathCache[GameConstants::path_logs_CacheLookupKey] = config->getString("LogPath","");
  1439. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified logs path [%s]\n",config->getString("LogPath","").c_str());
  1440. }
  1441. }
  1442.  
  1443. Text::DEFAULT_FONT_PATH = pathCache[GameConstants::path_data_CacheLookupKey];
  1444. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FONT_PATH]) == true) {
  1445. int foundParamIndIndex = -1;
  1446. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_PATH]) + string("="),&foundParamIndIndex);
  1447. if(foundParamIndIndex < 0) {
  1448. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_PATH]),&foundParamIndIndex);
  1449. }
  1450. string customPath = argv[foundParamIndIndex];
  1451. vector<string> paramPartTokens;
  1452. Tokenize(customPath,paramPartTokens,"=");
  1453. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  1454. string customPathValue = paramPartTokens[1];
  1455. Properties::applyTagsToValue(customPathValue);
  1456.  
  1457. Text::DEFAULT_FONT_PATH_ABSOLUTE = customPathValue;
  1458. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom fonts path [%s]\n",customPathValue.c_str());
  1459. }
  1460. else {
  1461.  
  1462. printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  1463. printParameterHelp(argv[0],false);
  1464. return 1;
  1465. }
  1466. }
  1467.  
  1468. return 0;
  1469. }
  1470.  
  1471. void setupLogging(Config &config, bool haveSpecialOutputCommandLineOption) {
  1472.  
  1473. SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = config.getBool("DebugMode","false");
  1474. SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = config.getBool("DebugNetwork","false");
  1475. SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled = config.getBool("DebugPerformance","false");
  1476. SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled = config.getBool("DebugWorldSynch","false");
  1477. SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled = config.getBool("DebugUnitCommands","false");
  1478. SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled = config.getBool("DebugPathFinder","false");
  1479. SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled = config.getBool("DebugLUA","false");
  1480. SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled = config.getBool("DebugSound","false");
  1481. SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled = config.getBool("DebugError","true");
  1482.  
  1483. string userData = config.getString("UserData_Root","");
  1484. if(userData != "") {
  1485. endPathWithSlash(userData);
  1486. }
  1487.  
  1488. #ifdef HAVE_GOOGLE_BREAKPAD
  1489. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 In setting up errorHandlerPtr->set_dump_path [%p]...\n",errorHandlerPtr.get());
  1490. if(errorHandlerPtr.get() != NULL) {
  1491. string dumpFilePath;
  1492. if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1493. dumpFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey);
  1494. }
  1495. else {
  1496. dumpFilePath = userData;
  1497. }
  1498.  
  1499. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 In setting up errorHandlerPtr->set_dump_path...\n");
  1500. #if defined(WIN32)
  1501. wstring dumpfilepath = utf8_decode(dumpFilePath);
  1502. if(SystemFlags::VERBOSE_MODE_ENABLED) wprintf(L"Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",dumpfilepath.c_str());
  1503. errorHandlerPtr->set_dump_path(dumpfilepath);
  1504. #else
  1505. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",dumpFilePath.c_str());
  1506. //errorHandlerPtr->set_dump_path(dumpfilepath);
  1507. google_breakpad::MinidumpDescriptor descriptor(dumpFilePath);
  1508. errorHandlerPtr->set_minidump_descriptor(descriptor);
  1509. #endif
  1510.  
  1511. }
  1512. #endif
  1513.  
  1514. string debugLogFile = config.getString("DebugLogFile","");
  1515. if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1516. debugLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLogFile;
  1517. }
  1518. else {
  1519. debugLogFile = userData + debugLogFile;
  1520. }
  1521.  
  1522. //printf("debugLogFile [%s]\n",debugLogFile.c_str());
  1523.  
  1524. string debugWorldSynchLogFile = config.getString("DebugLogFileWorldSynch","");
  1525. if(debugWorldSynchLogFile == "") {
  1526. debugWorldSynchLogFile = debugLogFile;
  1527. }
  1528. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1529. debugWorldSynchLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugWorldSynchLogFile;
  1530. }
  1531. else {
  1532. debugWorldSynchLogFile = userData + debugWorldSynchLogFile;
  1533. }
  1534.  
  1535. string debugPerformanceLogFile = config.getString("DebugLogFilePerformance","");
  1536. if(debugPerformanceLogFile == "") {
  1537. debugPerformanceLogFile = debugLogFile;
  1538. }
  1539. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1540. debugPerformanceLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPerformanceLogFile;
  1541. }
  1542. else {
  1543. debugPerformanceLogFile = userData + debugPerformanceLogFile;
  1544. }
  1545.  
  1546. string debugNetworkLogFile = config.getString("DebugLogFileNetwork","");
  1547. if(debugNetworkLogFile == "") {
  1548. debugNetworkLogFile = debugLogFile;
  1549. }
  1550. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1551. debugNetworkLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugNetworkLogFile;
  1552. }
  1553. else {
  1554. debugNetworkLogFile = userData + debugNetworkLogFile;
  1555. }
  1556.  
  1557. string debugUnitCommandsLogFile = config.getString("DebugLogFileUnitCommands","");
  1558. if(debugUnitCommandsLogFile == "") {
  1559. debugUnitCommandsLogFile = debugLogFile;
  1560. }
  1561. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1562. debugUnitCommandsLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugUnitCommandsLogFile;
  1563. }
  1564. else {
  1565. debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile;
  1566. }
  1567.  
  1568. string debugPathFinderLogFile = config.getString("DebugLogFilePathFinder","");
  1569. if(debugPathFinderLogFile == "") {
  1570. debugPathFinderLogFile = debugLogFile;
  1571. }
  1572. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1573. debugPathFinderLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPathFinderLogFile;
  1574. }
  1575. else {
  1576. debugPathFinderLogFile = userData + debugPathFinderLogFile;
  1577. }
  1578.  
  1579. string debugLUALogFile = config.getString("DebugLogFileLUA","");
  1580. if(debugLUALogFile == "") {
  1581. debugLUALogFile = debugLogFile;
  1582. }
  1583. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1584. debugLUALogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLUALogFile;
  1585. }
  1586. else {
  1587. debugLUALogFile = userData + debugLUALogFile;
  1588. }
  1589.  
  1590. string debugSoundLogFile = config.getString("DebugLogFileSound","");
  1591. if(debugSoundLogFile == "") {
  1592. debugSoundLogFile = debugLogFile;
  1593. }
  1594. else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  1595. debugSoundLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugSoundLogFile;
  1596. }
  1597. else {
  1598. debugSoundLogFile = userData + debugSoundLogFile;
  1599. }
  1600.  
  1601. string debugErrorLogFile = config.getString("DebugLogFileError","");
  1602.  
  1603. SystemFlags::getSystemSettingType(SystemFlags::debugSystem).debugLogFileName = debugLogFile;
  1604. SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).debugLogFileName = debugNetworkLogFile;
  1605. SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).debugLogFileName = debugPerformanceLogFile;
  1606. SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).debugLogFileName = debugWorldSynchLogFile;
  1607. SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).debugLogFileName = debugUnitCommandsLogFile;
  1608. SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).debugLogFileName = debugPathFinderLogFile;
  1609. SystemFlags::getSystemSettingType(SystemFlags::debugLUA).debugLogFileName = debugLUALogFile;
  1610. SystemFlags::getSystemSettingType(SystemFlags::debugSound).debugLogFileName = debugSoundLogFile;
  1611. SystemFlags::getSystemSettingType(SystemFlags::debugError).debugLogFileName = debugErrorLogFile;
  1612.  
  1613. if(haveSpecialOutputCommandLineOption == false) {
  1614. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--- Startup log settings are ---\ndebugSystem [%d][%s]\ndebugNetwork [%d][%s]\ndebugPerformance [%d][%s]\ndebugWorldSynch [%d][%s]\ndebugUnitCommands[%d][%s]\ndebugPathFinder[%d][%s]\ndebugLUA [%d][%s]\ndebugSound [%d][%s]\ndebugError [%d][%s]\n",
  1615. SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled,
  1616. debugLogFile.c_str(),
  1617. SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled,
  1618. debugNetworkLogFile.c_str(),
  1619. SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled,
  1620. debugPerformanceLogFile.c_str(),
  1621. SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled,
  1622. debugWorldSynchLogFile.c_str(),
  1623. SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled,
  1624. debugUnitCommandsLogFile.c_str(),
  1625. SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled,
  1626. debugPathFinderLogFile.c_str(),
  1627. SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled,
  1628. debugLUALogFile.c_str(),
  1629. SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled,
  1630. debugSoundLogFile.c_str(),
  1631. SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled,
  1632. debugErrorLogFile.c_str());
  1633. }
  1634. }
  1635.  
  1636. void runTilesetValidationForPath(string tilesetPath, string tilesetName,
  1637. World &world, bool purgeUnusedFiles,bool purgeDuplicateFiles,
  1638. bool showDuplicateFiles, bool svnPurgeFiles,double &purgedMegaBytes) {
  1639. //string file = tilesetPath + tilesetName + "/" + tilesetName + ".xml";
  1640. Checksum checksum;
  1641.  
  1642. bool techtree_errors = false;
  1643.  
  1644. std::map<string,vector<pair<string, string> > > loadedFileList;
  1645. vector<string> pathList;
  1646. pathList.push_back(tilesetPath);
  1647. world.loadTileset(pathList, tilesetName,&checksum, loadedFileList);
  1648.  
  1649. // Fixup paths with ..
  1650. {
  1651. std::map<string,vector<pair<string, string> > > newLoadedFileList;
  1652. for( std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
  1653. iterMap != loadedFileList.end(); ++iterMap) {
  1654. string loadedFile = iterMap->first;
  1655.  
  1656. replaceAll(loadedFile,"//","/");
  1657. replaceAll(loadedFile,"\\\\","\\");
  1658. updatePathClimbingParts(loadedFile);
  1659.  
  1660. if(newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) {
  1661. for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
  1662. pair<string, string> &newVal = iterMap->second[xx1];
  1663. replaceAll(newVal.first,"//","/");
  1664. replaceAll(newVal.first,"\\\\","\\");
  1665. updatePathClimbingParts(newVal.first);
  1666. replaceAll(newVal.second,"//","/");
  1667. replaceAll(newVal.second,"\\\\","\\");
  1668. updatePathClimbingParts(newVal.second);
  1669.  
  1670. newLoadedFileList[loadedFile].push_back(newVal);
  1671. }
  1672. }
  1673. else {
  1674. for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
  1675. pair<string, string> &newVal = iterMap->second[xx1];
  1676. replaceAll(newVal.first,"//","/");
  1677. replaceAll(newVal.first,"\\\\","\\");
  1678. updatePathClimbingParts(newVal.first);
  1679. replaceAll(newVal.second,"//","/");
  1680. replaceAll(newVal.second,"\\\\","\\");
  1681. updatePathClimbingParts(newVal.second);
  1682. }
  1683.  
  1684. newLoadedFileList[loadedFile] = iterMap->second;
  1685. }
  1686. }
  1687. loadedFileList = newLoadedFileList;
  1688. }
  1689.  
  1690. // Validate the faction setup to ensure we don't have any bad associations
  1691. // std::vector<std::string> resultErrors = world.validateFactionTypes();
  1692.  
  1693. // Now check for unused files in the techtree
  1694. std::map<string,vector<pair<string, string> > > foundFileList;
  1695. for(unsigned int i = 0; i < pathList.size(); ++i) {
  1696. string path = pathList[i];
  1697. endPathWithSlash(path);
  1698. path = path + tilesetName + "/";
  1699.  
  1700. replaceAll(path, "//", "/");
  1701. replaceAll(path, "\\\\", "\\");
  1702.  
  1703. vector<string> foundFiles = getFolderTreeContentsListRecursively(path + "*.", "");
  1704. for(unsigned int j = 0; j < foundFiles.size(); ++j) {
  1705. string file = foundFiles[j];
  1706. replaceAll(file, "//", "/");
  1707. replaceAll(file, "\\\\", "\\");
  1708.  
  1709. replaceAll(file,"//","/");
  1710. replaceAll(file,"\\\\","\\");
  1711.  
  1712. foundFileList[file].push_back(make_pair(path,path));
  1713. }
  1714. }
  1715.  
  1716. printf("Found tileset filecount = " MG_SIZE_T_SPECIFIER ", used = " MG_SIZE_T_SPECIFIER "\n",foundFileList.size(),loadedFileList.size());
  1717.  
  1718. int purgeCount = 0;
  1719. bool foundUnusedFile = false;
  1720. for( std::map<string,vector<pair<string, string> > >::iterator iterMap = foundFileList.begin();
  1721. iterMap != foundFileList.end(); ++iterMap) {
  1722. string foundFile = iterMap->first;
  1723. replaceAll(foundFile, "//", "/");
  1724. replaceAll(foundFile, "\\\\", "\\");
  1725.  
  1726. if(loadedFileList.find(foundFile) == loadedFileList.end() &&
  1727. foundFile.find("lang/") == foundFile.npos) {
  1728. if(foundUnusedFile == false) {
  1729. printf("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",__LINE__);
  1730. }
  1731. foundUnusedFile = true;
  1732.  
  1733. printf("[%s]\n",foundFile.c_str());
  1734.  
  1735. string fileName = extractFileFromDirectoryPath(foundFile);
  1736. if(loadedFileList.find(fileName) != loadedFileList.end()) {
  1737. printf("possible match on [%s] ?\n",loadedFileList.find(fileName)->first.c_str());
  1738. }
  1739. else if(purgeUnusedFiles == true) {
  1740. off_t fileSize = getFileSize(foundFile);
  1741. // convert to MB
  1742. purgedMegaBytes += ((double)fileSize / 1048576.0);
  1743. purgeCount++;
  1744.  
  1745. if(svnPurgeFiles == true) {
  1746. char szBuf[8096]="";
  1747. snprintf(szBuf,8096,"svn delete \"%s\"",foundFile.c_str());
  1748. bool svnOk = executeShellCommand(szBuf,0);
  1749. if(svnOk == false) {
  1750. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  1751. }
  1752. }
  1753. else {
  1754. removeFile(foundFile);
  1755. }
  1756. }
  1757. }
  1758. }
  1759. if(foundUnusedFile == true) {
  1760. if(purgedMegaBytes > 0) {
  1761. printf("Purged %.2f MB (%d) in files\n",purgedMegaBytes,purgeCount);
  1762. }
  1763. printf("\nLine ref: %d, Warning, unused files were detected - END:\n",__LINE__);
  1764. }
  1765.  
  1766. if(showDuplicateFiles == true) {
  1767. std::map<uint32,vector<string> > mapDuplicateFiles;
  1768. // Now check for duplicate data content
  1769. for(std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
  1770. iterMap != loadedFileList.end(); ++iterMap) {
  1771. string fileName = iterMap->first;
  1772. Checksum checksum;
  1773. checksum.addFile(fileName);
  1774. uint32 crcValue = checksum.getSum();
  1775. mapDuplicateFiles[crcValue].push_back(fileName);
  1776. }
  1777.  
  1778. double duplicateMegaBytesPurged=0;
  1779. int duplicateCountPurged=0;
  1780.  
  1781. double duplicateMegaBytes=0;
  1782. int duplicateCount=0;
  1783.  
  1784. bool foundDuplicates = false;
  1785. for(std::map<uint32,vector<string> >::iterator iterMap = mapDuplicateFiles.begin();
  1786. iterMap != mapDuplicateFiles.end(); ++iterMap) {
  1787. vector<string> &fileList = iterMap->second;
  1788. if(fileList.size() > 1) {
  1789. if(foundDuplicates == false) {
  1790. foundDuplicates = true;
  1791. printf("\nWarning, duplicate files were detected - START:\n=====================\n");
  1792. }
  1793.  
  1794. map<string,int> parentList;
  1795. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  1796. string duplicateFile = fileList[idx];
  1797. if(idx > 0) {
  1798. off_t fileSize = getFileSize(duplicateFile);
  1799. // convert to MB
  1800. duplicateMegaBytes += ((double)fileSize / 1048576.0);
  1801. duplicateCount++;
  1802. }
  1803. else {
  1804. printf("\n");
  1805. }
  1806.  
  1807. printf("[%s]\n",duplicateFile.c_str());
  1808. std::map<string,vector<pair<string, string> > >::iterator iterFind = loadedFileList.find(duplicateFile);
  1809. if(iterFind != loadedFileList.end()) {
  1810. for(unsigned int jdx = 0; jdx < iterFind->second.size(); jdx++) {
  1811. parentList[iterFind->second[jdx].first]++;
  1812. }
  1813. }
  1814. }
  1815.  
  1816. for(map<string,int>::iterator iterMap1 = parentList.begin();
  1817. iterMap1 != parentList.end(); ++iterMap1) {
  1818.  
  1819. if(iterMap1 == parentList.begin()) {
  1820. printf("\tParents:\n");
  1821. }
  1822. printf("\t[%s]\n",iterMap1->first.c_str());
  1823. }
  1824.  
  1825. if(purgeDuplicateFiles == true) {
  1826. //printf("\nPurge Duplicate Files detected - START:\n=====================\n");
  1827.  
  1828. string newCommonFileName = "";
  1829. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  1830. string duplicateFile = fileList[idx];
  1831. string fileExt = extractExtension(duplicateFile);
  1832. if(fileExt == "wav" || fileExt == "ogg") {
  1833. off_t fileSize = getFileSize(duplicateFile);
  1834. if(idx == 0) {
  1835. newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
  1836.  
  1837. string expandedNewCommonFileName = newCommonFileName;
  1838.  
  1839. std::map<string,string> mapExtraTagReplacementValues;
  1840.  
  1841. mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues);
  1842. Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues);
  1843. replaceAll(expandedNewCommonFileName, "//", "/");
  1844. createDirectoryPaths(extractDirectoryPathFromFile(expandedNewCommonFileName));
  1845.  
  1846. if(svnPurgeFiles == true) {
  1847. copyFileTo(duplicateFile, expandedNewCommonFileName);
  1848.  
  1849. char szBuf[8096]="";
  1850. snprintf(szBuf,8096,"svn delete \"%s\"",duplicateFile.c_str());
  1851. bool svnOk = executeShellCommand(szBuf,0);
  1852. if(svnOk == false) {
  1853. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  1854. }
  1855. printf("*** Duplicate file:\n[%s]\nwas svn deleted and copied to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  1856. }
  1857. else {
  1858. //int result = 0;
  1859. int result = rename(duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  1860. if(result != 0) {
  1861. char szBuf[8096]="";
  1862. char *errmsg = strerror(errno);
  1863. snprintf(szBuf,8096,"!!! Error [%s] Could not rename [%s] to [%s]!",errmsg,duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  1864. throw megaglest_runtime_error(szBuf);
  1865. }
  1866. else {
  1867. printf("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  1868. }
  1869. }
  1870. }
  1871. else {
  1872. if(svnPurgeFiles == true) {
  1873. char szBuf[8096]="";
  1874. snprintf(szBuf,8096,"svn delete \"%s\"",duplicateFile.c_str());
  1875. bool svnOk = executeShellCommand(szBuf,0);
  1876. if(svnOk == false) {
  1877. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  1878. }
  1879. printf("*** Duplicate file:\n[%s]\nwas svn deleted\n",duplicateFile.c_str());
  1880. }
  1881. else {
  1882. removeFile(duplicateFile);
  1883. }
  1884. printf("*** Duplicate file:\n[%s]\nwas removed\n",duplicateFile.c_str());
  1885.  
  1886. // convert to MB
  1887. duplicateMegaBytesPurged += ((double)fileSize / 1048576.0);
  1888. duplicateCountPurged++;
  1889. }
  1890. }
  1891. }
  1892.  
  1893. std::map<string,int> mapUniqueParentList;
  1894.  
  1895. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  1896. string duplicateFile = fileList[idx];
  1897. string fileExt = extractExtension(duplicateFile);
  1898. if(fileExt == "wav" || fileExt == "ogg") {
  1899. std::map<string,vector<pair<string, string> > >::iterator iterFind2 = loadedFileList.find(duplicateFile);
  1900. if(iterFind2 != loadedFileList.end()) {
  1901. for(unsigned int jdx1 = 0; jdx1 < iterFind2->second.size(); jdx1++) {
  1902. string parentFile = iterFind2->second[jdx1].first;
  1903. string searchText = iterFind2->second[jdx1].second;
  1904.  
  1905. if(mapUniqueParentList.find(parentFile) == mapUniqueParentList.end()) {
  1906. printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
  1907. bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false);
  1908. printf("foundText = %d\n",foundText);
  1909. if(foundText == false) {
  1910. char szBuf[8096]="";
  1911. snprintf(szBuf,8096,"Line ref = %d, Error finding text [%s] in file [%s]",__LINE__,searchText.c_str(),parentFile.c_str());
  1912. throw megaglest_runtime_error(szBuf);
  1913. }
  1914. mapUniqueParentList[parentFile]++;
  1915. }
  1916. }
  1917. }
  1918. }
  1919. }
  1920.  
  1921. //printf("\nPurge Duplicate Files detected - END:\n=====================\n");
  1922. }
  1923. else {
  1924. //printf("\nPurge Duplicate Files DISABLED - START:\n=====================\n");
  1925.  
  1926. string newCommonFileName = "";
  1927. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  1928. string duplicateFile = fileList[idx];
  1929. string fileExt = extractExtension(duplicateFile);
  1930. if(fileExt == "wav" || fileExt == "ogg") {
  1931. off_t fileSize = getFileSize(duplicateFile);
  1932. if(idx == 0) {
  1933. newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
  1934. break;
  1935. }
  1936. }
  1937. }
  1938.  
  1939. //printf("\nPurge Duplicate Files #2 DISABLED [" MG_SIZE_T_SPECIFIER "] - START:\n=====================\n",fileList.size());
  1940.  
  1941. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  1942. string duplicateFile = fileList[idx];
  1943. string fileExt = extractExtension(duplicateFile);
  1944. if(fileExt == "wav" || fileExt == "ogg") {
  1945. std::map<string,vector<pair<string, string> > >::iterator iterFind4 = loadedFileList.find(duplicateFile);
  1946. if(iterFind4 != loadedFileList.end()) {
  1947. for(unsigned int jdx = 0; jdx < iterFind4->second.size(); jdx++) {
  1948. string parentFile = iterFind4->second[jdx].first;
  1949. string searchText = iterFind4->second[jdx].second;
  1950.  
  1951. //printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
  1952. bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true);
  1953. //printf("foundText = %d\n",foundText);
  1954. if(foundText == false) {
  1955.  
  1956. char szBuf[8096]="";
  1957. snprintf(szBuf,8096,"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",__LINE__,searchText.c_str(),parentFile.c_str(),newCommonFileName.c_str());
  1958. printf("\n\n=================================================\n%s",szBuf);
  1959.  
  1960. throw megaglest_runtime_error(szBuf);
  1961. }
  1962. }
  1963. }
  1964. }
  1965. }
  1966.  
  1967. //printf("\nPurge Duplicate Files DISABLED - END:\n=====================\n");
  1968. }
  1969. }
  1970. }
  1971. if(foundDuplicates == true) {
  1972. printf("Duplicates %.2f MB (%d) in files\n",duplicateMegaBytes,duplicateCount);
  1973. printf("Duplicates purged %.2f MB (%d) in files\n",duplicateMegaBytesPurged,duplicateCountPurged);
  1974.  
  1975. printf("\nWarning, duplicate files were detected - END:\n");
  1976. }
  1977. }
  1978.  
  1979. if(techtree_errors == false) {
  1980. printf("\nValidation found NO ERRORS for tilesetPath [%s] tilesetName [%s]:\n",tilesetPath.c_str(), tilesetName.c_str());
  1981. }
  1982.  
  1983. printf("----------------------------------------------------------------");
  1984. }
  1985.  
  1986. void runTechValidationForPath(string techPath, string techName,
  1987. const std::vector<string> &filteredFactionList, World &world,
  1988. bool purgeUnusedFiles,bool purgeDuplicateFiles, bool showDuplicateFiles,
  1989. bool svnPurgeFiles,double &purgedMegaBytes) {
  1990. //Config &config = Config::getInstance();
  1991. vector<string> factionsList;
  1992. findDirs(techPath + techName + "/factions/", factionsList, false, false);
  1993.  
  1994. if(factionsList.empty() == false) {
  1995. Checksum checksum;
  1996. set<string> factions;
  1997. for(int j = 0; j < factionsList.size(); ++j) {
  1998. if( filteredFactionList.empty() == true ||
  1999. std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
  2000. factions.insert(factionsList[j]);
  2001. }
  2002. }
  2003.  
  2004. printf("\n----------------------------------------------------------------");
  2005. printf("\nChecking techPath [%s] techName [%s] total faction count = %d\n",techPath.c_str(), techName.c_str(),(int)factionsList.size());
  2006. for(int j = 0; j < factionsList.size(); ++j) {
  2007. if( filteredFactionList.empty() == true ||
  2008. std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
  2009. printf("Using faction [%s]\n",factionsList[j].c_str());
  2010. }
  2011. }
  2012.  
  2013. if(factions.empty() == false) {
  2014. bool techtree_errors = false;
  2015.  
  2016. std::map<string,vector<pair<string, string> > > loadedFileList;
  2017. //vector<string> pathList = config.getPathListForType(ptTechs,"");
  2018. vector<string> pathList;
  2019. pathList.push_back(techPath);
  2020. Config &config = Config::getInstance();
  2021. vector<string> otherTechPaths = config.getPathListForType(ptTechs,"");
  2022. pathList.insert(pathList.end(), otherTechPaths.begin(), otherTechPaths.end());
  2023. world.loadTech(pathList, techName, factions, &checksum, loadedFileList);
  2024.  
  2025. // Fixup paths with ..
  2026. {
  2027. std::map<string,vector<pair<string, string> > > newLoadedFileList;
  2028. for( std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
  2029. iterMap != loadedFileList.end(); ++iterMap) {
  2030. string loadedFile = iterMap->first;
  2031.  
  2032. replaceAll(loadedFile,"//","/");
  2033. replaceAll(loadedFile,"\\\\","\\");
  2034. updatePathClimbingParts(loadedFile);
  2035.  
  2036. if(newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) {
  2037. for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
  2038. pair<string, string> &newVal = iterMap->second[xx1];
  2039. replaceAll(newVal.first,"//","/");
  2040. replaceAll(newVal.first,"\\\\","\\");
  2041. updatePathClimbingParts(newVal.first);
  2042. replaceAll(newVal.second,"//","/");
  2043. replaceAll(newVal.second,"\\\\","\\");
  2044. updatePathClimbingParts(newVal.second);
  2045.  
  2046. newLoadedFileList[loadedFile].push_back(newVal);
  2047. }
  2048. }
  2049. else {
  2050. for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) {
  2051. pair<string, string> &newVal = iterMap->second[xx1];
  2052. replaceAll(newVal.first,"//","/");
  2053. replaceAll(newVal.first,"\\\\","\\");
  2054. updatePathClimbingParts(newVal.first);
  2055. replaceAll(newVal.second,"//","/");
  2056. replaceAll(newVal.second,"\\\\","\\");
  2057. updatePathClimbingParts(newVal.second);
  2058. }
  2059.  
  2060. newLoadedFileList[loadedFile] = iterMap->second;
  2061. }
  2062. }
  2063. loadedFileList = newLoadedFileList;
  2064. }
  2065.  
  2066. // Validate the faction setup to ensure we don't have any bad associations
  2067. std::vector<std::string> resultErrors = world.validateFactionTypes();
  2068. if(resultErrors.empty() == false) {
  2069. techtree_errors = true;
  2070. // Display the validation errors
  2071. string errorText = "\nErrors were detected:\n=====================\n";
  2072. for(int i = 0; i < resultErrors.size(); ++i) {
  2073. if(i > 0) {
  2074. errorText += "\n";
  2075. }
  2076. errorText = errorText + resultErrors[i];
  2077. }
  2078. errorText += "\n=====================\n";
  2079. //throw megaglest_runtime_error(errorText);
  2080. printf("%s",errorText.c_str());
  2081. }
  2082.  
  2083. // Validate the faction resource setup to ensure we don't have any bad associations
  2084. printf("\nChecking resources, count = %d\n",world.getTechTree()->getResourceTypeCount());
  2085.  
  2086. for(int i = 0; i < world.getTechTree()->getResourceTypeCount(); ++i) {
  2087. printf("Found techtree resource [%s]\n",world.getTechTree()->getResourceType(i)->getName().c_str());
  2088. }
  2089.  
  2090. resultErrors = world.validateResourceTypes();
  2091. if(resultErrors.empty() == false) {
  2092. techtree_errors = true;
  2093. // Display the validation errors
  2094. string errorText = "\nErrors were detected:\n=====================\n";
  2095. for(int i = 0; i < resultErrors.size(); ++i) {
  2096. if(i > 0) {
  2097. errorText += "\n";
  2098. }
  2099. errorText = errorText + resultErrors[i];
  2100. }
  2101. errorText += "\n=====================\n";
  2102. //throw megaglest_runtime_error(errorText);
  2103. printf("%s",errorText.c_str());
  2104. }
  2105.  
  2106. // Now check for unused files in the techtree
  2107. std::map<string,vector<pair<string, string> > > foundFileList;
  2108. for(unsigned int i = 0; i < pathList.size(); ++i) {
  2109. string path = pathList[i];
  2110. endPathWithSlash(path);
  2111. path = path + techName + "/";
  2112.  
  2113. replaceAll(path, "//", "/");
  2114. replaceAll(path, "\\\\", "\\");
  2115.  
  2116. vector<string> foundFiles = getFolderTreeContentsListRecursively(path + "*.", "");
  2117. for(unsigned int j = 0; j < foundFiles.size(); ++j) {
  2118. string file = foundFiles[j];
  2119. replaceAll(file, "//", "/");
  2120. replaceAll(file, "\\\\", "\\");
  2121.  
  2122. if( file.find(GameConstants::LOADING_SCREEN_FILE) != string::npos ||
  2123. file.find(GameConstants::PREVIEW_SCREEN_FILE) != string::npos ||
  2124. file.find(GameConstants::HUD_SCREEN_FILE) != string::npos) {
  2125. continue;
  2126. }
  2127. if(file.find("/factions/") != string::npos) {
  2128. bool includeFaction = false;
  2129. for ( set<string>::iterator it = factions.begin(); it != factions.end(); ++it ) {
  2130. string currentFaction = *it;
  2131. if(file.find("/factions/" + currentFaction) != string::npos) {
  2132. includeFaction = true;
  2133. break;
  2134. }
  2135. }
  2136. if(includeFaction == false) {
  2137. continue;
  2138. }
  2139. }
  2140.  
  2141. replaceAll(file,"//","/");
  2142. replaceAll(file,"\\\\","\\");
  2143.  
  2144. foundFileList[file].push_back(make_pair(path,path));
  2145. }
  2146. }
  2147.  
  2148. printf("Found techtree filecount = " MG_SIZE_T_SPECIFIER ", used = " MG_SIZE_T_SPECIFIER "\n",foundFileList.size(),loadedFileList.size());
  2149.  
  2150. // for( std::map<string,vector<string> >::iterator iterMap = loadedFileList.begin();
  2151. // iterMap != loadedFileList.end(); ++iterMap) {
  2152. // string foundFile = iterMap->first;
  2153. //
  2154. // if(foundFile.find("golem_ack1.wav") != string::npos) {
  2155. // printf("FOUND file [%s]\n",foundFile.c_str());
  2156. // }
  2157. // }
  2158.  
  2159. int purgeCount = 0;
  2160. bool foundUnusedFile = false;
  2161. for( std::map<string,vector<pair<string, string> > >::iterator iterMap = foundFileList.begin();
  2162. iterMap != foundFileList.end(); ++iterMap) {
  2163. string foundFile = iterMap->first;
  2164. replaceAll(foundFile, "//", "/");
  2165. replaceAll(foundFile, "\\\\", "\\");
  2166.  
  2167. if(loadedFileList.find(foundFile) == loadedFileList.end() &&
  2168. foundFile.find("lang/") == foundFile.npos) {
  2169. if(foundUnusedFile == false) {
  2170. printf("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",__LINE__);
  2171. }
  2172. foundUnusedFile = true;
  2173.  
  2174. printf("[%s]\n",foundFile.c_str());
  2175.  
  2176. string fileName = extractFileFromDirectoryPath(foundFile);
  2177. if(loadedFileList.find(fileName) != loadedFileList.end()) {
  2178. printf("possible match on [%s] ?\n",loadedFileList.find(fileName)->first.c_str());
  2179. }
  2180. else if(purgeUnusedFiles == true) {
  2181. off_t fileSize = getFileSize(foundFile);
  2182. // convert to MB
  2183. purgedMegaBytes += ((double)fileSize / 1048576.0);
  2184. purgeCount++;
  2185.  
  2186. if(svnPurgeFiles == true) {
  2187. char szBuf[8096]="";
  2188. snprintf(szBuf,8096,"svn delete \"%s\"",foundFile.c_str());
  2189. bool svnOk = executeShellCommand(szBuf,0);
  2190. if(svnOk == false) {
  2191. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  2192. }
  2193. }
  2194. else {
  2195. removeFile(foundFile);
  2196. }
  2197. }
  2198. }
  2199. }
  2200. if(foundUnusedFile == true) {
  2201. if(purgedMegaBytes > 0) {
  2202. printf("Purged %.2f MB (%d) in files\n",purgedMegaBytes,purgeCount);
  2203. }
  2204. printf("\nLine ref: %d, Warning, unused files were detected - END:\n",__LINE__);
  2205. }
  2206.  
  2207. if(showDuplicateFiles == true) {
  2208. std::map<uint32,vector<string> > mapDuplicateFiles;
  2209. // Now check for duplicate data content
  2210. for(std::map<string,vector<pair<string, string> > >::iterator iterMap = loadedFileList.begin();
  2211. iterMap != loadedFileList.end(); ++iterMap) {
  2212. string fileName = iterMap->first;
  2213. Checksum checksum;
  2214. checksum.addFile(fileName);
  2215. uint32 crcValue = checksum.getSum();
  2216. if(crcValue == 0) {
  2217. char szBuf[8096]="";
  2218. snprintf(szBuf,8096,"Error calculating CRC for file [%s]",fileName.c_str());
  2219. throw megaglest_runtime_error(szBuf);
  2220. }
  2221. // else {
  2222. // printf("** CRC for file [%s] is [%d] and has %d parents\n",fileName.c_str(),crcValue,(int)iterMap->second.size());
  2223. // }
  2224. mapDuplicateFiles[crcValue].push_back(fileName);
  2225. }
  2226.  
  2227. double duplicateMegaBytesPurged=0;
  2228. int duplicateCountPurged=0;
  2229.  
  2230. double duplicateMegaBytes=0;
  2231. int duplicateCount=0;
  2232.  
  2233. bool foundDuplicates = false;
  2234. for(std::map<uint32,vector<string> >::iterator iterMap = mapDuplicateFiles.begin();
  2235. iterMap != mapDuplicateFiles.end(); ++iterMap) {
  2236. vector<string> &fileList = iterMap->second;
  2237. if(fileList.size() > 1) {
  2238. if(foundDuplicates == false) {
  2239. foundDuplicates = true;
  2240. printf("\nWarning, duplicate files were detected - START:\n=====================\n");
  2241. }
  2242.  
  2243. printf("----- START duplicate files for CRC [%u] count [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",iterMap->first,fileList.size(),fileList[0].c_str());
  2244.  
  2245. map<string,int> parentList;
  2246. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  2247. string duplicateFile = fileList[idx];
  2248. if(idx > 0) {
  2249. off_t fileSize = getFileSize(duplicateFile);
  2250. // convert to MB
  2251. duplicateMegaBytes += ((double)fileSize / 1048576.0);
  2252. duplicateCount++;
  2253. }
  2254. else {
  2255. printf("\n");
  2256. }
  2257.  
  2258. printf("[%s]\n",duplicateFile.c_str());
  2259. std::map<string,vector<pair<string, string> > >::iterator iterFind = loadedFileList.find(duplicateFile);
  2260. if(iterFind != loadedFileList.end()) {
  2261. for(unsigned int jdx = 0; jdx < iterFind->second.size(); jdx++) {
  2262. parentList[iterFind->second[jdx].first]++;
  2263. }
  2264. }
  2265.  
  2266. //!!!
  2267. string newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
  2268. string expandedNewCommonFileName = newCommonFileName;
  2269. std::map<string,string> mapExtraTagReplacementValues;
  2270. string techCommonData = techPath + techName + "/commondata/";
  2271. replaceAll(techCommonData, "//", "/");
  2272. mapExtraTagReplacementValues["$COMMONDATAPATH"] = techCommonData;
  2273. mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues);
  2274. Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues);
  2275. replaceAll(expandedNewCommonFileName, "//", "/");
  2276.  
  2277. //printf("**** Checking for partial commondata scenario [%s] [%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  2278. //if(StartsWith(duplicateFile, expandedNewCommonFileName) == true) {
  2279. // throw megaglest_runtime_error("ERROR, this configuration has partial common data and duplicates, aborting..");
  2280. //}
  2281. }
  2282.  
  2283. printf("----- Finding parents for duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str());
  2284.  
  2285. for(map<string,int>::iterator iterMap1 = parentList.begin();
  2286. iterMap1 != parentList.end(); ++iterMap1) {
  2287.  
  2288. if(iterMap1 == parentList.begin()) {
  2289. printf("\tParents:\n");
  2290. }
  2291. printf("\t[%s]\n",iterMap1->first.c_str());
  2292. }
  2293.  
  2294. if(purgeDuplicateFiles == true) {
  2295. //printf("\nPurge Duplicate Files detected - START:\n=====================\n");
  2296.  
  2297. printf("----- move / remove duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str());
  2298. // First move first duplicate to commondata and delete all other copies
  2299. string newCommonFileName = "";
  2300. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  2301. string duplicateFile = fileList[idx];
  2302. string fileExt = extractExtension(duplicateFile);
  2303. if(fileExt == "wav" || fileExt == "ogg") {
  2304. off_t fileSize = getFileSize(duplicateFile);
  2305.  
  2306. printf("#1 [%u / " MG_SIZE_T_SPECIFIER "] removing duplicate [%s]\n",idx,fileList.size(),duplicateFile.c_str());
  2307.  
  2308. if(idx == 0) {
  2309. newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
  2310.  
  2311. string expandedNewCommonFileName = newCommonFileName;
  2312.  
  2313. std::map<string,string> mapExtraTagReplacementValues;
  2314.  
  2315. string techCommonData = techPath + techName + "/commondata/";
  2316. replaceAll(techCommonData, "//", "/");
  2317.  
  2318. mapExtraTagReplacementValues["$COMMONDATAPATH"] = techCommonData;
  2319. mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues);
  2320. Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues);
  2321. replaceAll(expandedNewCommonFileName, "//", "/");
  2322. createDirectoryPaths(extractDirectoryPathFromFile(expandedNewCommonFileName));
  2323.  
  2324. if(svnPurgeFiles == true) {
  2325. copyFileTo(duplicateFile, expandedNewCommonFileName);
  2326.  
  2327. char szBuf[8096]="";
  2328. snprintf(szBuf,8096,"svn delete \"%s\"",duplicateFile.c_str());
  2329. bool svnOk = executeShellCommand(szBuf,0);
  2330. if(svnOk == false) {
  2331. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  2332. }
  2333. printf("*** Duplicate file:\n[%s]\nwas svn deleted and copied to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  2334. }
  2335. else {
  2336. //int result = 0;
  2337. printf("moving duplicate [%s] to common data [%s] expanded to [%s]\n",duplicateFile.c_str(),newCommonFileName.c_str(),expandedNewCommonFileName.c_str());
  2338.  
  2339. int result = rename(duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  2340. if(result != 0) {
  2341. char szBuf[8096]="";
  2342. char *errmsg = strerror(errno);
  2343. snprintf(szBuf,8096,"!!! Error [%s] Could not rename [%s] to [%s]!",errmsg,duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  2344. throw megaglest_runtime_error(szBuf);
  2345. }
  2346. else {
  2347. printf("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str());
  2348. }
  2349. }
  2350. }
  2351. else {
  2352. if(svnPurgeFiles == true) {
  2353. char szBuf[8096]="";
  2354. snprintf(szBuf,8096,"svn delete \"%s\"",duplicateFile.c_str());
  2355. bool svnOk = executeShellCommand(szBuf,0);
  2356. if(svnOk == false) {
  2357. throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]");
  2358. }
  2359. printf("*** Duplicate file:\n[%s]\nwas svn deleted\n",duplicateFile.c_str());
  2360. }
  2361. else {
  2362. printf("removing duplicate [%s]\n",duplicateFile.c_str());
  2363. removeFile(duplicateFile);
  2364. }
  2365. printf("*** Duplicate file:\n[%s]\nwas removed\n",duplicateFile.c_str());
  2366.  
  2367. // convert to MB
  2368. duplicateMegaBytesPurged += ((double)fileSize / 1048576.0);
  2369. duplicateCountPurged++;
  2370. }
  2371. }
  2372. }
  2373.  
  2374. printf("----- update XML files for duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str());
  2375. std::map<string,int> mapUniqueParentList;
  2376.  
  2377. // Update the XML files to point to the new single copy in commondata
  2378. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  2379. string duplicateFile = fileList[idx];
  2380. string fileExt = extractExtension(duplicateFile);
  2381. if(fileExt == "wav" || fileExt == "ogg") {
  2382. std::map<string,vector<pair<string, string> > >::iterator iterFind2 = loadedFileList.find(duplicateFile);
  2383. if(iterFind2 != loadedFileList.end()) {
  2384. for(unsigned int jdx1 = 0; jdx1 < iterFind2->second.size(); jdx1++) {
  2385. string parentFile = iterFind2->second[jdx1].first;
  2386. string searchText = iterFind2->second[jdx1].second;
  2387.  
  2388. if(mapUniqueParentList.find(parentFile) == mapUniqueParentList.end()) {
  2389. printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
  2390. bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false);
  2391. printf("foundText = %d\n",foundText);
  2392. if(foundText == false) {
  2393.  
  2394. string techCommonData = techPath + techName + "/commondata/";
  2395. replaceAll(techCommonData, "//", "/");
  2396.  
  2397. //printf("WARNING #1 techCommonData check\n[%s]\n[%s]\n",techCommonData.c_str(),searchText.c_str());
  2398.  
  2399. if(StartsWith(searchText, techCommonData) == true) {
  2400. printf("WARNING #1 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n",
  2401. foundText,parentFile.c_str(),techCommonData.c_str(),searchText.c_str(),newCommonFileName.c_str());
  2402.  
  2403. replaceAll(searchText, techCommonData, "$COMMONDATAPATH/");
  2404. foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false);
  2405.  
  2406. printf("WARNING #2 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n",
  2407. foundText,parentFile.c_str(),techCommonData.c_str(),searchText.c_str(),newCommonFileName.c_str());
  2408. }
  2409. if(foundText == false) {
  2410. //printf("Error finding text [%s] in file [%s]",searchText.c_str(),parentFile.c_str());
  2411.  
  2412. char szBuf[8096]="";
  2413. snprintf(szBuf,8096,"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",__LINE__,searchText.c_str(),parentFile.c_str(),newCommonFileName.c_str());
  2414. printf("\n\n=================================================\n%s",szBuf);
  2415.  
  2416. throw megaglest_runtime_error(szBuf);
  2417. }
  2418. }
  2419. mapUniqueParentList[parentFile]++;
  2420. }
  2421. }
  2422. }
  2423. }
  2424. }
  2425.  
  2426. //printf("\nPurge Duplicate Files detected - END:\n=====================\n");
  2427. }
  2428. else {
  2429. //printf("\nPurge Duplicate Files DISABLED - START:\n=====================\n");
  2430.  
  2431. string newCommonFileName = "";
  2432. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  2433. string duplicateFile = fileList[idx];
  2434. string fileExt = extractExtension(duplicateFile);
  2435. if(fileExt == "wav" || fileExt == "ogg") {
  2436. off_t fileSize = getFileSize(duplicateFile);
  2437. if(idx == 0) {
  2438. newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile);
  2439. break;
  2440. }
  2441. }
  2442. }
  2443.  
  2444. //printf("\nPurge Duplicate Files #2 DISABLED [" MG_SIZE_T_SPECIFIER "] - START:\n=====================\n",fileList.size());
  2445.  
  2446. for(unsigned int idx = 0; idx < fileList.size(); ++idx) {
  2447. string duplicateFile = fileList[idx];
  2448. string fileExt = extractExtension(duplicateFile);
  2449. if(fileExt == "wav" || fileExt == "ogg") {
  2450. std::map<string,vector<pair<string, string> > >::iterator iterFind4 = loadedFileList.find(duplicateFile);
  2451. if(iterFind4 != loadedFileList.end()) {
  2452. for(unsigned int jdx = 0; jdx < iterFind4->second.size(); jdx++) {
  2453. string parentFile = iterFind4->second[jdx].first;
  2454. string searchText = iterFind4->second[jdx].second;
  2455. //replaceAll(parentFile, "//", "/");
  2456. //replaceAll(parentFile, "\\\\", "\\");
  2457.  
  2458. //printf("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n",parentFile.c_str(),searchText.c_str(),newCommonFileName.c_str());
  2459. bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true);
  2460. //printf("foundText = %d\n",foundText);
  2461. if(foundText == false) {
  2462. string techCommonData = techPath + techName + "/commondata/";
  2463. replaceAll(techCommonData, "//", "/");
  2464.  
  2465. //printf("WARNING #1 techCommonData check\n[%s]\n[%s]\n",techCommonData.c_str(),searchText.c_str());
  2466.  
  2467. if(StartsWith(searchText, techCommonData) == true) {
  2468. replaceAll(searchText, techCommonData, "$COMMONDATAPATH/");
  2469. foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true);
  2470.  
  2471. //printf("WARNING #2 techCommonData check\n[%s]\n[%s]\n[%s]\n",techCommonData.c_str(),searchText.c_str(),newCommonFileName.c_str());
  2472. }
  2473. if(foundText == false) {
  2474. //printf("Error finding text [%s] in file [%s]",searchText.c_str(),parentFile.c_str());
  2475.  
  2476. // Check if the sound file already references commandata
  2477. foundText = searchAndReplaceTextInFile(parentFile, newCommonFileName, newCommonFileName, true);
  2478. if(foundText == false) {
  2479. char szBuf[8096]="";
  2480. snprintf(szBuf,8096,"Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n",__LINE__,searchText.c_str(),parentFile.c_str(),newCommonFileName.c_str());
  2481. printf("\n\n=================================================\n%s",szBuf);
  2482.  
  2483. throw megaglest_runtime_error(szBuf);
  2484. }
  2485. }
  2486. }
  2487. }
  2488. }
  2489. }
  2490. }
  2491.  
  2492. //printf("\nPurge Duplicate Files DISABLED - END:\n=====================\n");
  2493. }
  2494.  
  2495.  
  2496. printf("----- END duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str());
  2497. }
  2498. }
  2499. if(foundDuplicates == true) {
  2500. printf("Duplicates %.2f MB (%d) in files\n",duplicateMegaBytes,duplicateCount);
  2501. printf("Duplicates purged %.2f MB (%d) in files\n",duplicateMegaBytesPurged,duplicateCountPurged);
  2502.  
  2503. printf("\nWarning, duplicate files were detected - END:\n");
  2504. }
  2505. }
  2506.  
  2507. if(techtree_errors == false) {
  2508. printf("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n",techPath.c_str(), techName.c_str(),(int)factions.size());
  2509. for ( set<string>::iterator it = factions.begin(); it != factions.end(); ++it ) {
  2510. printf("Faction [%s]\n",(*it).c_str());
  2511. }
  2512. }
  2513. }
  2514. printf("----------------------------------------------------------------");
  2515. }
  2516. }
  2517.  
  2518.  
  2519. void runTechTranslationExtractionForPath(string techPath, string techName,
  2520. const std::vector<string> &filteredFactionList, World &world) {
  2521. //Config &config = Config::getInstance();
  2522. vector<string> factionsList;
  2523. findDirs(techPath + techName + "/factions/", factionsList, false, false);
  2524.  
  2525. if(factionsList.empty() == false) {
  2526. Checksum checksum;
  2527. set<string> factions;
  2528. for(int j = 0; j < factionsList.size(); ++j) {
  2529. if( filteredFactionList.empty() == true ||
  2530. std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
  2531. factions.insert(factionsList[j]);
  2532. }
  2533. }
  2534.  
  2535. printf("\n----------------------------------------------------------------");
  2536. printf("\nChecking techPath [%s] techName [%s] total faction count = %d\n",techPath.c_str(), techName.c_str(),(int)factionsList.size());
  2537. for(int j = 0; j < factionsList.size(); ++j) {
  2538. if( filteredFactionList.empty() == true ||
  2539. std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) {
  2540. printf("Using faction [%s]\n",factionsList[j].c_str());
  2541. }
  2542. }
  2543.  
  2544. if(factions.empty() == false) {
  2545. std::map<string,vector<pair<string, string> > > loadedFileList;
  2546. //vector<string> pathList = config.getPathListForType(ptTechs,"");
  2547. vector<string> pathList;
  2548. pathList.push_back(techPath);
  2549. Config &config = Config::getInstance();
  2550. vector<string> otherTechPaths = config.getPathListForType(ptTechs,"");
  2551. pathList.insert(pathList.end(), otherTechPaths.begin(), otherTechPaths.end());
  2552. world.loadTech(pathList, techName, factions, &checksum, loadedFileList);
  2553.  
  2554. const TechTree *techtree = world.getTechTree();
  2555. string translationFile = techtree->getPath();
  2556. endPathWithSlash(translationFile);
  2557. translationFile += "lang/" + techName + "_default.lng";
  2558. if(fileExists(translationFile) == false) {
  2559. string txFilePath = extractDirectoryPathFromFile(translationFile);
  2560. createDirectoryPaths(txFilePath);
  2561.  
  2562. #if defined(WIN32) && !defined(__MINGW32__)
  2563. FILE *fp = _wfopen(utf8_decode(translationFile).c_str(), L"w");
  2564. std::ofstream txFile(fp);
  2565. #else
  2566. std::ofstream txFile;
  2567. txFile.open(translationFile.c_str(), ios_base::out | ios_base::trunc);
  2568. #endif
  2569.  
  2570. if(txFile.is_open() == true) {
  2571. txFile << "TechTreeName=" << techName << std::endl;
  2572.  
  2573. txFile << "; --------------" << std::endl;
  2574. txFile << "; Types of Armor" << std::endl;
  2575. for(unsigned int index = 0; index < techtree->getArmorTypeCount(); ++index) {
  2576. const ArmorType *at = techtree->getArmorTypeByIndex(index);
  2577. txFile << "ArmorTypeName_" << at->getName(false) << "=" << at->getName(false) << std::endl;
  2578. }
  2579.  
  2580. txFile << "; -------------- " << std::endl;
  2581. txFile << "; Types of Attack" << std::endl;
  2582. for(unsigned int index = 0; index < techtree->getAttackTypeCount(); ++index) {
  2583. const AttackType *at = techtree->getAttackTypeByIndex(index);
  2584. txFile << "AttackTypeName_" << at->getName(false) << "=" << at->getName(false) << std::endl;
  2585. }
  2586.  
  2587. txFile << "; ------------------" << std::endl;
  2588. txFile << "; Types of Resources" << std::endl;
  2589. for(unsigned int index = 0; index < techtree->getResourceTypeCount(); ++index) {
  2590. const ResourceType *rt = techtree->getResourceType(index);
  2591. txFile << "ResourceTypeName_" << rt->getName(false) << "=" << rt->getName(false) << std::endl;
  2592. }
  2593.  
  2594. txFile << "; -----------------" << std::endl;
  2595. txFile << "; Types of Factions" << std::endl;
  2596. txFile << "FactionName_" << GameConstants::OBSERVER_SLOTNAME << "=" << GameConstants::OBSERVER_SLOTNAME << std::endl;
  2597. txFile << "FactionName_" << GameConstants::RANDOMFACTION_SLOTNAME << "=" << GameConstants::RANDOMFACTION_SLOTNAME << std::endl;
  2598.  
  2599. for(unsigned int index = 0; index < techtree->getTypeCount(); ++index) {
  2600. const FactionType *ft = techtree->getType(index);
  2601. txFile << "FactionName_" << ft->getName(false) << "=" << ft->getName(false) << std::endl;
  2602.  
  2603. txFile << "; ----------------------------------" << std::endl;
  2604. txFile << "; Types of Upgrades for this Faction" << std::endl;
  2605. for(unsigned int upgradeIndex = 0; upgradeIndex < ft->getUpgradeTypeCount(); ++upgradeIndex) {
  2606. const UpgradeType *upt = ft->getUpgradeType(upgradeIndex);
  2607. txFile << "UpgradeTypeName_" << upt->getName(false) << "=" << upt->getName(false) << std::endl;
  2608. }
  2609.  
  2610. txFile << "; -------------------------------" << std::endl;
  2611. txFile << "; Types of Units for this Faction" << std::endl;
  2612. for(unsigned int unitIndex = 0; unitIndex < ft->getUnitTypeCount(); ++unitIndex) {
  2613. const UnitType *ut = ft->getUnitType(unitIndex);
  2614. txFile << "UnitTypeName_" << ut->getName(false) << "=" << ut->getName(false) << std::endl;
  2615.  
  2616. txFile << "; --------------------" << std::endl;
  2617. txFile << "; Levels for this Unit" << std::endl;
  2618. for(unsigned int levelIndex = 0; levelIndex < ut->getLevelCount(); ++levelIndex) {
  2619. const Level *level = ut->getLevel(levelIndex);
  2620. txFile << "LevelName_" << level->getName(false) << "=" << level->getName(false) << std::endl;
  2621. }
  2622.  
  2623. txFile << "; -------------------------------" << std::endl;
  2624. txFile << "; Types of Commands for this Unit" << std::endl;
  2625. for(unsigned int commandIndex = 0; commandIndex < ut->getCommandTypeCount(); ++commandIndex) {
  2626. const CommandType *ct = ut->getCommandType(commandIndex);
  2627. txFile << "CommandName_" << ct->getName(false) << "=" << ct->getName(false) << std::endl;
  2628. }
  2629. }
  2630. }
  2631. }
  2632. txFile.close();
  2633.  
  2634. #if defined(WIN32) && !defined(__MINGW32__)
  2635. if(fp) {
  2636. fclose(fp);
  2637. }
  2638. #endif
  2639.  
  2640. }
  2641. else {
  2642. printf("\n** Cannot product techtree translation file [%s] for techPath [%s] techName [%s] because the file already exists!\n",translationFile.c_str(),techPath.c_str(), techName.c_str());
  2643. }
  2644. }
  2645. printf("----------------------------------------------------------------");
  2646. }
  2647. }
  2648.  
  2649. void runTechTranslationExtraction(int argc, char** argv) {
  2650. //disableBacktrace=true;
  2651. printf("====== Started Translation Extraction ======\n");
  2652.  
  2653. Config &config = Config::getInstance();
  2654.  
  2655. // Did the user pass a specific list of factions to validate?
  2656. std::vector<string> filteredFactionList;
  2657.  
  2658. vector<string> results;
  2659. findDirs(config.getPathListForType(ptTechs), results);
  2660. vector<string> techTreeFiles = results;
  2661. // Did the user pass a specific list of techtrees to validate?
  2662. std::vector<string> filteredTechTreeList;
  2663. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string("=")) == true) {
  2664. int foundParamIndIndex = -1;
  2665. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string("="),&foundParamIndIndex);
  2666. string filterList = argv[foundParamIndIndex];
  2667. vector<string> paramPartTokens;
  2668. Tokenize(filterList,paramPartTokens,"=");
  2669. if(paramPartTokens.size() >= 2) {
  2670. string techtreeList = paramPartTokens[1];
  2671. Tokenize(techtreeList,filteredTechTreeList,",");
  2672.  
  2673. if(filteredTechTreeList.empty() == false) {
  2674. printf("Filtering techtrees and only looking for the following:\n");
  2675. for(int idx = 0; idx < filteredTechTreeList.size(); ++idx) {
  2676. filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]);
  2677. printf("%s\n",filteredTechTreeList[idx].c_str());
  2678. }
  2679. }
  2680.  
  2681. // if(paramPartTokens.size() >= 3) {
  2682. // if(paramPartTokens[2] == "purgeunused") {
  2683. // purgeUnusedFiles = true;
  2684. // printf("*NOTE All unused techtree files will be deleted!\n");
  2685. // }
  2686. // else if(paramPartTokens[2] == "purgeduplicates") {
  2687. // purgeDuplicateFiles = true;
  2688. // printf("*NOTE All duplicate techtree files will be merged!\n");
  2689. // }
  2690. // else if(paramPartTokens[2] == "svndelete") {
  2691. // svnPurgeFiles = true;
  2692. // printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2693. // }
  2694. // else if(paramPartTokens[2] == "hideduplicates") {
  2695. // showDuplicateFiles = false;
  2696. // printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2697. // }
  2698. // }
  2699. // if(paramPartTokens.size() >= 4) {
  2700. // if(paramPartTokens[3] == "purgeunused") {
  2701. // purgeUnusedFiles = true;
  2702. // printf("*NOTE All unused techtree files will be deleted!\n");
  2703. // }
  2704. // else if(paramPartTokens[3] == "purgeduplicates") {
  2705. // purgeDuplicateFiles = true;
  2706. // printf("*NOTE All duplicate techtree files will be merged!\n");
  2707. // }
  2708. // else if(paramPartTokens[3] == "svndelete") {
  2709. // svnPurgeFiles = true;
  2710. // printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2711. // }
  2712. // else if(paramPartTokens[3] == "hideduplicates") {
  2713. // showDuplicateFiles = false;
  2714. // printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2715. // }
  2716. // }
  2717. // if(paramPartTokens.size() >= 5) {
  2718. // if(paramPartTokens[4] == "purgeunused") {
  2719. // purgeUnusedFiles = true;
  2720. // printf("*NOTE All unused techtree files will be deleted!\n");
  2721. // }
  2722. // else if(paramPartTokens[4] == "purgeduplicates") {
  2723. // purgeDuplicateFiles = true;
  2724. // printf("*NOTE All duplicate techtree files will be merged!\n");
  2725. // }
  2726. // else if(paramPartTokens[4] == "svndelete") {
  2727. // svnPurgeFiles = true;
  2728. // printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2729. // }
  2730. // else if(paramPartTokens[4] == "hideduplicates") {
  2731. // showDuplicateFiles = false;
  2732. // printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2733. // }
  2734. // }
  2735.  
  2736. }
  2737. }
  2738.  
  2739. {
  2740. printf("\n---------------- Loading factions inside world ----------------");
  2741. World world;
  2742.  
  2743. vector<string> techPaths = config.getPathListForType(ptTechs);
  2744. for(int idx = 0; idx < techPaths.size(); idx++) {
  2745. string &techPath = techPaths[idx];
  2746. endPathWithSlash(techPath);
  2747.  
  2748. //printf("techPath [%s]\n",techPath.c_str());
  2749.  
  2750. for(int idx2 = 0; idx2 < techTreeFiles.size(); idx2++) {
  2751. string &techName = techTreeFiles[idx2];
  2752.  
  2753. if( filteredTechTreeList.empty() == true ||
  2754. std::find(filteredTechTreeList.begin(),filteredTechTreeList.end(),techName) != filteredTechTreeList.end()) {
  2755.  
  2756. runTechTranslationExtractionForPath(techPath, techName,
  2757. filteredFactionList,world);
  2758. }
  2759. }
  2760. }
  2761.  
  2762. printf("\n====== Finished Translation ======\n");
  2763. }
  2764.  
  2765. }
  2766.  
  2767.  
  2768. void runTechValidationReport(int argc, char** argv) {
  2769. //disableBacktrace=true;
  2770. printf("====== Started Validation ======\n");
  2771.  
  2772. bool purgeDuplicateFiles = false;
  2773. bool showDuplicateFiles = true;
  2774. bool purgeUnusedFiles = false;
  2775. bool svnPurgeFiles = false;
  2776.  
  2777. double purgedMegaBytes=0;
  2778. Config &config = Config::getInstance();
  2779.  
  2780. // Did the user pass a specific scenario to validate?
  2781. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("=")) == true) {
  2782.  
  2783. int foundParamIndIndex = -1;
  2784. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("="),&foundParamIndIndex);
  2785.  
  2786. string filterList = argv[foundParamIndIndex];
  2787. vector<string> paramPartTokens;
  2788. Tokenize(filterList,paramPartTokens,"=");
  2789.  
  2790. if(paramPartTokens.size() >= 2) {
  2791. //vector<string> optionList;
  2792. string validateScenarioName = paramPartTokens[1];
  2793.  
  2794. printf("Filtering scenario: %s\n",validateScenarioName.c_str());
  2795.  
  2796. if(paramPartTokens.size() >= 3) {
  2797. if(paramPartTokens[2] == "purgeunused") {
  2798. purgeUnusedFiles = true;
  2799. printf("*NOTE All unused scenario files will be deleted!\n");
  2800. }
  2801. }
  2802.  
  2803. {
  2804. printf("\n---------------- Loading scenario inside world ----------------\n");
  2805.  
  2806. bool scenarioFound = false;
  2807. World world;
  2808. //double purgedMegaBytes=0;
  2809. std::vector<string> filteredFactionList;
  2810.  
  2811. vector<string> scenarioPaths = config.getPathListForType(ptScenarios);
  2812. for(int idx = 0; idx < scenarioPaths.size(); idx++) {
  2813. string &scenarioPath = scenarioPaths[idx];
  2814. endPathWithSlash(scenarioPath);
  2815.  
  2816. //printf("techPath [%s]\n",techPath.c_str());
  2817.  
  2818. vector<string> scenarioList;
  2819. findDirs(scenarioPath, scenarioList, false, false);
  2820. for(int idx2 = 0; idx2 < scenarioList.size(); idx2++) {
  2821. string &scenarioName = scenarioList[idx2];
  2822.  
  2823. //printf("Comparing Scenario [%s] looking for [%s]\n",scenarioName.c_str(),validateScenarioName.c_str());
  2824.  
  2825. if(scenarioName == validateScenarioName) {
  2826. scenarioFound = true;
  2827.  
  2828. string file = scenarioPath + scenarioName + "/" + scenarioName + ".xml";
  2829.  
  2830. XmlTree xmlTree;
  2831. xmlTree.load(file,Properties::getTagReplacementValues());
  2832. const XmlNode *scenarioNode= xmlTree.getRootNode();
  2833. string techName = scenarioNode->getChild("tech-tree")->getAttribute("value")->getValue();
  2834.  
  2835. // Self Contained techtree?
  2836. string scenarioTechtree = scenarioPath + scenarioName + "/" + techName + "/" + techName + ".xml";
  2837.  
  2838. printf("\nFound Scenario [%s] looking for techtree [%s]...\n",scenarioName.c_str(),scenarioTechtree.c_str());
  2839.  
  2840. if(fileExists(scenarioTechtree) == true) {
  2841. string techPath = scenarioPath + scenarioName + "/";
  2842.  
  2843. printf("\nFound Scenario [%s] with custom techtree [%s] validating...\n",scenarioName.c_str(),techName.c_str());
  2844. runTechValidationForPath(techPath, techName, filteredFactionList,
  2845. world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes);
  2846. }
  2847. else {
  2848. vector<string> techPaths = config.getPathListForType(ptTechs);
  2849. for(int idx = 0; idx < techPaths.size(); idx++) {
  2850. string &techPath = techPaths[idx];
  2851. endPathWithSlash(techPath);
  2852.  
  2853. //printf("techPath [%s]\n",techPath.c_str());
  2854.  
  2855.  
  2856. //string techPath = scenarioPath + scenarioName + "/";
  2857. scenarioTechtree = techPath + "/" + techName + "/" + techName + ".xml";
  2858. if(fileExists(scenarioTechtree) == true) {
  2859. printf("\nFound Scenario [%s] with techtree [%s] validating...\n",scenarioName.c_str(),techName.c_str());
  2860. runTechValidationForPath(techPath, techName, filteredFactionList,
  2861. world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes);
  2862.  
  2863. break;
  2864. }
  2865. }
  2866. }
  2867. //
  2868. //
  2869. // runTechValidationForPath(techPath, techName, filteredFactionList,
  2870. // world, purgeUnusedFiles,purgedMegaBytes);
  2871. }
  2872. }
  2873. }
  2874.  
  2875. if(scenarioFound == false) {
  2876. printf("\nWARNING, the scenario [%s] was NOT FOUND!\n",validateScenarioName.c_str());
  2877. }
  2878. printf("\n====== Finished Validation ======\n");
  2879. }
  2880. return;
  2881. }
  2882. else {
  2883. printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  2884. //printParameterHelp(argv[0],false);
  2885. return;
  2886. }
  2887. }
  2888.  
  2889. // Did the user pass a specific list of factions to validate?
  2890. std::vector<string> filteredFactionList;
  2891. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("=")) == true) {
  2892. int foundParamIndIndex = -1;
  2893. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("="),&foundParamIndIndex);
  2894.  
  2895. string filterList = argv[foundParamIndIndex];
  2896. vector<string> paramPartTokens;
  2897. Tokenize(filterList,paramPartTokens,"=");
  2898.  
  2899. if(paramPartTokens.size() >= 2) {
  2900. string factionList = paramPartTokens[1];
  2901. Tokenize(factionList,filteredFactionList,",");
  2902.  
  2903. if(filteredFactionList.empty() == false) {
  2904. printf("Filtering factions and only looking for the following:\n");
  2905. for(int idx = 0; idx < filteredFactionList.size(); ++idx) {
  2906. filteredFactionList[idx] = trim(filteredFactionList[idx]);
  2907. printf("%s\n",filteredFactionList[idx].c_str());
  2908. }
  2909. }
  2910.  
  2911. if(paramPartTokens.size() >= 3) {
  2912. if(paramPartTokens[2] == "purgeunused") {
  2913. purgeUnusedFiles = true;
  2914. printf("*NOTE All unused faction files will be deleted!\n");
  2915. }
  2916. }
  2917. }
  2918. }
  2919. vector<string> results;
  2920. findDirs(config.getPathListForType(ptTechs), results);
  2921. vector<string> techTreeFiles = results;
  2922. // Did the user pass a specific list of techtrees to validate?
  2923. std::vector<string> filteredTechTreeList;
  2924. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("=")) == true) {
  2925. int foundParamIndIndex = -1;
  2926. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("="),&foundParamIndIndex);
  2927. string filterList = argv[foundParamIndIndex];
  2928. vector<string> paramPartTokens;
  2929. Tokenize(filterList,paramPartTokens,"=");
  2930. if(paramPartTokens.size() >= 2) {
  2931. string techtreeList = paramPartTokens[1];
  2932. Tokenize(techtreeList,filteredTechTreeList,",");
  2933.  
  2934. if(filteredTechTreeList.empty() == false) {
  2935. printf("Filtering techtrees and only looking for the following:\n");
  2936. for(int idx = 0; idx < filteredTechTreeList.size(); ++idx) {
  2937. filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]);
  2938. printf("%s\n",filteredTechTreeList[idx].c_str());
  2939. }
  2940. }
  2941.  
  2942. if(paramPartTokens.size() >= 3) {
  2943. if(paramPartTokens[2] == "purgeunused") {
  2944. purgeUnusedFiles = true;
  2945. printf("*NOTE All unused techtree files will be deleted!\n");
  2946. }
  2947. else if(paramPartTokens[2] == "purgeduplicates") {
  2948. purgeDuplicateFiles = true;
  2949. printf("*NOTE All duplicate techtree files will be merged!\n");
  2950. }
  2951. else if(paramPartTokens[2] == "svndelete") {
  2952. svnPurgeFiles = true;
  2953. printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2954. }
  2955. else if(paramPartTokens[2] == "hideduplicates") {
  2956. showDuplicateFiles = false;
  2957. printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2958. }
  2959. }
  2960. if(paramPartTokens.size() >= 4) {
  2961. if(paramPartTokens[3] == "purgeunused") {
  2962. purgeUnusedFiles = true;
  2963. printf("*NOTE All unused techtree files will be deleted!\n");
  2964. }
  2965. else if(paramPartTokens[3] == "purgeduplicates") {
  2966. purgeDuplicateFiles = true;
  2967. printf("*NOTE All duplicate techtree files will be merged!\n");
  2968. }
  2969. else if(paramPartTokens[3] == "svndelete") {
  2970. svnPurgeFiles = true;
  2971. printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2972. }
  2973. else if(paramPartTokens[3] == "hideduplicates") {
  2974. showDuplicateFiles = false;
  2975. printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2976. }
  2977. }
  2978. if(paramPartTokens.size() >= 5) {
  2979. if(paramPartTokens[4] == "purgeunused") {
  2980. purgeUnusedFiles = true;
  2981. printf("*NOTE All unused techtree files will be deleted!\n");
  2982. }
  2983. else if(paramPartTokens[4] == "purgeduplicates") {
  2984. purgeDuplicateFiles = true;
  2985. printf("*NOTE All duplicate techtree files will be merged!\n");
  2986. }
  2987. else if(paramPartTokens[4] == "svndelete") {
  2988. svnPurgeFiles = true;
  2989. printf("*NOTE All unused / duplicate techtree files will be removed from svn!\n");
  2990. }
  2991. else if(paramPartTokens[4] == "hideduplicates") {
  2992. showDuplicateFiles = false;
  2993. printf("*NOTE All duplicate techtree files will NOT be shown!\n");
  2994. }
  2995. }
  2996.  
  2997. }
  2998. }
  2999.  
  3000. {
  3001. printf("\n---------------- Loading factions inside world ----------------");
  3002. World world;
  3003.  
  3004. vector<string> techPaths = config.getPathListForType(ptTechs);
  3005. for(int idx = 0; idx < techPaths.size(); idx++) {
  3006. string &techPath = techPaths[idx];
  3007. endPathWithSlash(techPath);
  3008.  
  3009. //printf("techPath [%s]\n",techPath.c_str());
  3010.  
  3011. for(int idx2 = 0; idx2 < techTreeFiles.size(); idx2++) {
  3012. string &techName = techTreeFiles[idx2];
  3013.  
  3014. if( filteredTechTreeList.empty() == true ||
  3015. std::find(filteredTechTreeList.begin(),filteredTechTreeList.end(),techName) != filteredTechTreeList.end()) {
  3016.  
  3017. runTechValidationForPath(techPath, techName, filteredFactionList,
  3018. world, purgeUnusedFiles,purgeDuplicateFiles,
  3019. showDuplicateFiles,svnPurgeFiles,purgedMegaBytes);
  3020. }
  3021. }
  3022. }
  3023.  
  3024. printf("\n====== Finished Validation ======\n");
  3025. }
  3026.  
  3027. }
  3028.  
  3029. void runTilesetValidationReport(int argc, char** argv) {
  3030. //disableBacktrace=true;
  3031. printf("====== Started Validation ======\n");
  3032.  
  3033. //double purgedMegaBytes=0;
  3034. Config &config = Config::getInstance();
  3035.  
  3036. // Did the user pass a specific tileset to validate?
  3037. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string("=")) == true) {
  3038. int foundParamIndIndex = -1;
  3039. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string("="),&foundParamIndIndex);
  3040.  
  3041. string filterList = argv[foundParamIndIndex];
  3042. vector<string> paramPartTokens;
  3043. Tokenize(filterList,paramPartTokens,"=");
  3044.  
  3045. if(paramPartTokens.size() >= 2) {
  3046. //vector<string> optionList;
  3047. string validateTilesetName = paramPartTokens[1];
  3048.  
  3049. printf("Filtering tileset: %s\n",validateTilesetName.c_str());
  3050.  
  3051. bool purgeUnusedFiles = false;
  3052. if(paramPartTokens.size() >= 3) {
  3053. if(paramPartTokens[2] == "purgeunused") {
  3054. purgeUnusedFiles = true;
  3055. printf("*NOTE All unused tileset files will be deleted!\n");
  3056. }
  3057. }
  3058.  
  3059. {
  3060. printf("\n---------------- Loading tileset inside world ----------------\n");
  3061.  
  3062. World world;
  3063. double purgedMegaBytes=0;
  3064. bool showDuplicateFiles = true;
  3065.  
  3066. //std::vector<string> filteredFactionList;
  3067.  
  3068. vector<string> tilesetPaths = config.getPathListForType(ptTilesets);
  3069. for(int idx = 0; idx < tilesetPaths.size(); idx++) {
  3070. string &tilesetPath = tilesetPaths[idx];
  3071. endPathWithSlash(tilesetPath);
  3072.  
  3073. vector<string> tilesetList;
  3074. findDirs(tilesetPath, tilesetList, false, false);
  3075. for(int idx2 = 0; idx2 < tilesetList.size(); idx2++) {
  3076. string &tilesetName = tilesetList[idx2];
  3077. if(tilesetName == validateTilesetName) {
  3078. runTilesetValidationForPath(tilesetPath, tilesetName,
  3079. world, purgeUnusedFiles, showDuplicateFiles,
  3080. false, false, purgedMegaBytes);
  3081. }
  3082. }
  3083. }
  3084.  
  3085. printf("\n====== Finished Validation ======\n");
  3086. }
  3087. return;
  3088. }
  3089. else {
  3090. printf("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3091. return;
  3092. }
  3093. }
  3094. else {
  3095. printf("\nInvalid missing tileset specified on commandline\n\n");
  3096. return;
  3097. }
  3098. }
  3099.  
  3100. void ShowINISettings(int argc, char **argv,Config &config,Config &configKeys) {
  3101. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) {
  3102. vector<string> filteredPropertyList;
  3103. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("=")) == true) {
  3104. int foundParamIndIndex = -1;
  3105. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("="),&foundParamIndIndex);
  3106. string filterList = argv[foundParamIndIndex];
  3107. vector<string> paramPartTokens;
  3108. Tokenize(filterList,paramPartTokens,"=");
  3109. if(paramPartTokens.size() >= 2) {
  3110. string tokenList = paramPartTokens[1];
  3111. Tokenize(tokenList,filteredPropertyList,",");
  3112.  
  3113. if(filteredPropertyList.empty() == false) {
  3114. printf("Filtering properties and only looking for the following:\n");
  3115. for(int idx = 0; idx < filteredPropertyList.size(); ++idx) {
  3116. filteredPropertyList[idx] = trim(filteredPropertyList[idx]);
  3117. printf("%s\n",filteredPropertyList[idx].c_str());
  3118. }
  3119. }
  3120. }
  3121. }
  3122.  
  3123. printf("\nMain settings report\n");
  3124. printf("====================\n");
  3125. vector<pair<string,string> > mergedMainSettings = config.getMergedProperties();
  3126. vector<pair<string,string> > mergedKeySettings = configKeys.getMergedProperties();
  3127.  
  3128. // Figure out the max # of tabs we need to format display nicely
  3129. int tabCount = 1;
  3130. for(int i = 0; i < mergedMainSettings.size(); ++i) {
  3131. const pair<string,string> &nameValue = mergedMainSettings[i];
  3132.  
  3133. bool displayProperty = false;
  3134. if(filteredPropertyList.empty() == false) {
  3135. if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
  3136. displayProperty = true;
  3137. }
  3138. }
  3139. else {
  3140. displayProperty = true;
  3141. }
  3142.  
  3143. if(displayProperty == true) {
  3144. int requredTabs = (nameValue.first.length() / 8)+1;
  3145. if(nameValue.first.length() % 8) {
  3146. requredTabs++;
  3147. }
  3148. if(requredTabs > tabCount) {
  3149. tabCount = requredTabs;
  3150. }
  3151. }
  3152. }
  3153. for(int i = 0; i < mergedKeySettings.size(); ++i) {
  3154. const pair<string,string> &nameValue = mergedKeySettings[i];
  3155.  
  3156. bool displayProperty = false;
  3157. if(filteredPropertyList.empty() == false) {
  3158. if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
  3159. displayProperty = true;
  3160. }
  3161. }
  3162. else {
  3163. displayProperty = true;
  3164. }
  3165.  
  3166. if(displayProperty == true) {
  3167. int requredTabs = (nameValue.first.length() / 8)+1;
  3168. if(nameValue.first.length() % 8) {
  3169. requredTabs++;
  3170. }
  3171. if(requredTabs > tabCount) {
  3172. tabCount = requredTabs;
  3173. }
  3174. }
  3175. }
  3176.  
  3177. // Output the properties
  3178. for(int i = 0; i < mergedMainSettings.size(); ++i) {
  3179. const pair<string,string> &nameValue = mergedMainSettings[i];
  3180.  
  3181. bool displayProperty = false;
  3182. if(filteredPropertyList.empty() == false) {
  3183. if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
  3184. displayProperty = true;
  3185. }
  3186. }
  3187. else {
  3188. displayProperty = true;
  3189. }
  3190.  
  3191. if(displayProperty == true) {
  3192. printf("Property Name [%s]",nameValue.first.c_str());
  3193.  
  3194. int tabs = (nameValue.first.length() / 8) + 1;
  3195. for(int j = 0; j < (tabCount - tabs); ++j) {
  3196. printf("\t");
  3197. }
  3198.  
  3199. string displayValue = nameValue.second;
  3200. if(nameValue.first == "TranslationGetURLPassword") {
  3201. displayValue = "*****";
  3202. }
  3203.  
  3204. printf("Value [%s]\n",displayValue.c_str());
  3205. }
  3206. }
  3207.  
  3208. printf("\n\nMain key binding settings report\n");
  3209. printf("====================================\n");
  3210.  
  3211. for(int i = 0; i < mergedKeySettings.size(); ++i) {
  3212. const pair<string,string> &nameValue = mergedKeySettings[i];
  3213.  
  3214. bool displayProperty = false;
  3215. if(filteredPropertyList.empty() == false) {
  3216. if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) {
  3217. displayProperty = true;
  3218. }
  3219. }
  3220. else {
  3221. displayProperty = true;
  3222. }
  3223.  
  3224. if(displayProperty == true) {
  3225. printf("Property Name [%s]",nameValue.first.c_str());
  3226.  
  3227. int tabs = (nameValue.first.length() / 8) + 1;
  3228. for(int j = 0; j < (tabCount - tabs); ++j) {
  3229. printf("\t");
  3230. }
  3231.  
  3232. printf("Value [%s]\n",nameValue.second.c_str());
  3233. }
  3234. }
  3235. }
  3236. }
  3237.  
  3238. void CheckForDuplicateData() {
  3239. Config &config = Config::getInstance();
  3240.  
  3241. string duplicateWarnings="";
  3242.  
  3243. {
  3244. //vector<string> results;
  3245.  
  3246. string scenarioDir = "";
  3247. vector<string> pathList = config.getPathListForType(ptMaps,scenarioDir);
  3248. vector<string> invalidMapList;
  3249. vector<string> maps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList);
  3250. std::sort(maps.begin(),maps.end());
  3251.  
  3252. if(maps.empty() == true) {
  3253. throw megaglest_runtime_error("No maps were found!");
  3254. }
  3255. else if(invalidMapList.empty() == false) {
  3256. string errorMsg = "Warning invalid maps were detected (will be ignored):\n";
  3257. for(int i = 0; i < invalidMapList.size(); ++i) {
  3258. char szBuf[8096]="";
  3259. snprintf(szBuf,8096,"map [%s]\n",invalidMapList[i].c_str());
  3260.  
  3261. errorMsg += szBuf;
  3262. }
  3263. duplicateWarnings += errorMsg;
  3264. }
  3265.  
  3266. vector<string> duplicateMapsToRename;
  3267. for(int i = 0; i < maps.size(); ++i) {
  3268. string map1 = maps[i];
  3269. for(int j = 0; j < maps.size(); ++j) {
  3270. if(i != j) {
  3271. string map2 = maps[j];
  3272.  
  3273. //printf("i = %d map1 [%s] j = %d map2 [%s]\n",i,map1.c_str(),j,map2.c_str());
  3274.  
  3275. if(map1 == map2) {
  3276. if(std::find(duplicateMapsToRename.begin(),duplicateMapsToRename.end(),map1) == duplicateMapsToRename.end()) {
  3277. duplicateMapsToRename.push_back(map1);
  3278. }
  3279. }
  3280. }
  3281. }
  3282. }
  3283. if(duplicateMapsToRename.empty() == false) {
  3284. string errorMsg = "Warning duplicate maps were detected and renamed:\n";
  3285. for(int i = 0; i < duplicateMapsToRename.size(); ++i) {
  3286. string currentPath = pathList[1];
  3287. endPathWithSlash(currentPath);
  3288.  
  3289. string oldFile = currentPath + duplicateMapsToRename[i];
  3290. string newFile = currentPath + duplicateMapsToRename[i];
  3291. string ext = extractExtension(newFile);
  3292. newFile = newFile.substr( 0, newFile.length()-ext.length()-1);
  3293. newFile = newFile + "_custom." + ext;
  3294.  
  3295. char szBuf[8096]="";
  3296. int result = rename(oldFile.c_str(),newFile.c_str());
  3297. if(result != 0) {
  3298. char *errmsg = strerror(errno);
  3299. snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
  3300. throw megaglest_runtime_error(szBuf);
  3301. }
  3302. else {
  3303. snprintf(szBuf,8096,"map [%s] in [%s]\nwas renamed to [%s]",duplicateMapsToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
  3304. }
  3305. errorMsg += szBuf;
  3306. }
  3307. duplicateWarnings += errorMsg;
  3308. }
  3309. }
  3310.  
  3311. {
  3312. //tilesets
  3313. std::vector<std::string> tileSets;
  3314. vector<string> tilesetPaths = config.getPathListForType(ptTilesets);
  3315. findDirs(tilesetPaths, tileSets, false, true);
  3316.  
  3317. if (tileSets.empty()) {
  3318. throw megaglest_runtime_error("No tilesets were found!");
  3319. }
  3320.  
  3321. vector<string> duplicateTilesetsToRename;
  3322. for(int i = 0; i < tileSets.size(); ++i) {
  3323. string tileSet1 = tileSets[i];
  3324. for(int j = 0; j < tileSets.size(); ++j) {
  3325. if(i != j) {
  3326. string tileSet2= tileSets[j];
  3327. if(tileSet1 == tileSet2) {
  3328. if(std::find(duplicateTilesetsToRename.begin(),duplicateTilesetsToRename.end(),tileSet1) == duplicateTilesetsToRename.end()) {
  3329. duplicateTilesetsToRename.push_back(tileSet1);
  3330. }
  3331. }
  3332. }
  3333. }
  3334. }
  3335. if(duplicateTilesetsToRename.empty() == false) {
  3336. string errorMsg = "Warning duplicate tilesets were detected and renamed:\n";
  3337.  
  3338. for(int i = 0; i < duplicateTilesetsToRename.size(); ++i) {
  3339. string currentPath = tilesetPaths[1];
  3340. endPathWithSlash(currentPath);
  3341.  
  3342. string oldFile = currentPath + duplicateTilesetsToRename[i];
  3343. string newFile = currentPath + duplicateTilesetsToRename[i];
  3344. newFile = newFile + "_custom";
  3345.  
  3346. char szBuf[8096]="";
  3347. int result = rename(oldFile.c_str(),newFile.c_str());
  3348. if(result != 0) {
  3349. char *errmsg = strerror(errno);
  3350. snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
  3351. throw megaglest_runtime_error(szBuf);
  3352. }
  3353. else {
  3354. snprintf(szBuf,8096,"tileset [%s] in [%s]\nwas renamed to [%s]",duplicateTilesetsToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
  3355.  
  3356. string tilesetName = extractFileFromDirectoryPath(oldFile);
  3357. oldFile = newFile + "/" + tilesetName + ".xml";
  3358. newFile = newFile + "/" + tilesetName + "_custom.xml";
  3359.  
  3360. //printf("\n\n\n###### RENAME [%s] to [%s]\n\n",oldFile.c_str(),newFile.c_str());
  3361. rename(oldFile.c_str(),newFile.c_str());
  3362. }
  3363. errorMsg += szBuf;
  3364. }
  3365. duplicateWarnings += errorMsg;
  3366. }
  3367. }
  3368.  
  3369. {
  3370. vector<string> techPaths = config.getPathListForType(ptTechs);
  3371. vector<string> techTrees;
  3372. findDirs(techPaths, techTrees, false, true);
  3373. if(techTrees.empty()) {
  3374. throw megaglest_runtime_error("No tech-trees were found!");
  3375. }
  3376.  
  3377. vector<string> duplicateTechtreesToRename;
  3378. for(int i = 0; i < techTrees.size(); ++i) {
  3379. string techtree1 = techTrees[i];
  3380. for(int j = 0; j < techTrees.size(); ++j) {
  3381. if(i != j) {
  3382. string techtree2 = techTrees[j];
  3383. if(techtree1 == techtree2) {
  3384. if(std::find(duplicateTechtreesToRename.begin(),duplicateTechtreesToRename.end(),techtree1) == duplicateTechtreesToRename.end()) {
  3385. duplicateTechtreesToRename.push_back(techtree1);
  3386. }
  3387. }
  3388. }
  3389. }
  3390. }
  3391. if(duplicateTechtreesToRename.empty() == false) {
  3392. string errorMsg = "Warning duplicate techtrees were detected and renamed:\n";
  3393.  
  3394. for(int i = 0; i < duplicateTechtreesToRename.size(); ++i) {
  3395. string currentPath = techPaths[1];
  3396. endPathWithSlash(currentPath);
  3397.  
  3398. string oldFile = currentPath + duplicateTechtreesToRename[i];
  3399. string newFile = currentPath + duplicateTechtreesToRename[i];
  3400. newFile = newFile + "_custom";
  3401.  
  3402. char szBuf[8096]="";
  3403. int result = rename(oldFile.c_str(),newFile.c_str());
  3404. if(result != 0) {
  3405. char *errmsg = strerror(errno);
  3406. snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str());
  3407. throw megaglest_runtime_error(szBuf);
  3408. }
  3409. else {
  3410. snprintf(szBuf,8096,"techtree [%s] in [%s]\nwas renamed to [%s]",duplicateTechtreesToRename[i].c_str(),oldFile.c_str(),newFile.c_str());
  3411.  
  3412. string tilesetName = extractFileFromDirectoryPath(oldFile);
  3413. oldFile = newFile + "/" + tilesetName + ".xml";
  3414. newFile = newFile + "/" + tilesetName + "_custom.xml";
  3415.  
  3416. //printf("\n\n\n###### RENAME [%s] to [%s]\n\n",oldFile.c_str(),newFile.c_str());
  3417. rename(oldFile.c_str(),newFile.c_str());
  3418. }
  3419. errorMsg += szBuf;
  3420. }
  3421. duplicateWarnings += errorMsg;
  3422. }
  3423. }
  3424.  
  3425. if(duplicateWarnings != "") {
  3426. if(mainProgram) {
  3427. mainProgram->getState()->setForceMouseRender(true);
  3428. }
  3429. ExceptionHandler::DisplayMessage(duplicateWarnings.c_str(), false);
  3430. }
  3431. }
  3432.  
  3433. int glestMain(int argc, char** argv) {
  3434. #ifdef SL_LEAK_DUMP
  3435. //AllocInfo::set_application_binary(executable_path(argv[0],true));
  3436. string &app = AllocInfo::get_application_binary();
  3437. app = executable_path(argv[0],true);
  3438. //want_full_leak_stacktrace = true;
  3439. //want_full_leak_stacktrace_line_numbers = true;
  3440.  
  3441. #endif
  3442.  
  3443. // printf("START ALLOC char 200\n");
  3444. //char *ptr = new char[200];
  3445. // printf("END ALLOC char 200\n");
  3446. // return -1;
  3447. SystemFlags::VERBOSE_MODE_ENABLED = false;
  3448. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == true) {
  3449. SystemFlags::VERBOSE_MODE_ENABLED = true;
  3450. Thread::setEnableVerboseMode(true);
  3451. }
  3452. // DEbug testing threads
  3453. //Thread::setEnableVerboseMode(true);
  3454.  
  3455. if( hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
  3456. //isMasterServerModeEnabled = true;
  3457. //Window::setMasterserverMode(isMasterServerModeEnabled);
  3458. GlobalStaticFlags::setIsNonGraphicalModeEnabled(true);
  3459.  
  3460. int foundParamIndIndex = -1;
  3461. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) + string("="),&foundParamIndIndex);
  3462. if(foundParamIndIndex < 0) {
  3463. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]),&foundParamIndIndex);
  3464. }
  3465. string paramValue = argv[foundParamIndIndex];
  3466. vector<string> paramPartTokens;
  3467. Tokenize(paramValue,paramPartTokens,"=");
  3468. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  3469. string headless_command_list = paramPartTokens[1];
  3470.  
  3471. vector<string> paramHeadlessCommandList;
  3472. Tokenize(headless_command_list,paramHeadlessCommandList,",");
  3473.  
  3474. for(unsigned int i = 0; i < paramHeadlessCommandList.size(); ++i) {
  3475. string headless_command = paramHeadlessCommandList[i];
  3476. if(headless_command == "exit") {
  3477. printf("Forcing quit after game has completed [%s]\n",headless_command.c_str());
  3478. Program::setWantShutdownApplicationAfterGame(true);
  3479. }
  3480. else if(headless_command == "vps") {
  3481. printf("Disabled reading from console [%s]\n",headless_command.c_str());
  3482. disableheadless_console = true;
  3483. }
  3484. else if(headless_command == "lan") {
  3485. printf("Forcing local LAN mode [%s]\n",headless_command.c_str());
  3486. GlobalStaticFlags::setFlag(gsft_lan_mode);
  3487. }
  3488. }
  3489. }
  3490. }
  3491.  
  3492. PlatformExceptionHandler::application_binary= executable_path(argv[0],true);
  3493. mg_app_name = GameConstants::application_name;
  3494. mailStringSupport = mailString;
  3495. SystemFlags::ENABLE_THREADED_LOGGING = false;
  3496. disableBacktrace = false;
  3497. bool foundInvalidArgs = false;
  3498. preCacheThread=NULL;
  3499.  
  3500. Properties::setApplicationPath(executable_path(argv[0]));
  3501. Properties::setGameVersion(glestVersionString);
  3502.  
  3503. ServerSocket::setMaxPlayerCount(GameConstants::maxPlayers);
  3504.  
  3505. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true) {
  3506. disableBacktrace = true;
  3507. }
  3508. PlatformExceptionHandler::disableBacktrace= disableBacktrace;
  3509.  
  3510. #if defined(CUSTOM_DATA_INSTALL_PATH)
  3511. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n",formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)).c_str());
  3512. #endif
  3513.  
  3514. const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]);
  3515. for(int idx = 1; idx < argc; ++idx) {
  3516. if( hasCommandArgument(knownArgCount, (char **)&GAME_ARGS[0], argv[idx], NULL, 0, true) == false) {
  3517. foundInvalidArgs = true;
  3518. printf("\nInvalid argument: %s",argv[idx]);
  3519. }
  3520. }
  3521.  
  3522. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_HELP]) == true ||
  3523. foundInvalidArgs == true) {
  3524.  
  3525. printParameterHelp(argv[0],foundInvalidArgs);
  3526. return 2;
  3527. }
  3528.  
  3529. #ifdef WIN32
  3530. SocketManager winSockManager;
  3531. #endif
  3532.  
  3533. bool haveSpecialOutputCommandLineOption = false;
  3534.  
  3535. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true ||
  3536. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true ||
  3537. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true ||
  3538. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true ||
  3539. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true ||
  3540. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true ||
  3541. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true ||
  3542. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true ||
  3543. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true ||
  3544. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true ||
  3545. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true ||
  3546. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true ||
  3547. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true ||
  3548. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true ||
  3549. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true ||
  3550. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true ||
  3551. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) {
  3552. haveSpecialOutputCommandLineOption = true;
  3553. }
  3554.  
  3555. if( haveSpecialOutputCommandLineOption == false ||
  3556. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true) {
  3557. printf("%s %s",extractFileFromDirectoryPath(argv[0]).c_str(),getNetworkPlatformFreeVersionString().c_str());
  3558. printf("\nCompiled using: %s on: %s platform: %s endianness: %s",getCompilerNameString().c_str(),getCompileDateTime().c_str(),getPlatformNameString().c_str(),(Shared::PlatformByteOrder::isBigEndian() == true ? "big" : "little"));
  3559.  
  3560. // printf("\n\nData type sizes int8 = " MG_SIZE_T_SPECIFIER " int16 = " MG_SIZE_T_SPECIFIER " int32 = " MG_SIZE_T_SPECIFIER " int64 = " MG_SIZE_T_SPECIFIER "\n\n",sizeof(int8),sizeof(int16),sizeof(int32),sizeof(int64));
  3561. //
  3562. // Config::getInstance().setBool("DebugNetworkPackets",true,true);
  3563. // NetworkMessageIntro data(424336, "mg_version_x","player_x", 3, nmgstOk,444444, 555555, "english");
  3564. // unsigned char *buf = data.packMessage();
  3565. // printf("\nSend packet size = %u\n%s\n",data.getPackedSize(),data.toString().c_str());
  3566. // data.dump_packet("Send data", buf, data.getPackedSize());
  3567. // //delete [] buf;
  3568. //
  3569. // NetworkMessageIntro data2;
  3570. // data2.unpackMessage(buf);
  3571. // printf("\nReceive packet size = %u\n%s\n",data2.getPackedSize(),data2.toString().c_str());
  3572. // data2.dump_packet("nReceive data", buf, data2.getPackedSize());
  3573. // delete [] buf;
  3574.  
  3575. // SwitchSetupRequest data("factionname", 3,-1,2,"softcoder",10, 11,"eng");
  3576. //
  3577. // unsigned char *buf = data.packMessage();
  3578. // printf("\nSend packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags());
  3579. // //delete [] buf;
  3580. //
  3581. // data.unpackMessage(buf);
  3582. // printf("\nGot packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags());
  3583. // delete [] buf;
  3584.  
  3585. // int8 a = 1;
  3586. // uint8 b = 2;
  3587. // int16 c = 3;
  3588. // uint16 d = 4;
  3589. // int32 e = 5;
  3590. // uint32 f = 6;
  3591. //
  3592. // printf("\nPack test #1: [%d][%u][%d][%u][%d][%u]\n,",a,b,c,d,e,f);
  3593. //
  3594. // unsigned char *buf = new unsigned char[100];
  3595. // unsigned int packedsize = pack(buf, "cChHlL",
  3596. // a,
  3597. // b,
  3598. // c,
  3599. // d,
  3600. // e,
  3601. // f);
  3602. //
  3603. // printf("Pack test #2: [%u][%s]\n,",packedsize,buf);
  3604. //
  3605. // int8 a1 = 0;
  3606. // uint8 b1 = 0;
  3607. // int16 c1 = 0;
  3608. // uint16 d1 = 0;
  3609. // int32 e1 = 0;
  3610. // uint32 f1 = 0;
  3611. //
  3612. // unpack(buf, "cChHlL",
  3613. // &a1,
  3614. // &b1,
  3615. // &c1,
  3616. // &d1,
  3617. // &e1,
  3618. // &f1);
  3619. //
  3620. // printf("UnPack test #3: [%d][%u][%d][%u][%d][%u]\n,",a1,b1,c1,d1,e1,f1);
  3621.  
  3622. if(SystemFlags::VERBOSE_MODE_ENABLED == true) {
  3623. int8 testVar = 111;
  3624. printf("\nEndian value = %d",testVar);
  3625. testVar = Shared::PlatformByteOrder::toCommonEndian(testVar);
  3626. printf("\nEndian to common value = %d",testVar);
  3627. testVar = Shared::PlatformByteOrder::fromCommonEndian(testVar);
  3628. printf("\nEndian from common value = %d",testVar);
  3629.  
  3630. printf("\nint8 sizeof = " MG_SIZE_T_SPECIFIER "",sizeof(int8));
  3631. printf("\nSwitchSetupRequest sizeof = " MG_SIZE_T_SPECIFIER "",SwitchSetupRequest().getDataSize());
  3632. }
  3633.  
  3634. printf("\nSVN: [%s]",getSVNRevisionString().c_str());
  3635.  
  3636. #ifdef USE_STREFLOP
  3637. //# define STREFLOP_NO_DENORMALS
  3638. // streflop_init<streflop::Simple>();
  3639.  
  3640. #if defined(STREFLOP_SSE)
  3641. const char *instruction_set = "[SSE]";
  3642. #elif defined(STREFLOP_X87)
  3643. const char *instruction_set = "[X87]";
  3644. #elif defined(STREFLOP_SOFT)
  3645. const char *instruction_set = "[SOFTFLOAT]";
  3646. #else
  3647. const char *instruction_set = "[none]";
  3648. #endif
  3649.  
  3650. #if defined(STREFLOP_NO_DENORMALS)
  3651. const char *denormals = "[no-denormals]";
  3652. #else
  3653. const char *denormals = "[denormals]";
  3654. #endif
  3655.  
  3656. printf(" - using STREFLOP %s - %s\n",instruction_set,denormals);
  3657. #endif
  3658. }
  3659.  
  3660. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true ||
  3661. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true ||
  3662. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true ||
  3663. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true ||
  3664. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true ||
  3665. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true ||
  3666. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true ||
  3667. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true ||
  3668. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true ||
  3669. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true ||
  3670. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true ||
  3671. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true ||
  3672. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true ||
  3673. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true ||
  3674. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true ||
  3675. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true ||
  3676. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) {
  3677. VideoPlayer::setDisabled(true);
  3678. }
  3679.  
  3680. //throw megaglest_runtime_error("Test!");
  3681.  
  3682. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true) {
  3683. SDL_version ver;
  3684.  
  3685. // Prints the compile time version
  3686. SDL_VERSION(&ver);
  3687. print_SDL_version("SDL compile-time version", &ver);
  3688.  
  3689. // Prints the run-time version
  3690. ver = *SDL_Linked_Version();
  3691. print_SDL_version("SDL runtime version", &ver);
  3692. //const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo();
  3693. //printf("Video card Memory: %u\n",vidInfo->video_mem);
  3694. }
  3695.  
  3696. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true) {
  3697. printf("LUA version: %s\n", LUA_RELEASE);
  3698. }
  3699.  
  3700. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true) {
  3701. curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW);
  3702. printf("CURL version: %s [%s] SSL enabled: %d\n", curlVersion->version,(curlVersion->ssl_version != NULL ? curlVersion->ssl_version : ""),((curlVersion->features & CURL_VERSION_SSL) == CURL_VERSION_SSL ? true : false));
  3703. if(curlVersion->protocols != NULL && curlVersion->protocols[0] != NULL) {
  3704. printf("protocols: ");
  3705. for(unsigned int i = 0; curlVersion->protocols != NULL && curlVersion->protocols[i] != NULL; ++i) {
  3706. printf("%s ", curlVersion->protocols[i]);
  3707. if(i > 0 && i % 10 == 0) {
  3708. printf("\n ");
  3709. }
  3710. }
  3711. printf("\n");
  3712. }
  3713. }
  3714.  
  3715. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) {
  3716. printf("XERCES version: %s\n", XERCES_FULLVERSIONDOT);
  3717. }
  3718.  
  3719. if( (hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true ||
  3720. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true ||
  3721. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true ||
  3722. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true ||
  3723. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) &&
  3724. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false &&
  3725. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == false &&
  3726. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == false &&
  3727. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == false &&
  3728. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == false &&
  3729. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == false &&
  3730. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == false &&
  3731. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == false &&
  3732. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == false &&
  3733. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == false &&
  3734. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == false) {
  3735. return 0;
  3736. }
  3737.  
  3738. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD])) == true) {
  3739.  
  3740. int foundParamIndIndex = -1;
  3741. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]) + string("="),&foundParamIndIndex);
  3742. if(foundParamIndIndex < 0) {
  3743. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]),&foundParamIndIndex);
  3744. }
  3745. string scenarioName = argv[foundParamIndIndex];
  3746. vector<string> paramPartTokens;
  3747. Tokenize(scenarioName,paramPartTokens,"=");
  3748. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  3749. string autoloadModName = paramPartTokens[1];
  3750. if(Properties::applyTagsToValue(autoloadModName) == true) {
  3751. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s]\n",Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName.c_str());
  3752. }
  3753.  
  3754. Config::setCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName);
  3755.  
  3756. printf("Setting mod active [%s]\n",autoloadModName.c_str());
  3757. }
  3758. else {
  3759. printf("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3760. printParameterHelp(argv[0],foundInvalidArgs);
  3761. return 1;
  3762. }
  3763. }
  3764.  
  3765. SystemFlags::init(haveSpecialOutputCommandLineOption);
  3766. //SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true;
  3767. //SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true;
  3768.  
  3769. MainWindow *mainWindow= NULL;
  3770. Program *program= NULL;
  3771. ExceptionHandler exceptionHandler;
  3772. exceptionHandler.install( getCrashDumpFileName() );
  3773.  
  3774. int shutdownFadeSoundMilliseconds = 1000;
  3775. Chrono chronoshutdownFadeSound;
  3776. SimpleTaskThread *soundThreadManager = NULL;
  3777.  
  3778. try {
  3779. // Setup paths to game items (like data, logs, ini etc)
  3780. int setupResult = setupGameItemPaths(argc, argv, NULL);
  3781. if(setupResult != 0) {
  3782. return setupResult;
  3783. }
  3784.  
  3785. // Attempt to read ini files
  3786. Config &config = Config::getInstance();
  3787. setupGameItemPaths(argc, argv, &config);
  3788.  
  3789. if(config.getString("PlayerId","") == "") {
  3790. char uuid_str[38];
  3791. get_uuid_string(uuid_str,sizeof(uuid_str));
  3792.  
  3793. config.setString("PlayerId",uuid_str);
  3794. config.save();
  3795. }
  3796. //printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str());
  3797.  
  3798. if(config.getBool("DisableLuaSandbox","false") == true) {
  3799. LuaScript::setDisableSandbox(true);
  3800. }
  3801.  
  3802. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKETS]) == true) {
  3803. printf("*NOTE: debugging network packets.\n");
  3804. config.setBool("DebugNetworkPackets",true,true);
  3805. }
  3806.  
  3807. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_ENABLE_NEW_PROTOCOL]) == true) {
  3808. printf("*NOTE: enabling new newtork protocol.\n");
  3809. NetworkMessage::useOldProtocol = false;
  3810. }
  3811.  
  3812. Socket::setBroadCastPort(config.getInt("BroadcastPort",intToStr(Socket::getBroadCastPort()).c_str()));
  3813.  
  3814. Socket::disableNagle = config.getBool("DisableNagle","false");
  3815. if(Socket::disableNagle) {
  3816. printf("*WARNING users wants to disable the socket nagle algorithm.\n");
  3817. }
  3818. Socket::DEFAULT_SOCKET_SENDBUF_SIZE = config.getInt("DefaultSocketSendBufferSize",intToStr(Socket::DEFAULT_SOCKET_SENDBUF_SIZE).c_str());
  3819. if(Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) {
  3820. printf("*WARNING users wants to set default socket send buffer size to: %d\n",Socket::DEFAULT_SOCKET_SENDBUF_SIZE);
  3821. }
  3822. Socket::DEFAULT_SOCKET_RECVBUF_SIZE = config.getInt("DefaultSocketReceiveBufferSize",intToStr(Socket::DEFAULT_SOCKET_RECVBUF_SIZE).c_str());
  3823. if(Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) {
  3824. printf("*WARNING users wants to set default socket receive buffer size to: %d\n",Socket::DEFAULT_SOCKET_RECVBUF_SIZE);
  3825. }
  3826.  
  3827. shutdownFadeSoundMilliseconds = config.getInt("ShutdownFadeSoundMilliseconds",intToStr(shutdownFadeSoundMilliseconds).c_str());
  3828.  
  3829. string userData = config.getString("UserData_Root","");
  3830. if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  3831. userData = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey);
  3832. }
  3833. if(userData != "") {
  3834. endPathWithSlash(userData);
  3835. }
  3836.  
  3837. if(userData != "") {
  3838. if(isdir(userData.c_str()) == false) {
  3839. createDirectoryPaths(userData);
  3840. }
  3841. }
  3842. string crcCachePath = userData + "cache/";
  3843. if(isdir(crcCachePath.c_str()) == false) {
  3844. createDirectoryPaths(crcCachePath);
  3845. }
  3846. setCRCCacheFilePath(crcCachePath);
  3847.  
  3848. string savedGamePath = userData + "saved/";
  3849. if(isdir(savedGamePath.c_str()) == false) {
  3850. createDirectoryPaths(savedGamePath);
  3851. //printf("savedGamePath = [%s]\n",savedGamePath.c_str());
  3852. }
  3853.  
  3854. string tempDataPath = userData + "temp/";
  3855. if(isdir(tempDataPath.c_str()) == true) {
  3856. removeFolder(tempDataPath);
  3857. }
  3858. createDirectoryPaths(tempDataPath);
  3859.  
  3860. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_PORTS]) == true) {
  3861. int foundParamIndIndex = -1;
  3862. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]) + string("="),&foundParamIndIndex);
  3863. if(foundParamIndIndex < 0) {
  3864. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]),&foundParamIndIndex);
  3865. }
  3866. string paramValue = argv[foundParamIndIndex];
  3867. vector<string> paramPartTokens;
  3868. Tokenize(paramValue,paramPartTokens,"=");
  3869. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  3870. string portsToUse = paramPartTokens[1];
  3871.  
  3872. vector<string> paramPartPortsTokens;
  3873. Tokenize(portsToUse,paramPartPortsTokens,",");
  3874. if(paramPartPortsTokens.size() >= 2 && paramPartPortsTokens[1].length() > 0) {
  3875. int internalPort = strToInt(paramPartPortsTokens[0]);
  3876. int externalPort = strToInt(paramPartPortsTokens[1]);
  3877.  
  3878. printf("Forcing internal port# %d, external port# %d\n",internalPort,externalPort);
  3879.  
  3880. config.setInt("PortServer",internalPort,true);
  3881. config.setInt("PortExternal",externalPort,true);
  3882. config.setInt("FTPServerPort",internalPort+1,true);
  3883.  
  3884. if(paramPartPortsTokens.size() >= 3 && paramPartPortsTokens[2].length() > 0) {
  3885. int statusPort = strToInt(paramPartPortsTokens[2]);
  3886.  
  3887. printf("Forcing status port# %d\n",statusPort);
  3888.  
  3889. config.setInt("ServerAdminPort",statusPort,true);
  3890. }
  3891. }
  3892. else {
  3893. printf("\nInvalid ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3894. //printParameterHelp(argv[0],false);
  3895. return 1;
  3896. }
  3897. }
  3898. else {
  3899. printf("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3900. //printParameterHelp(argv[0],false);
  3901. return 1;
  3902. }
  3903. }
  3904.  
  3905. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) == true) {
  3906. Ip ip("localhost");
  3907. int port = Config::getInstance().getInt("ServerAdminPort", intToStr(GameConstants::serverAdminPort).c_str());
  3908. ClientSocket clientSocket;
  3909. clientSocket.setBlock(false);
  3910. clientSocket.connect(ip, port);
  3911. if(clientSocket.isConnected() == true) {
  3912. clientSocket.setBlock(true);
  3913.  
  3914. char szBuf[8096]="";
  3915. clientSocket.receive(&szBuf[0],8095,false);
  3916. std::cout << szBuf << std::endl;
  3917. }
  3918. else {
  3919. std::cout << "Could not connect (possibly no clients connected) to host: " << ip.getString() << " port: " << port << std::endl;
  3920. }
  3921.  
  3922. return 0;
  3923. }
  3924.  
  3925. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_SOUND]) == true ||
  3926. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
  3927. config.setString("FactorySound","None",true);
  3928. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
  3929. //Logger::getInstance().setMasterserverMode(true);
  3930. //Model::setMasterserverMode(true);
  3931. //Shared::Sound::Sound::setMasterserverMode(true);
  3932. }
  3933. }
  3934.  
  3935. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]) == true ||
  3936. config.getBool("CheckGlCaps") == false) {
  3937. printf("**WARNING** disabling opengl capability checking...\n");
  3938. config.setBool("CheckGlCaps",false,true);
  3939. }
  3940.  
  3941. bool enableATIHacks = config.getBool("EnableATIHacks","false");
  3942. if(enableATIHacks == true) {
  3943. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Enabling ATI video card hacks\n");
  3944. TextureGl::setEnableATIHacks(enableATIHacks);
  3945. }
  3946.  
  3947. if(config.getBool("ForceFTGLFonts","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FORCE_FTGLFONTS]) == true) {
  3948. Shared::Graphics::Font::forceFTGLFonts = true;
  3949. //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Forcing Legacy Fonts Enabled\n");
  3950. printf("**WARNING** Forcing use of FTGL Fonts\n");
  3951. }
  3952. else {
  3953. Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str());
  3954. }
  3955.  
  3956. if(config.getBool("EnableLegacyFonts","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) == true) {
  3957. Shared::Graphics::Font::forceLegacyFonts = true;
  3958. Renderer::renderText3DEnabled = false;
  3959. //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Forcing Legacy Fonts Enabled\n");
  3960. printf("**WARNING** Forcing Legacy Fonts Enabled\n");
  3961. }
  3962. else {
  3963. Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str());
  3964. }
  3965.  
  3966. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true) {
  3967. int foundParamIndIndex = -1;
  3968. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]) + string("="),&foundParamIndIndex);
  3969. if(foundParamIndIndex < 0) {
  3970. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]),&foundParamIndIndex);
  3971. }
  3972. string paramValue = argv[foundParamIndIndex];
  3973. vector<string> paramPartTokens;
  3974. Tokenize(paramValue,paramPartTokens,"=");
  3975. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  3976. string settings = paramPartTokens[1];
  3977. printf("Forcing resolution [%s]\n",settings.c_str());
  3978.  
  3979. paramPartTokens.clear();
  3980. Tokenize(settings,paramPartTokens,"x");
  3981. if(paramPartTokens.size() >= 2) {
  3982. int newScreenWidth = strToInt(paramPartTokens[0]);
  3983. config.setInt("ScreenWidth",newScreenWidth,true);
  3984.  
  3985. int newScreenHeight = strToInt(paramPartTokens[1]);
  3986. config.setInt("ScreenHeight",newScreenHeight,true);
  3987. }
  3988. else {
  3989. printf("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3990. //printParameterHelp(argv[0],false);
  3991. return 1;
  3992. }
  3993. }
  3994. else {
  3995. printf("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  3996. //printParameterHelp(argv[0],false);
  3997. return 1;
  3998. }
  3999. }
  4000.  
  4001. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_COLORBITS]) == true) {
  4002. int foundParamIndIndex = -1;
  4003. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]) + string("="),&foundParamIndIndex);
  4004. if(foundParamIndIndex < 0) {
  4005. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]),&foundParamIndIndex);
  4006. }
  4007. string paramValue = argv[foundParamIndIndex];
  4008. vector<string> paramPartTokens;
  4009. Tokenize(paramValue,paramPartTokens,"=");
  4010. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4011. string settings = paramPartTokens[1];
  4012. printf("Forcing colorbits [%s]\n",settings.c_str());
  4013.  
  4014. int newColorBits = strToInt(settings);
  4015. config.setInt("ColorBits",newColorBits,true);
  4016. }
  4017. else {
  4018. printf("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4019. //printParameterHelp(argv[0],false);
  4020. return 1;
  4021. }
  4022. }
  4023.  
  4024. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) == true) {
  4025. int foundParamIndIndex = -1;
  4026. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + string("="),&foundParamIndIndex);
  4027. if(foundParamIndIndex < 0) {
  4028. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]),&foundParamIndIndex);
  4029. }
  4030. string paramValue = argv[foundParamIndIndex];
  4031. vector<string> paramPartTokens;
  4032. Tokenize(paramValue,paramPartTokens,"=");
  4033. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4034. string settings = paramPartTokens[1];
  4035. printf("Forcing depthbits [%s]\n",settings.c_str());
  4036.  
  4037. int newDepthBits = strToInt(settings);
  4038. config.setInt("DepthBits",newDepthBits,true);
  4039. }
  4040. else {
  4041. printf("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4042. //printParameterHelp(argv[0],false);
  4043. return 1;
  4044. }
  4045. }
  4046.  
  4047. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true) {
  4048. int foundParamIndIndex = -1;
  4049. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) + string("="),&foundParamIndIndex);
  4050. if(foundParamIndIndex < 0) {
  4051. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]),&foundParamIndIndex);
  4052. }
  4053. string paramValue = argv[foundParamIndIndex];
  4054. vector<string> paramPartTokens;
  4055. Tokenize(paramValue,paramPartTokens,"=");
  4056. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4057. string settings = paramPartTokens[1];
  4058. printf("Forcing fullscreen [%s]\n",settings.c_str());
  4059.  
  4060. bool newFullScreenMode = strToBool(settings);
  4061. config.setBool("Windowed",!newFullScreenMode,true);
  4062. }
  4063. else {
  4064. printf("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4065. //printParameterHelp(argv[0],false);
  4066. return 1;
  4067. }
  4068. }
  4069.  
  4070. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SET_GAMMA]) == true) {
  4071. int foundParamIndIndex = -1;
  4072. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]) + string("="),&foundParamIndIndex);
  4073. if(foundParamIndIndex < 0) {
  4074. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]),&foundParamIndIndex);
  4075. }
  4076. string paramValue = argv[foundParamIndIndex];
  4077. vector<string> paramPartTokens;
  4078. Tokenize(paramValue,paramPartTokens,"=");
  4079. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4080. string settings = paramPartTokens[1];
  4081. printf("Forcing gamma [%s]\n",settings.c_str());
  4082.  
  4083. float newGammaValue = strToFloat(settings);
  4084. config.setFloat("GammaValue",newGammaValue,true);
  4085. }
  4086. else {
  4087. printf("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4088. //printParameterHelp(argv[0],false);
  4089. return 1;
  4090. }
  4091. }
  4092.  
  4093.  
  4094. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]) == true) {
  4095. VideoPlayer::setDisabled(true);
  4096. }
  4097. else if(config.getBool("EnableVideos","true") == false) {
  4098. VideoPlayer::setDisabled(true);
  4099. }
  4100.  
  4101. // Set some statics based on ini entries
  4102. SystemFlags::ENABLE_THREADED_LOGGING = config.getBool("ThreadedLogging","true");
  4103. FontGl::setDefault_fontType(config.getString("DefaultFont",FontGl::getDefault_fontType().c_str()));
  4104. UPNP_Tools::isUPNP = !config.getBool("DisableUPNP","false");
  4105. Texture::useTextureCompression = config.getBool("EnableTextureCompression","false");
  4106.  
  4107. // 256 for English
  4108. // 30000 for Chinese
  4109. Shared::Graphics::Font::charCount = config.getInt("FONT_CHARCOUNT",intToStr(Shared::Graphics::Font::charCount).c_str());
  4110. Shared::Graphics::Font::fontTypeName = config.getString("FONT_TYPENAME",Shared::Graphics::Font::fontTypeName.c_str());
  4111. Shared::Graphics::Font::fontIsMultibyte = config.getBool("FONT_MULTIBYTE",intToStr(Shared::Graphics::Font::fontIsMultibyte).c_str());
  4112. Shared::Graphics::Font::fontIsRightToLeft = config.getBool("FONT_RIGHTTOLEFT",intToStr(Shared::Graphics::Font::fontIsRightToLeft).c_str());
  4113. Shared::Graphics::Font::baseSize = config.getInt("FONT_BASE_SIZE",intToStr(Shared::Graphics::Font::baseSize).c_str());
  4114. Shared::Graphics::Font::scaleFontValue = config.getFloat("FONT_SCALE_SIZE",floatToStr(Shared::Graphics::Font::scaleFontValue).c_str());
  4115. Shared::Graphics::Font::scaleFontValueCenterHFactor = config.getFloat("FONT_SCALE_CENTERH_FACTOR",floatToStr(Shared::Graphics::Font::scaleFontValueCenterHFactor).c_str());
  4116. Shared::Graphics::Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",Shared::Graphics::Font::langHeightText.c_str());
  4117.  
  4118. // Example values:
  4119. // DEFAULT_CHARSET (English) = 1
  4120. // GB2312_CHARSET (Chinese) = 134
  4121. Shared::Platform::charSet = config.getInt("FONT_CHARSET",intToStr(Shared::Platform::charSet).c_str());
  4122. if(config.getBool("No2DMouseRendering","false") == false) {
  4123. showCursor(false);
  4124. }
  4125. if(config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str()) >= 0) {
  4126. SystemFlags::DEFAULT_HTTP_TIMEOUT = config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str());
  4127. }
  4128.  
  4129. bool allowAltEnterFullscreenToggle = config.getBool("AllowAltEnterFullscreenToggle",boolToStr(Shared::Platform::Window::getAllowAltEnterFullscreenToggle()).c_str());
  4130. Shared::Platform::Window::setAllowAltEnterFullscreenToggle(allowAltEnterFullscreenToggle);
  4131.  
  4132. if(config.getBool("noTeamColors","false") == true) {
  4133. MeshCallbackTeamColor::noTeamColors = true;
  4134. }
  4135.  
  4136. // Setup debug logging etc
  4137. setupLogging(config, haveSpecialOutputCommandLineOption);
  4138.  
  4139. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,Shared::Graphics::Font::charCount,Shared::Graphics::Font::fontTypeName.c_str(),Shared::Platform::charSet,Shared::Graphics::Font::fontIsMultibyte, Shared::Graphics::Font::fontIsRightToLeft);
  4140.  
  4141. NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
  4142. MenuStateMasterserver::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
  4143.  
  4144. #ifdef USE_STREFLOP
  4145. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP enabled.\n",getNetworkVersionString().c_str());
  4146. #else
  4147. SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP NOT enabled.\n",getNetworkVersionString().c_str());
  4148. #endif
  4149.  
  4150. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  4151. SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"START\n");
  4152. SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"START\n");
  4153.  
  4154. // Setup hotkeys from key ini files
  4155. Config &configKeys = Config::getInstance(
  4156. std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys),
  4157. std::pair<string,string>(Config::glestkeys_ini_filename,Config::glestuserkeys_ini_filename),
  4158. std::pair<bool,bool>(true,false));
  4159.  
  4160. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  4161.  
  4162. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) {
  4163. ShowINISettings(argc,argv,config,configKeys);
  4164. return 0;
  4165. }
  4166.  
  4167. //setVBOSupported(false);
  4168. // Explicitly disable VBO's
  4169. if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) {
  4170. setVBOSupported(false);
  4171. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Disabling VBO's\n");
  4172. }
  4173.  
  4174. if(config.getBool("EnableVSynch","false") == true) {
  4175. Shared::Platform::Window::setTryVSynch(true);
  4176. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**ENABLED OPENGL VSYNCH**\n");
  4177. }
  4178.  
  4179. //float pingTime = Socket::getAveragePingMS("soft-haus.com");
  4180. //printf("Ping time = %f\n",pingTime);
  4181.  
  4182. // Load the language strings
  4183. Lang &lang= Lang::getInstance();
  4184. string language = config.getString("Lang");
  4185. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_LANGUAGE]) == true) {
  4186. int foundParamIndIndex = -1;
  4187. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + string("="),&foundParamIndIndex);
  4188. if(foundParamIndIndex < 0) {
  4189. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]),&foundParamIndIndex);
  4190. }
  4191. string paramValue = argv[foundParamIndIndex];
  4192. vector<string> paramPartTokens;
  4193. Tokenize(paramValue,paramPartTokens,"=");
  4194. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4195. language = paramPartTokens[1];
  4196. printf("Forcing language [%s]\n",language.c_str());
  4197. }
  4198. else {
  4199. printf("\nInvalid missing language specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4200. //printParameterHelp(argv[0],false);
  4201. return 1;
  4202. }
  4203. }
  4204. else {
  4205.  
  4206. #ifdef _WIN32
  4207. int localeBufferSize = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, NULL, 0);
  4208. wchar_t *sysLocale = new wchar_t[localeBufferSize];
  4209. GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, sysLocale,localeBufferSize);
  4210.  
  4211. //String langValue(sysLocale);
  4212. //const char *lang_locale = langValue.c_str();
  4213. char langValue[1024]="";
  4214. wcstombs(langValue,sysLocale, 1023);
  4215. const char *lang_locale = &langValue[0];
  4216.  
  4217. delete [] sysLocale;
  4218. #else
  4219. const char *lang_locale = setlocale(LC_ALL,"");
  4220. #endif
  4221.  
  4222. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Locale is: [%s]\n", lang_locale);
  4223.  
  4224. if(lang_locale != NULL && strlen(lang_locale) >= 2) {
  4225. if(config.getBool("AutoLocaleLanguageDetect","true") == true) {
  4226. language = lang_locale;
  4227. language = language.substr(0,2);
  4228. printf("Auto setting language [%s]\n",language.c_str());
  4229.  
  4230. config.setString("AutoLocaleLanguageDetect","false");
  4231. config.save();
  4232. }
  4233. }
  4234. }
  4235.  
  4236. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true ||
  4237. Config::getInstance().getBool("AutoTest","false") == true) {
  4238. printf("Running in auto test mode\n");
  4239. }
  4240. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true) {
  4241. Config::getInstance().setBool("AutoTest","true",true);
  4242.  
  4243. int foundParamIndIndex = -1;
  4244. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST]) + string("="),&foundParamIndIndex);
  4245. if(foundParamIndIndex < 0) {
  4246. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST]),&foundParamIndIndex);
  4247. }
  4248. string paramValue = argv[foundParamIndIndex];
  4249. vector<string> paramPartTokens;
  4250. Tokenize(paramValue,paramPartTokens,"=");
  4251. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4252. vector<string> paramPartTokens2;
  4253. Tokenize(paramPartTokens[1],paramPartTokens2,",");
  4254. if(paramPartTokens2.empty() == false && paramPartTokens2[0].length() > 0) {
  4255. string newMaxSeconds = paramPartTokens2[0];
  4256. time_t newTimeMaxSeconds = strToInt(newMaxSeconds);
  4257. AutoTest::setMaxGameTime(newTimeMaxSeconds);
  4258. //printf("#1 Forcing font [%s] paramPartTokens.size() = %d, paramValue [%s]\n",newfont.c_str(),paramPartTokens.size(),paramValue.c_str());
  4259. printf("Forcing maximum game time to [%ld] seconds (%.2f minutes)\n",newTimeMaxSeconds,((double)newTimeMaxSeconds / 60.0));
  4260. }
  4261. if(paramPartTokens2.size() >= 3 && paramPartTokens2[2].length() > 0) {
  4262. string autoTestCmd = paramPartTokens2[2];
  4263. if(autoTestCmd == "exit") {
  4264. printf("Detected auto test command [%s], will exit after game.\n",autoTestCmd.c_str());
  4265.  
  4266. AutoTest::setWantExitGameWhenDone(true);
  4267. }
  4268. else {
  4269. printf("WARNING: Detected and UNKNOWN auto test command [%s].\n",autoTestCmd.c_str());
  4270. }
  4271. }
  4272.  
  4273. if(paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) {
  4274. string newGameSettingsFileToLoad = paramPartTokens2[1];
  4275.  
  4276. printf("About to auto test using game settings file [%s]\n",newGameSettingsFileToLoad.c_str());
  4277. AutoTest::setLoadGameSettingsFile(newGameSettingsFileToLoad);
  4278. }
  4279. }
  4280. }
  4281.  
  4282. Renderer &renderer= Renderer::getInstance();
  4283. lang.loadStrings(language,false, true);
  4284.  
  4285. if( lang.hasString("FONT_HEIGHT_TEXT")) {
  4286. Shared::Graphics::Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",Shared::Graphics::Font::langHeightText.c_str());
  4287. }
  4288.  
  4289. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FONT_BASESIZE]) == true) {
  4290. int foundParamIndIndex = -1;
  4291. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + string("="),&foundParamIndIndex);
  4292. if(foundParamIndIndex < 0) {
  4293. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]),&foundParamIndIndex);
  4294. }
  4295. string paramValue = argv[foundParamIndIndex];
  4296. vector<string> paramPartTokens;
  4297. Tokenize(paramValue,paramPartTokens,"=");
  4298. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4299. string newfontBaseSize = paramPartTokens[1];
  4300. //printf("#1 Forcing font [%s] paramPartTokens.size() = %d, paramValue [%s]\n",newfont.c_str(),paramPartTokens.size(),paramValue.c_str());
  4301. printf("Forcing font base size[%s]\n",newfontBaseSize.c_str());
  4302.  
  4303. Shared::Graphics::Font::baseSize = strToInt(newfontBaseSize);
  4304. }
  4305. else {
  4306. printf("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4307. //printParameterHelp(argv[0],false);
  4308.  
  4309. return 1;
  4310. }
  4311. }
  4312.  
  4313. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,Shared::Graphics::Font::charCount,Shared::Graphics::Font::fontTypeName.c_str(),Shared::Platform::charSet,Shared::Graphics::Font::fontIsMultibyte,Shared::Graphics::Font::fontIsRightToLeft);
  4314. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",Shared::Graphics::Font::charCount,Shared::Graphics::Font::fontTypeName.c_str(),Shared::Platform::charSet,Shared::Graphics::Font::fontIsMultibyte,Shared::Graphics::Font::fontIsRightToLeft);
  4315.  
  4316. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FONT]) == true) {
  4317. int foundParamIndIndex = -1;
  4318. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]) + string("="),&foundParamIndIndex);
  4319. if(foundParamIndIndex < 0) {
  4320. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]),&foundParamIndIndex);
  4321. }
  4322. string paramValue = argv[foundParamIndIndex];
  4323. vector<string> paramPartTokens;
  4324. Tokenize(paramValue,paramPartTokens,"=");
  4325. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4326. string newfont = paramPartTokens[1];
  4327. //printf("#1 Forcing font [%s] paramPartTokens.size() = %d, paramValue [%s]\n",newfont.c_str(),paramPartTokens.size(),paramValue.c_str());
  4328. Properties::applyTagsToValue(newfont);
  4329. printf("Forcing font [%s]\n",newfont.c_str());
  4330.  
  4331. #if defined(WIN32)
  4332. string newEnvValue = "MEGAGLEST_FONT=" + newfont;
  4333. _putenv(newEnvValue.c_str());
  4334. #else
  4335. setenv("MEGAGLEST_FONT",newfont.c_str(),1);
  4336. #endif
  4337. }
  4338. else {
  4339. printf("\nInvalid missing font specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4340. //printParameterHelp(argv[0],false);
  4341. return 1;
  4342. }
  4343. }
  4344.  
  4345. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  4346.  
  4347. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == true) {
  4348. int foundParamIndIndex = -1;
  4349. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + string("="),&foundParamIndIndex);
  4350. if(foundParamIndIndex < 0) {
  4351. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]),&foundParamIndIndex);
  4352. }
  4353. string paramValue = argv[foundParamIndIndex];
  4354. vector<string> paramPartTokens;
  4355. Tokenize(paramValue,paramPartTokens,"=");
  4356. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4357. string itemName = paramPartTokens[1];
  4358.  
  4359. string file = Map::getMapPath(itemName,"",false);
  4360. if(file != "") {
  4361. Checksum checksum;
  4362. checksum.addFile(file);
  4363. uint32 crcValue = checksum.getSum();
  4364.  
  4365. printf("CRC value for map [%s] file [%s] is [%u]\n",itemName.c_str(),file.c_str(),crcValue);
  4366. }
  4367. else {
  4368. printf("Map [%s] was NOT FOUND\n",itemName.c_str());
  4369. return 1;
  4370. }
  4371.  
  4372. return 0;
  4373. }
  4374. else {
  4375. printf("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4376. //printParameterHelp(argv[0],false);
  4377.  
  4378. return 1;
  4379. }
  4380. }
  4381.  
  4382. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true) {
  4383. int foundParamIndIndex = -1;
  4384. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) + string("="),&foundParamIndIndex);
  4385. if(foundParamIndIndex < 0) {
  4386. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]),&foundParamIndIndex);
  4387. }
  4388. string paramValue = argv[foundParamIndIndex];
  4389. vector<string> paramPartTokens;
  4390. Tokenize(paramValue,paramPartTokens,"=");
  4391. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4392. string itemName = paramPartTokens[1];
  4393. uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + itemName + string("/*"), ".xml", NULL, true);
  4394. if(crcValue != 0) {
  4395. printf("CRC value for tileset [%s] is [%u]\n",itemName.c_str(),crcValue);
  4396. }
  4397. else {
  4398. printf("Tileset [%s] was NOT FOUND\n",itemName.c_str());
  4399. return 1;
  4400. }
  4401.  
  4402. return 0;
  4403. }
  4404. else {
  4405. printf("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4406. //printParameterHelp(argv[0],false);
  4407.  
  4408. return 0;
  4409. }
  4410. }
  4411.  
  4412. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true) {
  4413. int foundParamIndIndex = -1;
  4414. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) + string("="),&foundParamIndIndex);
  4415. if(foundParamIndIndex < 0) {
  4416. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]),&foundParamIndIndex);
  4417. }
  4418. string paramValue = argv[foundParamIndIndex];
  4419. vector<string> paramPartTokens;
  4420. Tokenize(paramValue,paramPartTokens,"=");
  4421. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4422. string itemName = paramPartTokens[1];
  4423. uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + itemName + "/*", ".xml", NULL, true);
  4424. if(crcValue != 0) {
  4425. printf("CRC value for techtree [%s] is [%u]\n",itemName.c_str(),crcValue);
  4426. }
  4427. else {
  4428. printf("Techtree [%s] was NOT FOUND\n",itemName.c_str());
  4429. return 1;
  4430. }
  4431.  
  4432. return 0;
  4433. }
  4434. else {
  4435. printf("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4436. //printParameterHelp(argv[0],false);
  4437.  
  4438. return 0;
  4439. }
  4440. }
  4441.  
  4442. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true) {
  4443. int foundParamIndIndex = -1;
  4444. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) + string("="),&foundParamIndIndex);
  4445. if(foundParamIndIndex < 0) {
  4446. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]),&foundParamIndIndex);
  4447. }
  4448. string paramValue = argv[foundParamIndIndex];
  4449. vector<string> paramPartTokens;
  4450. Tokenize(paramValue,paramPartTokens,"=");
  4451. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4452. string itemName = paramPartTokens[1];
  4453. uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptScenarios,""), "/" + itemName + "/*", ".xml", NULL, true);
  4454. if(crcValue != 0) {
  4455. printf("CRC value for scenario [%s] is [%u]\n",itemName.c_str(),crcValue);
  4456. }
  4457. else {
  4458. printf("Scenario [%s] was NOT FOUND\n",itemName.c_str());
  4459. return 1;
  4460. }
  4461.  
  4462. return 0;
  4463. }
  4464. else {
  4465. printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4466. //printParameterHelp(argv[0],false);
  4467.  
  4468. return 0;
  4469. }
  4470. }
  4471.  
  4472. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) {
  4473. int foundParamIndIndex = -1;
  4474. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + string("="),&foundParamIndIndex);
  4475. if(foundParamIndIndex < 0) {
  4476. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]),&foundParamIndIndex);
  4477. }
  4478.  
  4479. string paramValue = argv[foundParamIndIndex];
  4480. vector<string> paramPartTokens;
  4481. Tokenize(paramValue,paramPartTokens,"=");
  4482. if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) {
  4483. string itemName = paramPartTokens[1];
  4484. string itemNameFilter = paramPartTokens[2];
  4485. //printf("\n\nitemName [%s] itemNameFilter [%s]\n",itemName.c_str(),itemNameFilter.c_str());
  4486. uint32 crcValue = getFolderTreeContentsCheckSumRecursively(itemName, itemNameFilter, NULL, true);
  4487.  
  4488. printf("CRC value for path [%s] filter [%s] is [%u]\n",itemName.c_str(),itemNameFilter.c_str(),crcValue);
  4489.  
  4490. return 0;
  4491. }
  4492. else {
  4493. if(paramPartTokens.size() < 2) {
  4494. printf("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4495. }
  4496. if(paramPartTokens.size() < 3) {
  4497. printf("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 3 ? paramPartTokens[2].c_str() : NULL));
  4498. }
  4499.  
  4500. //printParameterHelp(argv[0],false);
  4501.  
  4502. return 1;
  4503. }
  4504. }
  4505.  
  4506. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true) {
  4507. int foundParamIndIndex = -1;
  4508. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_MAPS]) + string("="),&foundParamIndIndex);
  4509. if(foundParamIndIndex < 0) {
  4510. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_MAPS]),&foundParamIndIndex);
  4511. }
  4512.  
  4513. vector<string> pathList = config.getPathListForType(ptMaps,"");
  4514. vector<string> maps = MapPreview::findAllValidMaps(pathList,"",false,true);
  4515. std::sort(maps.begin(),maps.end());
  4516.  
  4517. string paramValue = argv[foundParamIndIndex];
  4518. vector<string> paramPartTokens;
  4519. Tokenize(paramValue,paramPartTokens,"=");
  4520. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4521. string itemNameFilter = paramPartTokens[1];
  4522. printf("Using filter for maps list [%s]\n",itemNameFilter.c_str());
  4523.  
  4524. vector<string> filteredMaps;
  4525. for(unsigned int i = 0; i < maps.size(); ++i) {
  4526. string mapName = maps[i];
  4527. if(itemNameFilter.find("*") != itemNameFilter.npos) {
  4528. if(StartsWith(mapName, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) {
  4529. filteredMaps.push_back(mapName);
  4530. }
  4531. }
  4532. else if(mapName == itemNameFilter) {
  4533. filteredMaps.push_back(mapName);
  4534. }
  4535. }
  4536. maps = filteredMaps;
  4537. }
  4538.  
  4539. printf("Maps found:\n===========================================\n");
  4540. for(unsigned int i = 0; i < maps.size(); ++i) {
  4541. string mapName = maps[i];
  4542. printf("%s\n",mapName.c_str());
  4543. }
  4544. printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",maps.size());
  4545.  
  4546. return 0;
  4547. }
  4548.  
  4549. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true) {
  4550. int foundParamIndIndex = -1;
  4551. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) + string("="),&foundParamIndIndex);
  4552. if(foundParamIndIndex < 0) {
  4553. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]),&foundParamIndIndex);
  4554. }
  4555.  
  4556. vector<string> pathList = config.getPathListForType(ptTechs,"");
  4557. vector<string> results;
  4558. findDirs(pathList, results);
  4559.  
  4560. bool showfactions=false;
  4561. string paramValue = argv[foundParamIndIndex];
  4562. vector<string> paramPartTokens;
  4563. Tokenize(paramValue,paramPartTokens,"=");
  4564. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4565. string cmd = paramPartTokens[1];
  4566. if(cmd == "showfactions") {
  4567. showfactions = true;
  4568. }
  4569. else {
  4570. throw megaglest_runtime_error("unknown command for techtreelist [" + cmd + "]");
  4571. }
  4572. printf("Using special command for techtree list [%s]\n",cmd.c_str());
  4573. }
  4574.  
  4575. printf("Techtrees found:\n===========================================\n");
  4576. for(unsigned int i = 0; i < results.size(); ++i) {
  4577. string name = results[i];
  4578.  
  4579. for(unsigned int j = 0; j < pathList.size(); ++j) {
  4580. string techPath = pathList[j];
  4581. if(techPath != "") {
  4582. endPathWithSlash(techPath);
  4583. }
  4584. vector<string> results2;
  4585. findDirs(techPath + name + "/factions", results2, false,true);
  4586. if(results2.empty() == false) {
  4587. string downloadArchive = techPath + name + ".7z";
  4588. //printf("dl [%s] [%s]\n",name.c_str(),downloadArchive.c_str());
  4589. if(fileExists(downloadArchive) == true) {
  4590. off_t fileSize = getFileSize(downloadArchive);
  4591. // convert to MB
  4592. double megaBytes = ((double)fileSize / 1048576.0);
  4593. printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes);
  4594. }
  4595. else {
  4596. printf("%s\n",name.c_str());
  4597. }
  4598.  
  4599. if(showfactions == true) {
  4600. printf("--> Factions:\n");
  4601. for(unsigned int k = 0; k < results2.size(); ++k) {
  4602. string name2 = results2[k];
  4603. printf("--> %s\n",name2.c_str());
  4604. }
  4605. printf("--> Total Factions: " MG_SIZE_T_SPECIFIER "\n",results2.size());
  4606. break;
  4607. }
  4608. }
  4609. }
  4610. }
  4611. printf("===========================================\nTotal Techtrees: " MG_SIZE_T_SPECIFIER "\n",results.size());
  4612.  
  4613. return 0;
  4614. }
  4615.  
  4616. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true) {
  4617. int foundParamIndIndex = -1;
  4618. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) + string("="),&foundParamIndIndex);
  4619. if(foundParamIndIndex < 0) {
  4620. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]),&foundParamIndIndex);
  4621. }
  4622.  
  4623. vector<string> pathList = config.getPathListForType(ptScenarios,"");
  4624. vector<string> results;
  4625. findDirs(pathList, results);
  4626.  
  4627. string paramValue = argv[foundParamIndIndex];
  4628. vector<string> paramPartTokens;
  4629. Tokenize(paramValue,paramPartTokens,"=");
  4630. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4631. string itemNameFilter = paramPartTokens[1];
  4632. printf("Using filter for scenarios list [%s]\n",itemNameFilter.c_str());
  4633.  
  4634. vector<string> filtered;
  4635. for(unsigned int i = 0; i < results.size(); ++i) {
  4636. string name = results[i];
  4637. if(itemNameFilter.find("*") != itemNameFilter.npos) {
  4638. if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) {
  4639. filtered.push_back(name);
  4640. }
  4641. }
  4642. else if(name == itemNameFilter) {
  4643. filtered.push_back(name);
  4644. }
  4645. }
  4646. results = filtered;
  4647. }
  4648.  
  4649. printf("Scenarios found:\n===========================================\n");
  4650. for(unsigned int i = 0; i < results.size(); ++i) {
  4651. string name = results[i];
  4652. printf("%s\n",name.c_str());
  4653. }
  4654. printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size());
  4655.  
  4656. return 0;
  4657. }
  4658.  
  4659. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true) {
  4660. int foundParamIndIndex = -1;
  4661. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TILESETS]) + string("="),&foundParamIndIndex);
  4662. if(foundParamIndIndex < 0) {
  4663. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TILESETS]),&foundParamIndIndex);
  4664. }
  4665.  
  4666. vector<string> pathList = config.getPathListForType(ptTilesets,"");
  4667. vector<string> results;
  4668. findDirs(pathList, results);
  4669.  
  4670. string paramValue = argv[foundParamIndIndex];
  4671. vector<string> paramPartTokens;
  4672. Tokenize(paramValue,paramPartTokens,"=");
  4673. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4674. string itemNameFilter = paramPartTokens[1];
  4675. printf("Using filter for tilesets list [%s]\n",itemNameFilter.c_str());
  4676.  
  4677. vector<string> filtered;
  4678. for(unsigned int i = 0; i < results.size(); ++i) {
  4679. string name = results[i];
  4680. if(itemNameFilter.find("*") != itemNameFilter.npos) {
  4681. if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) {
  4682. filtered.push_back(name);
  4683. }
  4684. }
  4685. else if(name == itemNameFilter) {
  4686. filtered.push_back(name);
  4687. }
  4688. }
  4689. results = filtered;
  4690. }
  4691.  
  4692. printf("Tilesets found:\n===========================================\n");
  4693. for(unsigned int i = 0; i < results.size(); ++i) {
  4694. string name = results[i];
  4695.  
  4696. for(unsigned int j = 0; j < pathList.size(); ++j) {
  4697. string tilesetPath = pathList[j];
  4698. if(tilesetPath != "") {
  4699. endPathWithSlash(tilesetPath);
  4700. }
  4701. if(fileExists(tilesetPath + name + "/" + name + ".xml") == true) {
  4702. string downloadArchive = tilesetPath + name + ".7z";
  4703. //printf("dl [%s] [%s]\n",name.c_str(),downloadArchive.c_str());
  4704. if(fileExists(downloadArchive) == true) {
  4705. off_t fileSize = getFileSize(downloadArchive);
  4706. // convert to MB
  4707. double megaBytes = ((double)fileSize / 1048576.0);
  4708. printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes);
  4709. }
  4710. else {
  4711. printf("%s\n",name.c_str());
  4712. }
  4713.  
  4714. break;
  4715. }
  4716. }
  4717. }
  4718. printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size());
  4719.  
  4720. return 0;
  4721. }
  4722.  
  4723. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) {
  4724. int foundParamIndIndex = -1;
  4725. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) + string("="),&foundParamIndIndex);
  4726. if(foundParamIndIndex < 0) {
  4727. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]),&foundParamIndIndex);
  4728. }
  4729.  
  4730. vector<string> pathList = config.getPathListForType(ptTutorials,"");
  4731. vector<string> results;
  4732. findDirs(pathList, results);
  4733.  
  4734. string paramValue = argv[foundParamIndIndex];
  4735. vector<string> paramPartTokens;
  4736. Tokenize(paramValue,paramPartTokens,"=");
  4737. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4738. string itemNameFilter = paramPartTokens[1];
  4739. printf("Using filter for tutorials list [%s]\n",itemNameFilter.c_str());
  4740.  
  4741. vector<string> filtered;
  4742. for(unsigned int i = 0; i < results.size(); ++i) {
  4743. string name = results[i];
  4744. if(itemNameFilter.find("*") != itemNameFilter.npos) {
  4745. if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) {
  4746. filtered.push_back(name);
  4747. }
  4748. }
  4749. else if(name == itemNameFilter) {
  4750. filtered.push_back(name);
  4751. }
  4752. }
  4753. results = filtered;
  4754. }
  4755.  
  4756. printf("Tutorials found:\n===========================================\n");
  4757. for(unsigned int i = 0; i < results.size(); ++i) {
  4758. string name = results[i];
  4759.  
  4760. for(unsigned int j = 0; j < pathList.size(); ++j) {
  4761. string tutorialsPath = pathList[j];
  4762. if(tutorialsPath != "") {
  4763. endPathWithSlash(tutorialsPath);
  4764. }
  4765. if(fileExists(tutorialsPath + name + "/" + name + ".xml") == true) {
  4766. string downloadArchive = tutorialsPath + name + ".7z";
  4767. //printf("dl [%s] [%s]\n",name.c_str(),downloadArchive.c_str());
  4768. if(fileExists(downloadArchive) == true) {
  4769. off_t fileSize = getFileSize(downloadArchive);
  4770. // convert to MB
  4771. double megaBytes = ((double)fileSize / 1048576.0);
  4772. printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes);
  4773. }
  4774. else {
  4775. printf("%s\n",name.c_str());
  4776. }
  4777.  
  4778. break;
  4779. }
  4780. }
  4781. }
  4782. printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size());
  4783.  
  4784. return 0;
  4785. }
  4786.  
  4787. program= new Program();
  4788. mainProgram = program;
  4789. renderer.setProgram(program);
  4790.  
  4791. if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
  4792. renderer.setAllowRenderUnitTitles(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled);
  4793. SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n",__FILE__,__FUNCTION__,__LINE__,SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled);
  4794. }
  4795. renderer.setAllowRenderUnitTitles(true);
  4796.  
  4797. string screenShotsPath = userData + GameConstants::folder_path_screenshots;
  4798. if(isdir(screenShotsPath.c_str()) == false) {
  4799. createDirectoryPaths(screenShotsPath);
  4800. }
  4801.  
  4802. // Cache Player textures - START
  4803. string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
  4804. std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
  4805. for(int index = 0; index < GameConstants::maxPlayers; ++index) {
  4806. //string playerTexture = data_path + "data/core/faction_textures/faction" + intToStr(index) + ".tga";
  4807. string playerTexture = getGameCustomCoreDataPath(data_path, "data/core/faction_textures/faction" + intToStr(index) + ".tga");
  4808. if(fileExists(playerTexture) == true) {
  4809. Texture2D *texture = Renderer::getInstance().newTexture2D(rsGlobal);
  4810. if(texture) {
  4811. texture->load(playerTexture);
  4812. }
  4813. crcPlayerTextureCache[index] = texture;
  4814. }
  4815. else {
  4816. crcPlayerTextureCache[index] = NULL;
  4817. }
  4818. }
  4819. // Cache Player textures - END
  4820.  
  4821. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  4822.  
  4823. mainWindow= new MainWindow(program);
  4824.  
  4825. mainWindow->setUseDefaultCursorOnly(config.getBool("No2DMouseRendering","false"));
  4826.  
  4827. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  4828.  
  4829. GameSettings startupGameSettings;
  4830.  
  4831. //parse command line
  4832. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SERVER]) == true) {
  4833. program->initServer(mainWindow,false,true);
  4834. gameInitialized = true;
  4835. }
  4836. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) {
  4837. program->initServer(mainWindow,false,true,true);
  4838. gameInitialized = true;
  4839. }
  4840. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) {
  4841. program->initServer(mainWindow,true,false);
  4842. gameInitialized = true;
  4843. }
  4844. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == true) {
  4845. string fileName = "";
  4846. int foundParamIndIndex = -1;
  4847. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]) + string("="),&foundParamIndIndex);
  4848. if(foundParamIndIndex >= 0) {
  4849. string loadfileName = argv[foundParamIndIndex];
  4850. vector<string> paramPartTokens;
  4851. Tokenize(loadfileName,paramPartTokens,"=");
  4852. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4853. fileName = paramPartTokens[1];
  4854.  
  4855. if(fileExists(fileName) == false) {
  4856. // Save the file now
  4857. string saveGameFile = "saved/" + fileName;
  4858. if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") {
  4859. saveGameFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFile;
  4860. }
  4861. else {
  4862. // string userData = config.getString("UserData_Root","");
  4863. // if(userData != "") {
  4864. // endPathWithSlash(userData);
  4865. // }
  4866. saveGameFile = userData + saveGameFile;
  4867. }
  4868. if(fileExists(saveGameFile) == true) {
  4869. fileName = saveGameFile;
  4870. }
  4871. }
  4872.  
  4873. if(fileExists(fileName) == false) {
  4874. char szBuf[8096]="";
  4875. snprintf(szBuf,8096,"File specified for loading a saved game cannot be found: [%s]",fileName.c_str());
  4876. printf("\n\n======================================================================================\n%s\n======================================================================================\n\n\n",szBuf);
  4877.  
  4878. throw megaglest_runtime_error(szBuf);
  4879. }
  4880. }
  4881. }
  4882. program->initSavedGame(mainWindow,false,fileName);
  4883. gameInitialized = true;
  4884. }
  4885. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) {
  4886. int foundParamIndIndex = -1;
  4887. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + string("="),&foundParamIndIndex);
  4888. if(foundParamIndIndex < 0) {
  4889. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]),&foundParamIndIndex);
  4890. }
  4891. string mapName = argv[foundParamIndIndex];
  4892. vector<string> paramPartTokens;
  4893. Tokenize(mapName,paramPartTokens,"=");
  4894. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4895. string autoloadMapName = paramPartTokens[1];
  4896.  
  4897. GameSettings *gameSettings = &startupGameSettings;
  4898. //int factionCount= 0;
  4899. gameSettings->setMap(autoloadMapName);
  4900. gameSettings->setTileset("forest");
  4901. gameSettings->setTech("megapack");
  4902. gameSettings->setDefaultUnits(false);
  4903. gameSettings->setDefaultResources(false);
  4904. gameSettings->setDefaultVictoryConditions(true);
  4905. gameSettings->setFogOfWar(false);
  4906. gameSettings->setAllowObservers(true);
  4907. gameSettings->setPathFinderType(pfBasic);
  4908.  
  4909. for(int i = 0; i < GameConstants::maxPlayers; ++i) {
  4910. ControlType ct= ctClosed;
  4911.  
  4912. gameSettings->setNetworkPlayerStatuses(i, npst_None);
  4913. gameSettings->setFactionControl(i, ct);
  4914. gameSettings->setStartLocationIndex(i, i);
  4915. gameSettings->setResourceMultiplierIndex(i, 10);
  4916. gameSettings->setNetworkPlayerName(i, "Closed");
  4917. }
  4918.  
  4919. ControlType ct= ctHuman;
  4920.  
  4921. gameSettings->setNetworkPlayerStatuses(0, npst_None);
  4922. gameSettings->setFactionControl(0, ct);
  4923. gameSettings->setFactionTypeName(0, formatString(GameConstants::OBSERVER_SLOTNAME));
  4924. gameSettings->setTeam(0, GameConstants::maxPlayers + fpt_Observer - 1);
  4925. gameSettings->setStartLocationIndex(0, 0);
  4926. gameSettings->setNetworkPlayerName(0, GameConstants::OBSERVER_SLOTNAME);
  4927.  
  4928. gameSettings->setFactionCount(1);
  4929.  
  4930. Config &config = Config::getInstance();
  4931. gameSettings->setEnableServerControlledAI(config.getBool("ServerControlledAI","true"));
  4932. gameSettings->setNetworkFramePeriod(config.getInt("NetworkSendFrameCount","20"));
  4933.  
  4934. program->initServer(mainWindow,gameSettings);
  4935. gameInitialized = true;
  4936. }
  4937. else {
  4938. printf("\nInvalid map name specified on commandline [%s] map [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4939. printParameterHelp(argv[0],foundInvalidArgs);
  4940. delete mainWindow;
  4941. mainWindow=NULL;
  4942. return 1;
  4943. }
  4944. }
  4945.  
  4946. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT])) == true) {
  4947. int foundParamIndIndex = -1;
  4948. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT]) + string("="),&foundParamIndIndex);
  4949. if(foundParamIndIndex < 0) {
  4950. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT]),&foundParamIndIndex);
  4951. }
  4952. string serverToConnectTo = argv[foundParamIndIndex];
  4953. vector<string> paramPartTokens;
  4954. Tokenize(serverToConnectTo,paramPartTokens,"=");
  4955. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4956. string autoConnectServer = paramPartTokens[1];
  4957.  
  4958. int port = config.getInt("PortServer",intToStr(GameConstants::serverPort).c_str());
  4959. vector<string> paramPartTokens2;
  4960. Tokenize(autoConnectServer,paramPartTokens2,":");
  4961. autoConnectServer = paramPartTokens2[0];
  4962. if(paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) {
  4963. port = strToInt(paramPartTokens2[1]);
  4964. }
  4965.  
  4966. printf("Connecting to host [%s] using port: %d\n",autoConnectServer.c_str(),port);
  4967. if(autoConnectServer == "auto-connect") {
  4968. program->initClientAutoFindHost(mainWindow);
  4969. }
  4970. else {
  4971. program->initClient(mainWindow, autoConnectServer,port);
  4972. }
  4973. gameInitialized = true;
  4974. }
  4975. else {
  4976.  
  4977. printf("\nInvalid host specified on commandline [%s] host [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  4978. printParameterHelp(argv[0],foundInvalidArgs);
  4979. delete mainWindow;
  4980. mainWindow=NULL;
  4981. return 1;
  4982. }
  4983. }
  4984.  
  4985. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT])) == true) {
  4986. int foundParamIndIndex = -1;
  4987. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]) + string("="),&foundParamIndIndex);
  4988. if(foundParamIndIndex < 0) {
  4989. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]),&foundParamIndIndex);
  4990. }
  4991. string serverToConnectTo = argv[foundParamIndIndex];
  4992. vector<string> paramPartTokens;
  4993. Tokenize(serverToConnectTo,paramPartTokens,"=");
  4994. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  4995. string autoConnectServer = paramPartTokens[1];
  4996.  
  4997. if(autoConnectServer == "auto-connect") {
  4998. program->initClientAutoFindHost(mainWindow);
  4999. }
  5000. else {
  5001. program->initClient(mainWindow, autoConnectServer);
  5002. }
  5003. gameInitialized = true;
  5004. }
  5005. else {
  5006.  
  5007. printf("\nInvalid host specified on commandline [%s] host [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  5008. printParameterHelp(argv[0],foundInvalidArgs);
  5009. delete mainWindow;
  5010. mainWindow=NULL;
  5011. return 1;
  5012. }
  5013. }
  5014. else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true) {
  5015.  
  5016. int foundParamIndIndex = -1;
  5017. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]) + string("="),&foundParamIndIndex);
  5018. if(foundParamIndIndex < 0) {
  5019. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]),&foundParamIndIndex);
  5020. }
  5021. string scenarioName = argv[foundParamIndIndex];
  5022. vector<string> paramPartTokens;
  5023. Tokenize(scenarioName,paramPartTokens,"=");
  5024. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  5025. string autoloadScenarioName = paramPartTokens[1];
  5026.  
  5027. program->initScenario(mainWindow, autoloadScenarioName);
  5028. gameInitialized = true;
  5029. }
  5030. else {
  5031. printf("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  5032. printParameterHelp(argv[0],foundInvalidArgs);
  5033. delete mainWindow;
  5034. mainWindow=NULL;
  5035. return 1;
  5036. }
  5037. }
  5038. else {
  5039. program->initNormal(mainWindow);
  5040. }
  5041.  
  5042. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5043.  
  5044. // Initialize Renderer
  5045. //Renderer &renderer= Renderer::getInstance();
  5046. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] OpenGL Info:\n%s\n",__FILE__,__FUNCTION__,__LINE__,renderer.getGlInfo().c_str());
  5047.  
  5048. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true) {
  5049. //Renderer &renderer= Renderer::getInstance();
  5050. printf("%s",renderer.getGlInfo().c_str());
  5051. printf("%s",renderer.getGlMoreInfo().c_str());
  5052.  
  5053. delete mainWindow;
  5054. mainWindow=NULL;
  5055. return 0;
  5056. }
  5057.  
  5058. if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true) {
  5059. int foundParamIndIndex = -1;
  5060. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]) + string("="),&foundParamIndIndex);
  5061. if(foundParamIndIndex < 0) {
  5062. hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]),&foundParamIndIndex);
  5063. }
  5064. string paramValue = argv[foundParamIndIndex];
  5065. vector<string> paramPartTokens;
  5066. Tokenize(paramValue,paramPartTokens,"=");
  5067. if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) {
  5068. string modelFile = paramPartTokens[1];
  5069. printf("About to convert model(s) [%s]\n",modelFile.c_str());
  5070.  
  5071. string textureFormat = "";
  5072. if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) {
  5073. textureFormat = paramPartTokens[2];
  5074. printf("About to convert using texture format [%s]\n",textureFormat.c_str());
  5075. }
  5076.  
  5077. bool keepsmallest = false;
  5078. if(paramPartTokens.size() >= 4 && paramPartTokens[1].length() > 0) {
  5079. keepsmallest = (paramPartTokens[3] == "keepsmallest");
  5080. printf("About to convert using keepsmallest = %d\n",keepsmallest);
  5081. }
  5082.  
  5083. //CoreData::getInstance().load();
  5084.  
  5085. showCursor(true);
  5086. mainWindow->setUseDefaultCursorOnly(true);
  5087.  
  5088. const Metrics &metrics= Metrics::getInstance();
  5089. renderer.clearBuffers();
  5090. renderer.clearZBuffer();
  5091. renderer.reset2d();
  5092.  
  5093. if(CoreData::getInstance().getMenuFontBig3D() != NULL) {
  5094. renderer.renderText3D(
  5095. "Please wait, converting models...",
  5096. CoreData::getInstance().getMenuFontBig3D(),
  5097. Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
  5098. (metrics.getScreenH() / 2), true);
  5099. }
  5100. else {
  5101. renderer.renderText(
  5102. "Please wait, converting models...",
  5103. CoreData::getInstance().getMenuFontBig(),
  5104. Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
  5105. (metrics.getScreenH() / 2), true);
  5106. }
  5107. renderer.swapBuffers();
  5108.  
  5109. std::vector<string> models;
  5110. if(isdir(modelFile.c_str()) == true) {
  5111. models = getFolderTreeContentsListRecursively(modelFile, ".g3d");
  5112. }
  5113. else {
  5114. models.push_back(modelFile);
  5115. }
  5116.  
  5117. sleep(0);
  5118. Shared::Platform::Window::handleEvent();
  5119. SDL_PumpEvents();
  5120.  
  5121. int result = 0;
  5122. char szTextBuf[8096]="";
  5123. for(unsigned int i =0; i < models.size(); ++i) {
  5124. string &file = models[i];
  5125. bool modelLoadedOk = false;
  5126.  
  5127. renderer.clearBuffers();
  5128. renderer.clearZBuffer();
  5129. renderer.reset2d();
  5130. snprintf(szTextBuf,8096,"Please wait, converting models [%u of " MG_SIZE_T_SPECIFIER "] ...",i,models.size());
  5131.  
  5132. if(CoreData::getInstance().getMenuFontBig3D() != NULL) {
  5133. renderer.renderText3D(
  5134. szTextBuf,
  5135. CoreData::getInstance().getMenuFontBig3D(),
  5136. Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
  5137. (metrics.getScreenH() / 2), true);
  5138. }
  5139. else {
  5140. renderer.renderText(
  5141. szTextBuf,
  5142. CoreData::getInstance().getMenuFontBig(),
  5143. Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400,
  5144. (metrics.getScreenH() / 2), true);
  5145. }
  5146. renderer.swapBuffers();
  5147.  
  5148. sleep(0);
  5149. Shared::Platform::Window::handleEvent();
  5150. SDL_PumpEvents();
  5151.  
  5152. Model *model = renderer.newModel(rsGlobal);
  5153. try {
  5154. printf("About to load model [%s] [%u of " MG_SIZE_T_SPECIFIER "]\n",file.c_str(),i,models.size());
  5155. model->load(file);
  5156. modelLoadedOk = true;
  5157. }
  5158. catch(const exception &ex) {
  5159. result = 1;
  5160. printf("ERROR loading model [%s] message [%s]\n",file.c_str(),ex.what());
  5161. }
  5162.  
  5163. if(modelLoadedOk == true) {
  5164. printf("About to save converted model [%s]\n",file.c_str());
  5165. model->save(file,textureFormat,keepsmallest);
  5166. }
  5167.  
  5168. Renderer::getInstance().endModel(rsGlobal, model);
  5169. }
  5170.  
  5171. delete mainWindow;
  5172. mainWindow=NULL;
  5173. return result;
  5174. }
  5175. else {
  5176. printf("\nInvalid model specified on commandline [%s] texture [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL));
  5177. printParameterHelp(argv[0],foundInvalidArgs);
  5178. delete mainWindow;
  5179. mainWindow=NULL;
  5180. return 1;
  5181. }
  5182. }
  5183.  
  5184. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true ||
  5185. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true ||
  5186. hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true) {
  5187. runTechValidationReport(argc, argv);
  5188.  
  5189. delete mainWindow;
  5190. mainWindow=NULL;
  5191. return 0;
  5192. }
  5193.  
  5194. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true) {
  5195. runTechTranslationExtraction(argc, argv);
  5196. delete mainWindow;
  5197. mainWindow=NULL;
  5198. return 0;
  5199. }
  5200.  
  5201. if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true) {
  5202. runTilesetValidationReport(argc, argv);
  5203.  
  5204. delete mainWindow;
  5205. mainWindow=NULL;
  5206. return 0;
  5207. }
  5208.  
  5209. gameInitialized = true;
  5210.  
  5211. // Setup the screenshots folder
  5212. // if(userData != "") {
  5213. // endPathWithSlash(userData);
  5214. // }
  5215.  
  5216. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5217.  
  5218. CheckForDuplicateData();
  5219.  
  5220. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5221.  
  5222. //throw "BLAH!";
  5223.  
  5224. // START Test out SIGSEGV error handling
  5225. //int *foo = (int*)-1; // make a bad pointer
  5226. //printf("%d\n", *foo); // causes segfault
  5227. // END
  5228. bool startCRCPrecacheThread = config.getBool("PreCacheCRCThread","true");
  5229. //printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED);
  5230. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] precache thread enabled = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread);
  5231. if(startCRCPrecacheThread == true) {
  5232. vector<string> techDataPaths = config.getPathListForType(ptTechs);
  5233. static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
  5234. preCacheThread = new FileCRCPreCacheThread();
  5235. preCacheThread->setUniqueID(mutexOwnerId);
  5236. preCacheThread->setTechDataPaths(techDataPaths);
  5237. //preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame);
  5238. preCacheThread->start();
  5239. }
  5240.  
  5241. std::auto_ptr<NavtiveLanguageNameListCacheGenerator> lngCacheGen;
  5242. std::auto_ptr<SimpleTaskThread> languageCacheGen;
  5243.  
  5244. bool startNativeLanguageNamesPrecacheThread = config.getBool("PreCacheNativeLanguageNamesThread","true");
  5245. if(startNativeLanguageNamesPrecacheThread == true &&
  5246. GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5247. lngCacheGen.reset(new NavtiveLanguageNameListCacheGenerator());
  5248. languageCacheGen.reset(new SimpleTaskThread(lngCacheGen.get(),1));
  5249.  
  5250. languageCacheGen->start();
  5251. }
  5252.  
  5253. // test
  5254. //Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0);
  5255. //throw megaglest_runtime_error("test!");
  5256. //ExceptionHandler::DisplayMessage("test!", false);
  5257.  
  5258. // Check for commands being input from stdin
  5259. string command="";
  5260.  
  5261. #ifndef WIN32
  5262. pollfd cinfd[1];
  5263. #else
  5264. HANDLE h = 0;
  5265. #endif
  5266. if(disableheadless_console == false) {
  5267. #ifndef WIN32
  5268. // Theoretically this should always be 0, but one fileno call isn't going to hurt, and if
  5269. // we try to run somewhere that stdin isn't fd 0 then it will still just work
  5270. cinfd[0].fd = fileno(stdin);
  5271. cinfd[0].events = POLLIN;
  5272. #else
  5273. h = GetStdHandle(STD_INPUT_HANDLE);
  5274. //DWORD dwMode;
  5275. //GetConsoleMode(h, &dwMode);
  5276. //SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT);
  5277. FlushConsoleInputBuffer(h);
  5278. #endif
  5279. }
  5280.  
  5281. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
  5282. printf("Headless server is now running...\n");
  5283. printf("To shutdown type: quit\n");
  5284. printf("All commands require you to press ENTER\n");
  5285. }
  5286.  
  5287. //throw megaglest_runtime_error("Test!");
  5288. //printf("About to throw an exception...\n");
  5289. //throw 123;
  5290.  
  5291. //main loop
  5292. while(program->isShutdownApplicationEnabled() == false && Shared::Platform::Window::handleEvent()) {
  5293. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
  5294.  
  5295. if(disableheadless_console == false) {
  5296. #ifndef WIN32
  5297. int pollresult = poll(cinfd, 1, 0);
  5298. int pollerror = errno;
  5299. if(pollresult)
  5300. #else
  5301. // This is problematic because input on Windows is not line-buffered so this will return
  5302. // even if getline may block. I haven't found a good way to fix it, so for the moment
  5303. // I just strongly suggest only running the server from the Python frontend, which does
  5304. // line buffer input. This does work okay as long as the user doesn't enter characters
  5305. // without pressing enter, and then try to end the server another way (say a remote
  5306. // console command), in which case we'll still be waiting for the stdin EOL and hang.
  5307.  
  5308. DWORD saveMode;
  5309. GetConsoleMode(h, &saveMode);
  5310. DWORD dwMode = saveMode;
  5311. dwMode &= ~ENABLE_MOUSE_INPUT;
  5312. dwMode &= ~ENABLE_WINDOW_INPUT;
  5313. SetConsoleMode(h, dwMode);
  5314.  
  5315. bool gotData = (WaitForSingleObject(h, 0) == WAIT_OBJECT_0);
  5316. SetConsoleMode(h, saveMode);
  5317. if(gotData == true)
  5318. #endif
  5319. {
  5320.  
  5321.  
  5322. #ifdef WIN32
  5323. bool skip = true;
  5324. DWORD nNumberOfCharsToRead = 1024;
  5325. DWORD nRead = 0;
  5326. INPUT_RECORD irInRec[1025];
  5327.  
  5328. PeekConsoleInput(h,&irInRec[0],nNumberOfCharsToRead,&nRead);
  5329. for(int i = 0; i < nRead; ++i) {
  5330. INPUT_RECORD &inr = irInRec[i];
  5331.  
  5332. //printf("inr.EventType = %d\n",inr.EventType);
  5333. if(inr.EventType == KEY_EVENT) {
  5334. if(inr.Event.KeyEvent.bKeyDown) {
  5335. char cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar;
  5336. if(cHoldKey == '\r') {
  5337. skip = false;
  5338. break;
  5339. }
  5340. }
  5341. }
  5342. }
  5343. #else
  5344. bool skip = false;
  5345. #endif
  5346. if(skip == false) {
  5347. getline(cin, command);
  5348. cin.clear();
  5349.  
  5350. printf("server command [%s]\n",command.c_str());
  5351. if(command == "quit") {
  5352. break;
  5353. }
  5354.  
  5355. #ifndef WIN32
  5356. if (cinfd[0].revents & POLLNVAL) {
  5357. printf("invalid file descriptor\n");
  5358. }
  5359. if (cinfd[0].revents & POLLERR) {
  5360. printf("error in file descriptor\n");
  5361. }
  5362. if (cinfd[0].revents & POLLHUP) {
  5363. printf("hang up in file descriptor\n");
  5364. }
  5365.  
  5366. if(pollresult < 0) {
  5367. printf("pollresult = %d errno = %d [%s]\n",pollresult,pollerror,strerror(pollerror));
  5368.  
  5369. cinfd[0].fd = fileno(stdin);
  5370. cinfd[0].events = POLLIN;
  5371. }
  5372. #endif
  5373. }
  5374. }
  5375. }
  5376. //printf("looping\n");
  5377. }
  5378.  
  5379. program->loop();
  5380.  
  5381. // Because OpenGL really doesn't do multi-threading well
  5382. // if(difftime(time(NULL),lastTextureLoadEvent) >= 3) {
  5383. // lastTextureLoadEvent = time(NULL);
  5384. // vector<Texture2D *> textureList = preCacheThread->getPendingTextureList(1);
  5385. // for(unsigned int i = 0; i < textureList.size(); ++i) {
  5386. // Texture2D * factionLogo = textureList[i];
  5387. // if(factionLogo != NULL) {
  5388. // printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str());
  5389. // //Renderer::findTexture(factionLogo);
  5390. // renderer.initTexture(rsGlobal,factionLogo);
  5391. // }
  5392. // }
  5393. // }
  5394. }
  5395.  
  5396. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
  5397. printf("\nHeadless server is about to quit...\n");
  5398. }
  5399.  
  5400. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__);
  5401.  
  5402. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5403. soundThreadManager = program->getSoundThreadManager(true);
  5404. if(soundThreadManager) {
  5405. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5406. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5407. chronoshutdownFadeSound.start();
  5408. }
  5409. }
  5410.  
  5411. cleanupCRCThread();
  5412. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5413.  
  5414. showCursor(true);
  5415. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5416. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5417. }
  5418. catch(const megaglest_runtime_error &e) {
  5419. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5420. soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
  5421. if(soundThreadManager) {
  5422. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5423. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5424. chronoshutdownFadeSound.start();
  5425. }
  5426. }
  5427.  
  5428. ExceptionHandler::handleRuntimeError(e);
  5429. }
  5430. catch(const exception &e) {
  5431. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5432. soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
  5433. if(soundThreadManager) {
  5434. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5435. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5436. chronoshutdownFadeSound.start();
  5437. }
  5438. }
  5439.  
  5440. ExceptionHandler::handleRuntimeError(e.what(),true);
  5441. }
  5442. catch(const char *e) {
  5443. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5444. soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
  5445. if(soundThreadManager) {
  5446. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5447. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5448. chronoshutdownFadeSound.start();
  5449. }
  5450. }
  5451.  
  5452. ExceptionHandler::handleRuntimeError(e,true);
  5453. }
  5454. catch(const string &ex) {
  5455. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5456. soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
  5457. if(soundThreadManager) {
  5458. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5459. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5460. chronoshutdownFadeSound.start();
  5461. }
  5462. }
  5463.  
  5464. ExceptionHandler::handleRuntimeError(ex.c_str(),true);
  5465. }
  5466. #if !defined(HAVE_GOOGLE_BREAKPAD)
  5467. catch(...) {
  5468. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5469. soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL);
  5470. if(soundThreadManager) {
  5471. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5472. soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds);
  5473. chronoshutdownFadeSound.start();
  5474. }
  5475. }
  5476.  
  5477. ExceptionHandler::handleRuntimeError("Unknown error [main]!",true);
  5478. }
  5479. #endif
  5480.  
  5481. cleanupCRCThread();
  5482.  
  5483. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5484. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5485.  
  5486. //printf("Closing IRC CLient %d\n",__LINE__);
  5487.  
  5488. delete mainWindow;
  5489. mainWindow = NULL;
  5490.  
  5491. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5492. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5493.  
  5494. //showCursor(true);
  5495. //restoreVideoMode(true);
  5496.  
  5497. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5498. GraphicComponent::clearRegisteredComponents();
  5499.  
  5500. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5501. SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5502.  
  5503. //printf("Closing IRC CLient %d\n",__LINE__);
  5504.  
  5505. if(soundThreadManager) {
  5506. SoundRenderer &soundRenderer= SoundRenderer::getInstance();
  5507. if( Config::getInstance().getString("FactorySound","") != "None" &&
  5508. soundRenderer.isVolumeTurnedOff() == false) {
  5509. //printf("chronoshutdownFadeSound.getMillis() = %llu\n",chronoshutdownFadeSound.getMillis());
  5510. for(;chronoshutdownFadeSound.getMillis() <= shutdownFadeSoundMilliseconds;) {
  5511. sleep(10);
  5512. }
  5513. }
  5514.  
  5515. BaseThread::shutdownAndWait(soundThreadManager);
  5516. delete soundThreadManager;
  5517. soundThreadManager = NULL;
  5518. }
  5519.  
  5520. //printf("Closing IRC CLient %d\n",__LINE__);
  5521.  
  5522. return 0;
  5523. }
  5524.  
  5525. #if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
  5526. void handleSIGSEGV(int sig) {
  5527. char szBuf[8096]="";
  5528. snprintf(szBuf, 8096,"In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig);
  5529. printf("%s",szBuf);
  5530. //abort();
  5531.  
  5532. ExceptionHandler::handleRuntimeError(szBuf,true);
  5533. }
  5534. #endif
  5535.  
  5536. #if defined(HAVE_GOOGLE_BREAKPAD)
  5537.  
  5538. #if defined(WIN32)
  5539. // Callback when minidump written.
  5540. static bool MinidumpCallback(const wchar_t *dump_path,
  5541. const wchar_t *minidump_id,
  5542. void *context,
  5543. EXCEPTION_POINTERS* exinfo,
  5544. MDRawAssertionInfo* assertion,
  5545. bool succeeded) {
  5546. printf("\n======= In MinidumpCallback...\n");
  5547. wprintf(L"\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s.dmp\nSucceeded: %d\n", (dump_path != NULL ? dump_path : L"(null)"),(minidump_id != NULL ? minidump_id : L"(null)"),succeeded);
  5548.  
  5549. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5550. wchar_t szBuf[8096];
  5551. int bufBytes = _snwprintf(szBuf,8096,L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp",dump_path,minidump_id);
  5552. szBuf[bufBytes] = '\0';
  5553. MessageBox(NULL, szBuf, L"Unhandled error", MB_OK|MB_SYSTEMMODAL);
  5554. }
  5555.  
  5556. return succeeded;
  5557. }
  5558.  
  5559. #else
  5560.  
  5561. // Callback when minidump written.
  5562. static bool MinidumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
  5563. void* context,
  5564. bool succeeded) {
  5565. printf("\n======= In MinidumpCallback...\n");
  5566. printf("\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s\nSucceeded: %d\n", descriptor.directory().c_str(),descriptor.path(),succeeded);
  5567.  
  5568. if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
  5569. char szBuf[8096];
  5570. snprintf(szBuf,8096,"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s",descriptor.directory().c_str(),descriptor.path());
  5571. //MessageBox(NULL, szBuf, "Unhandled error", MB_OK|MB_SYSTEMMODAL);
  5572. message(szBuf);
  5573. }
  5574.  
  5575. return succeeded;
  5576. }
  5577.  
  5578. #endif
  5579.  
  5580. #endif
  5581.  
  5582. #ifdef WIN32
  5583. void EnableCrashingOnCrashes() {
  5584. typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
  5585. typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
  5586. const DWORD EXCEPTION_SWALLOWING = 0x1;
  5587.  
  5588. HMODULE kernel32 = LoadLibraryA("kernel32.dll");
  5589. if(kernel32 != 0) {
  5590. tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy");
  5591. tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
  5592. if (pGetPolicy && pSetPolicy) {
  5593. DWORD dwFlags;
  5594. if (pGetPolicy(&dwFlags)) {
  5595. // Turn off the filter
  5596. pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
  5597. }
  5598. }
  5599. }
  5600. }
  5601. #endif
  5602.  
  5603. int glestMainSEHWrapper(int argc, char** argv) {
  5604. #ifdef WIN32_STACK_TRACE
  5605. //printf("Hooking up WIN32_STACK_TRACE...\n");
  5606. __try {
  5607. #endif
  5608.  
  5609. //application_binary= executable_path(argv[0],true);
  5610. //printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str());
  5611.  
  5612. #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
  5613.  
  5614. if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false) {
  5615. signal(SIGSEGV, handleSIGSEGV);
  5616. }
  5617.  
  5618. // http://developerweb.net/viewtopic.php?id=3013
  5619. //signal(SIGPIPE, SIG_IGN);
  5620. #endif
  5621.  
  5622. initSpecialStrings();
  5623. IRCThread::setGlobalCacheContainerName(GameConstants::ircClientCacheLookupKey);
  5624. int result = glestMain(argc, argv);
  5625.  
  5626. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5627. cleanupProcessObjects();
  5628.  
  5629. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5630.  
  5631. if(sdl_quitCalled == false) {
  5632. sdl_quitCalled = true;
  5633. SDL_Quit();
  5634. }
  5635.  
  5636. if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
  5637. return result;
  5638. #ifdef WIN32_STACK_TRACE
  5639. } __except(stackdumper(0, GetExceptionInformation(),true), EXCEPTION_CONTINUE_SEARCH) { return 0; }
  5640. #endif
  5641.  
  5642. }
  5643.  
  5644. int glestMainWrapper(int argc, char** argv) {
  5645. //setlocale(LC_ALL, "zh_TW.UTF-8");
  5646. //setlocale(LC_ALL, "");
  5647.  
  5648. #ifdef WIN32
  5649. EnableCrashingOnCrashes();
  5650. #endif
  5651.  
  5652. #if defined(HAVE_GOOGLE_BREAKPAD)
  5653. /*
  5654. handler = new ExceptionHandler(const wstring& dump_path,
  5655. FilterCallback filter,
  5656. MinidumpCallback callback,
  5657. void* callback_context,
  5658. int handler_types,
  5659. MINIDUMP_TYPE dump_type,
  5660. const wchar_t* pipe_name,
  5661. const CustomClientInfo* custom_info);
  5662. */
  5663.  
  5664. // See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/
  5665. //DWORD dwFlags;
  5666. //if (GetProcessUserModeExceptionPolicy(&dwFlags)) {
  5667. // SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1
  5668. //}
  5669.  
  5670. //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n");
  5671.  
  5672. #if defined(WIN32)
  5673. wstring dumpfilepath = utf8_decode(".");
  5674. //google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true);
  5675. errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(dumpfilepath, NULL, MinidumpCallback,
  5676. NULL, google_breakpad::ExceptionHandler::HANDLER_ALL));
  5677. #else
  5678. google_breakpad::MinidumpDescriptor descriptor(".");
  5679. errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(descriptor, NULL, MinidumpCallback, NULL, true,-1));
  5680. #endif
  5681.  
  5682. // ExceptionHandler(const wstring& dump_path,
  5683. // FilterCallback filter,
  5684. // MinidumpCallback callback,
  5685. // void* callback_context,
  5686. // int handler_types);
  5687.  
  5688. #endif
  5689.  
  5690. #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
  5691. //#ifdef DEBUG
  5692. //printf("MTRACE will be called...\n");
  5693. //mtrace ();
  5694. //#endif
  5695. #endif
  5696.  
  5697. int result = glestMainSEHWrapper(argc, argv);
  5698. return result;
  5699. }
  5700.  
  5701. }}//end namespace
  5702.  
  5703. MAIN_FUNCTION(Glest::Game::glestMainWrapper)
Add Comment
Please, Sign In to add comment