// This file is part of Glest (www.glest.org) // // Copyright (C) 2001-2008 MartiƱo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #ifdef WIN32 #include #include #include #include #endif #ifdef HAVE_GOOGLE_BREAKPAD #include "handler/exception_handler.h" #endif #include "math_wrapper.h" #include "main.h" #include #include #include "steamshim_child.h" #include "steam.h" #include "game.h" #include "main_menu.h" #include "program.h" #include "config.h" #include "metrics.h" #include "game_util.h" #include "platform_util.h" #include "platform_main.h" #include "network_interface.h" #include "ImageReaders.h" #include "renderer.h" #include "simple_threads.h" //#include #include "font.h" #include #include "menu_state_masterserver.h" #include "checksum.h" #include #include "sound_renderer.h" #include "font_gl.h" #include "FileReader.h" #include "cache_manager.h" #include #include "core_data.h" #include "font_text.h" #include #include "string_utils.h" #include "auto_test.h" #include "lua_script.h" #include "interpolation.h" #include "common_scoped_ptr.h" // To handle signal catching #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) #include #endif #if defined WIN32 && !defined(HAVE_GOOGLE_BREAKPAD) #if defined(__WIN32__) && !defined(__GNUC__) #include #endif #include #endif #ifndef WIN32 #include #define stricmp strcasecmp #define strnicmp strncasecmp #define _strnicmp strncasecmp #endif #include #include "network_message.h" #include "network_protocol.h" #include "conversion.h" #include "gen_uuid.h" //#include "intro.h" #include "leak_dumper.h" #if defined(WIN32) #ifndef _DEBUG #ifndef __GNUC__ #define WIN32_STACK_TRACE #endif #endif #endif using namespace std; using namespace Shared::Platform; using namespace Shared::Util; using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; using namespace Shared::Xml; using namespace Shared; /** * @namespace Glest * Namespace used for all %Glest related code. */ /** * @namespace Game * Namespace used for game related code. */ namespace Glest { namespace Game { static string tempDataLocation = getUserHome(); static string mg_app_name = ""; static string mailStringSupport = ""; static bool sdl_quitCalled = false; static bool disableheadless_console = false; static bool disableBacktrace = false; static bool gameInitialized = false; static Program *mainProgram = NULL; static FileCRCPreCacheThread *preCacheThread = NULL; #ifdef WIN32 static string runtimeErrorMsg = ""; // keeps in scope for duration of the application //SocketManager *winSockManager = NULL; #endif #ifdef HAVE_GOOGLE_BREAKPAD auto_ptr errorHandlerPtr; #endif class NavtiveLanguageNameListCacheGenerator : public SimpleTaskCallbackInterface { virtual void simpleTask(BaseThread *callingThread,void *userdata) { Lang &lang = Lang::getInstance(); lang.getDiscoveredLanguageList(true); } }; // ===================================================== // class ExceptionHandler // ===================================================== class ExceptionHandler: public PlatformExceptionHandler{ public: #if defined(__WIN32__) && !defined(__GNUC__) virtual void handle(LPEXCEPTION_POINTERS pointers); #endif virtual void handle(); static void logError(const char *msg, bool confirmToConsole); static void handleRuntimeError(const megaglest_runtime_error &ex); static void handleRuntimeError(const char *msg, bool getStackTraceString); static int DisplayMessage(const char *msg, bool exitApp); }; void cleanupCRCThread() { if(preCacheThread != NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); const double MAX_THREAD_WAIT = 60; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("START - shutting down crc threads\n"); time_t elapsed = time(NULL); preCacheThread->signalQuit(); for(;preCacheThread->canShutdown(false) == false && difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT;) { } if(difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("B - shutting down crc threads\n"); for(;preCacheThread->shutdownAndWait() == false && difftime((long int)time(NULL),elapsed) <= MAX_THREAD_WAIT;) { } if(preCacheThread->getRunningStatus() == false) { delete preCacheThread; preCacheThread=NULL; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("C - shutting down crc threads\n"); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("D - shutting down crc threads\n"); if(preCacheThread->canShutdown(false) == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete preCacheThread; preCacheThread=NULL; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("E - shutting down crc threads\n"); } } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("F - shutting down crc threads\n"); preCacheThread = NULL; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } static void cleanupProcessObjects() { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { showCursor(true); restoreVideoMode(::Shared::Platform::Window::getSDLWindow(), true); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 IRCCLient Cache SHUTDOWN\n"); IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(GameConstants::ircClientCacheLookupKey); if(ircClient != NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 IRCCLient Cache SHUTDOWN\n"); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ircClient->disconnect(); ircClient->signalQuit(); ircClient = NULL; sleep(0); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#4 IRCCLient Cache SHUTDOWN\n"); cleanupCRCThread(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(Renderer::isEnded() == false) { Renderer::getInstance().end(); CoreData &coreData= CoreData::getInstance(); coreData.cleanup(); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::Close(); SystemFlags::SHUTDOWN_PROGRAM_MODE=true; //printf("Closing IRC CLient %d\n",__LINE__); Thread::shutdownThreads(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("start running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size()); time_t elapsed = time(NULL); int lastLazyThreadDump = 0; for(;Thread::getThreadList().size() > 0 && difftime((long int)time(NULL),elapsed) <= 10;) { if(difftime((long int)time(NULL),elapsed) > 1) { if(lastLazyThreadDump != (int)difftime((long int)time(NULL),elapsed)) { lastLazyThreadDump = difftime((long int)time(NULL),elapsed); printf("Waiting for the following threads to exit [" MG_SIZE_T_SPECIFIER "]:\n",Thread::getThreadList().size()); for(int i = 0; i < (int)Thread::getThreadList().size(); ++i) { BaseThread *baseThread = dynamic_cast(Thread::getThreadList()[i]); printf("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n",i,baseThread,(baseThread != NULL ? 1 : 0),(baseThread != NULL ? baseThread->getUniqueID().c_str() : "")); } } } } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("end running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size()); Thread::shutdownThreads(); std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); crcPlayerTextureCache.clear(); std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); crcFactionPreviewTextureCache.clear(); std::map const * >* > &list2d = FileReader::getFileReadersMap(); deleteMapValues(list2d.begin(),list2d.end()); std::map const * >* > &list3d = FileReader::getFileReadersMap(); deleteMapValues(list3d.begin(),list3d.end()); #if defined(WANT_XERCES) XmlIo::getInstance().cleanup(); #endif if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::globalCleanupHTTP(); CacheManager::cleanupMutexes(); } #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) void fatal(const char *s, ...) // failure exit { static int errors = 0; errors++; if(errors <= 5) { // print up to two extra recursive errors defvformatstring(msg,s,s); string errText = string(msg) + " [" + runtimeErrorMsg + "]"; //puts(msg); string sErr = string(mg_app_name) + " fatal error"; SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",errText.c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",errText.c_str()); if(errors <= 1) { // avoid recursion if(SDL_WasInit(SDL_INIT_VIDEO)) { SDL_SetRelativeMouseMode(SDL_FALSE); } #ifdef WIN32 LPWSTR wstr = Ansi2WideString(errText.c_str()); LPWSTR wstr1 = Ansi2WideString(sErr.c_str()); if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { MessageBox(NULL, wstr, wstr1, MB_OK|MB_SYSTEMMODAL); } if(wstr) delete [] wstr; if(wstr1) delete [] wstr1; #endif } } // Now try to shutdown threads if possible delete mainProgram; mainProgram = NULL; // END if(sdl_quitCalled == false) { sdl_quitCalled = true; SDL_Quit(); } exit(EXIT_FAILURE); } std::string get_module_path(HMODULE module = 0) { char path_name[MAX_PATH] = {}; DWORD size = GetModuleFileNameA(module, path_name, MAX_PATH); return std::string(path_name, size); } void write_module_name(string &out, HANDLE process, DWORD64 program_counter) { DWORD64 module_base = SymGetModuleBase64(process, program_counter); if (module_base) { std::string module_name = get_module_path(reinterpret_cast(module_base)); if (!module_name.empty()) out += module_name + "|"; else out += "Unknown module|"; } else { out += "Unknown module|"; } } void write_function_name(string &out, HANDLE process, DWORD64 program_counter) { SYMBOL_INFO_PACKAGE sym = { sizeof(sym) }; sym.si.MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(process, program_counter, 0, &sym.si)) { out += string(sym.si.Name) + "()"; } else { out += "Unknown function"; } } void write_file_and_line(string & out, HANDLE process, DWORD64 program_counter) { IMAGEHLP_LINE64 ih_line = { sizeof(IMAGEHLP_LINE64) }; DWORD dummy = 0; if (SymGetLineFromAddr64(process, program_counter, &dummy, &ih_line)) { out += string("|") + string(ih_line.FileName) + ":" + intToStr(ih_line.LineNumber); } } void generate_stack_trace(string &out, CONTEXT ctx, int skip) { STACKFRAME64 sf = {}; #if !defined(_WIN64) sf.AddrPC.Offset = ctx.Eip; #else sf.AddrPC.Offset = ctx.Rip; #endif sf.AddrPC.Mode = AddrModeFlat; #if !defined(_WIN64) sf.AddrStack.Offset = ctx.Esp; #else sf.AddrStack.Offset = ctx.Rsp; #endif sf.AddrStack.Mode = AddrModeFlat; #if !defined(_WIN64) sf.AddrFrame.Offset = ctx.Ebp; #else sf.AddrFrame.Offset = ctx.Rbp; #endif sf.AddrFrame.Mode = AddrModeFlat; HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); bool tryThreadContext = true; CONTEXT threadContext; memset(&threadContext, 0, sizeof(CONTEXT)); threadContext.ContextFlags = CONTEXT_FULL; for (;;) { SetLastError(0); #if !defined(_WIN64) BOOL stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_I386, #else BOOL stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_AMD64, #endif process, thread, &sf, (tryThreadContext == false ? &threadContext : &ctx), 0, &SymFunctionTableAccess64, &SymGetModuleBase64, 0); if (!stack_walk_ok || !sf.AddrFrame.Offset) { if(tryThreadContext == true) { tryThreadContext = false; if(GetThreadContext(thread, &threadContext) != 0) { #if !defined(_WIN64) sf.AddrPC.Offset = threadContext.Eip; #else sf.AddrPC.Offset = threadContext.Rip; #endif sf.AddrPC.Mode = AddrModeFlat; #if !defined(_WIN64) sf.AddrStack.Offset = threadContext.Esp; #else sf.AddrStack.Offset = threadContext.Rsp; #endif sf.AddrStack.Mode = AddrModeFlat; #if !defined(_WIN64) sf.AddrFrame.Offset = threadContext.Ebp; #else sf.AddrFrame.Offset = threadContext.Rbp; #endif sf.AddrFrame.Mode = AddrModeFlat; } else { return; } } else { return; } } if (skip) { --skip; } else { // write the address out += intToStr(sf.AddrPC.Offset) + "|"; write_module_name(out, process, sf.AddrPC.Offset); write_function_name(out, process, sf.AddrPC.Offset); write_file_and_line(out, process, sf.AddrPC.Offset); out += "\n"; } } } struct UntypedException { explicit UntypedException(const EXCEPTION_RECORD & er) : exception_object(reinterpret_cast(er.ExceptionInformation[1])), type_array(reinterpret_cast<_ThrowInfo *>(er.ExceptionInformation[2])->pCatchableTypeArray) {} void * exception_object; _CatchableTypeArray * type_array; }; void * exception_cast_worker(const UntypedException & e, const type_info & ti) { for (int i = 0; i < e.type_array->nCatchableTypes; ++i) { _CatchableType & type_i = *e.type_array->arrayOfCatchableTypes[i]; const std::type_info & ti_i = *reinterpret_cast(type_i.pType); if (ti_i == ti) { char * base_address = reinterpret_cast(e.exception_object); base_address += type_i.thisDisplacement.mdisp; return base_address; } } return 0; } template T * exception_cast(const UntypedException & e) { const std::type_info & ti = typeid(T); return reinterpret_cast(exception_cast_worker(e, ti)); } void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep, bool fatalExit) { #ifdef HAVE_GOOGLE_BREAKPAD if(errorHandlerPtr.get() != NULL) { errorHandlerPtr->WriteMinidump(); } #endif if(!ep) { fatal("unknown type"); return; } EXCEPTION_RECORD *er = ep->ExceptionRecord; CONTEXT *context = ep->ContextRecord; string out=""; int skip = 0; switch (er->ExceptionCode) { case 0xE06D7363: { // C++ exception UntypedException ue(*er); if (std::exception * e = exception_cast(ue)) { const std::type_info & ti = typeid(*e); out += string(ti.name()) + ":" + string(e->what()); } else { out += "Unknown C++ exception thrown."; } skip = 2; // skip RaiseException and _CxxThrowException } break; case EXCEPTION_ACCESS_VIOLATION: { out += string("Access violation. Illegal ") + (er->ExceptionInformation[0] ? "write" : "read") + string(" by ") + intToStr((int)er->ExceptionAddress) + string(" at ") + intToStr(er->ExceptionInformation[1]); } break; default: { out += "SEH exception thrown. Exception code: " + er->ExceptionCode + string(" at ") + intToStr((int)er->ExceptionAddress); } } generate_stack_trace(out, *context, skip); if(fatalExit == true) { fatal(out.c_str()); } else { ExceptionHandler::logError(out.c_str(), true); } } #endif // ===================================================== // class ExceptionHandler // ===================================================== #if defined(WIN32) && !defined(__GNUC__) void ExceptionHandler::handle(LPEXCEPTION_POINTERS pointers) { string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to: " + string(mailString); msg += ", attaching the generated " + getCrashDumpFileName()+ " file."; SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",msg.c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg.c_str()); stackdumper(0, pointers, false); if(mainProgram && gameInitialized == true) { mainProgram->showMessage(msg.c_str()); } message(msg.c_str(),GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } #endif void ExceptionHandler::handle() { string msg = "#1 An error occurred and " + string(mg_app_name) + " will close.\nPlease report this bug to: " + string(mailString); #ifdef WIN32 msg += ", attaching the generated " + getCrashDumpFileName()+ " file."; #endif SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",msg.c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg.c_str()); if(mainProgram && gameInitialized == true) { mainProgram->showMessage(msg.c_str()); } message(msg.c_str(),GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } void ExceptionHandler::logError(const char *msg, bool confirmToConsole) { string errorLogFile = "error.log"; if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { errorLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + errorLogFile; } else { string userData = Config::getInstance().getString("UserData_Root",""); if(userData != "") { endPathWithSlash(userData); } errorLogFile = userData + errorLogFile; } #if defined(WIN32) && !defined(__MINGW32__) FILE *fp = _wfopen(utf8_decode(errorLogFile).c_str(), L"w"); std::ofstream logFile(fp); #else std::ofstream logFile; logFile.open(errorLogFile.c_str(), ios_base::out | ios_base::trunc); #endif if(logFile.is_open() == true) { //time_t curtime = time (NULL); //struct tm *loctime = localtime (&curtime); struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); logFile << "[" << szBuf2 << "] Runtime Error information:" << std::endl; logFile << "======================================================" << std::endl; logFile << (msg != NULL ? msg : "null") << std::endl; logFile.close(); #if defined(WIN32) && !defined(__MINGW32__) if(fp) { fclose(fp); } #endif if(confirmToConsole == true) { printf("Error saved to logfile [%s]\n",errorLogFile.c_str()); fflush(stdout); } } else { if(confirmToConsole == true) { printf("COULD NOT SAVE TO ERROR logfile [%s]\n",errorLogFile.c_str()); fflush(stdout); } } } void ExceptionHandler::handleRuntimeError(const megaglest_runtime_error &ex) { const char *msg = ex.what(); handleRuntimeError(msg,false); } void ExceptionHandler::handleRuntimeError(const char *msg, bool getStackTraceString) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); static bool inErrorNow = false; if(inErrorNow == true) { printf("\n=====================================\n"); printf("\n** Already in error handler aborting, msg [%s]\n",msg); fflush(stdout); abort(); //return; } inErrorNow = true; logError(msg,true); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n",__FILE__,__FUNCTION__,__LINE__,mainProgram,gameInitialized,msg); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,mainProgram); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n",__FILE__,__FUNCTION__,__LINE__,msg,gameInitialized,mainProgram); string errMsg = (msg != NULL ? msg : "null"); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); bool gotStackTrace = false; if(getStackTraceString == true && disableBacktrace == false && sdl_quitCalled == false) { string stackTrace = getStackTrace(); errMsg += stackTrace; gotStackTrace = true; } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); logError(errMsg.c_str(),false); if(gotStackTrace == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str()); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,errMsg.c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //abort(); if(mainProgram && gameInitialized == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(mainProgram->getState() != NULL) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); mainProgram->showMessage(errMsg.c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(glActiveTexture != NULL) { for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && mainProgram->isMessageShowing();) { ::Shared::Platform::Window::handleEvent(); try { mainProgram->loop(); } catch(const exception &e) { printf("\n=====================================\n"); printf("\n** Already in error handler exiting error rendering, msg [%s]\n",e.what()); fflush(stdout); break; } } } } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); mainProgram->showMessage(errMsg.c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(glActiveTexture != NULL) { for(;GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && mainProgram->isMessageShowing();) { ::Shared::Platform::Window::handleEvent(); try { mainProgram->loop(); } catch(const exception &e) { printf("\n=====================================\n"); printf("\n** Already in error handler exiting error rendering, msg [%s]\n",e.what()); fflush(stdout); break; } } } } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); string err = "#2 An error occurred and "; if(sdl_quitCalled == false) { err += mg_app_name; } err += " will close.\nError msg = [" + errMsg + "]\n\nPlease report this bug to "; if(sdl_quitCalled == false) { err += mailStringSupport; } #ifdef WIN32 err += string(", attaching the generated ") + getCrashDumpFileName() + string(" file."); #endif if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); message(err,GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); // Now try to shutdown threads if possible delete mainProgram; mainProgram = NULL; // END if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); #ifdef WIN32 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { showCursor(true); restoreVideoMode(::Shared::Platform::Window::getSDLWindow(), true); } runtimeErrorMsg = errMsg; inErrorNow = false; throw runtimeErrorMsg; #endif if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanupProcessObjects(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(sdl_quitCalled == false) { sdl_quitCalled = true; SDL_Quit(); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); inErrorNow = false; abort(); } int ExceptionHandler::DisplayMessage(const char *msg, bool exitApp) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); if(mainProgram && gameInitialized == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); mainProgram->showMessage(msg); } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); message(msg,GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); if(exitApp == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",msg); // Now try to shutdown threads if possible delete mainProgram; mainProgram = NULL; // END if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); cleanupProcessObjects(); if(sdl_quitCalled == false) { sdl_quitCalled = true; SDL_Quit(); } exit(-1); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n",__FILE__,__FUNCTION__,__LINE__,msg,exitApp); return 0; } // ===================================================== // class MainWindow // ===================================================== MainWindow::MainWindow(Program *program) : WindowGl(), popupMenu("MainWindow", "popupMenu") { this->program= program; //this->popupMenu.registerGraphicComponentOnlyFontCallbacks("MainWindow", "popupMenu"); this->popupMenu.setEnabled(false); this->popupMenu.setVisible(false); this->triggerLanguageToggle = false; this->triggerLanguage = ""; this->cancelLanguageSelection = -1; } MainWindow::~MainWindow(){ if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete program; program = NULL; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } int MainWindow::getDesiredScreenWidth() { Config &config= Config::getInstance(); return config.getInt("ScreenWidth"); } int MainWindow::getDesiredScreenHeight() { Config &config= Config::getInstance(); return config.getInt("ScreenHeight"); } void MainWindow::eventToggleFullScreen(bool isFullscreen) { WindowGl::eventToggleFullScreen(isFullscreen); if(isFullscreen) { Metrics::reload(this->program->getWindow()->getScreenWidth(), this->program->getWindow()->getScreenHeight()); } else { Config &config= Config::getInstance(); Metrics::reload(config.getInt("ScreenWidth"),config.getInt("ScreenHeight")); //window->setText(config.getString("WindowTitle","MegaGlest")); //this->mainMenu->init(); } } void MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton){ const Metrics &metrics = Metrics::getInstance(); int vx = metrics.toVirtualX(x); int vy = metrics.toVirtualY(getH() - y); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventMouseDown] ERROR, program == NULL!"); } if(popupMenu.getVisible() == true && popupMenu.mouseClick(vx, vy)) { std::pair result = popupMenu.mouseClickedMenuItem(vx, vy); popupMenu.setEnabled(false); popupMenu.setVisible(false); // Exit game if(result.first != cancelLanguageSelection) { Lang &lang= Lang::getInstance(); map languageList = lang.getDiscoveredLanguageList(true); for(map::iterator iterMap = languageList.begin(); iterMap != languageList.end(); ++iterMap) { string matchLanguage = iterMap->first + "-" + iterMap->second; if(matchLanguage == result.second) { this->triggerLanguageToggle = true; this->triggerLanguage = iterMap->first; break; } } } return; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); switch(mouseButton) { case mbLeft: program->mouseDownLeft(vx, vy); break; case mbRight: //program->mouseDownRight(vx, vy); break; case mbCenter: //program->mouseDownCenter(vx, vy); break; default: break; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ProgramState *programState = program->getState(); if(programState != NULL) { switch(mouseButton) { case mbLeft: programState->mouseDownLeft(vx, vy); break; case mbRight: programState->mouseDownRight(vx, vy); break; case mbCenter: programState->mouseDownCenter(vx, vy); break; default: break; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::eventMouseUp(int x, int y, MouseButton mouseButton){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); const Metrics &metrics = Metrics::getInstance(); int vx = metrics.toVirtualX(x); int vy = metrics.toVirtualY(getH() - y); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventMouseUp] ERROR, program == NULL!"); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ProgramState *programState = program->getState(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(programState != NULL) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); switch(mouseButton) { case mbLeft: programState->mouseUpLeft(vx, vy); break; case mbRight: programState->mouseUpRight(vx, vy); break; case mbCenter: programState->mouseUpCenter(vx, vy); break; default: break; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::eventMouseDoubleClick(int x, int y, MouseButton mouseButton) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); const Metrics &metrics= Metrics::getInstance(); int vx = metrics.toVirtualX(x); int vy = metrics.toVirtualY(getH() - y); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!"); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ProgramState *programState = program->getState(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(programState != NULL) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); switch(mouseButton){ case mbLeft: programState->mouseDoubleClickLeft(vx, vy); break; case mbRight: programState->mouseDoubleClickRight(vx, vy); break; case mbCenter: programState->mouseDoubleClickCenter(vx, vy); break; default: break; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::eventMouseMove(int x, int y, const MouseState *ms){ const Metrics &metrics= Metrics::getInstance(); int vx = metrics.toVirtualX(x); int vy = metrics.toVirtualY(getH() - y); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); } program->eventMouseMove(vx, vy, ms); ProgramState *programState = program->getState(); if(programState != NULL) { programState->mouseMove(vx, vy, ms); } } void MainWindow::eventMouseWheel(int x, int y, int zDelta) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); const Metrics &metrics= Metrics::getInstance(); int vx = metrics.toVirtualX(x); int vy = metrics.toVirtualY(getH() - y); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); } ProgramState *programState = program->getState(); if(programState != NULL) { programState->eventMouseWheel(vx, vy, zDelta); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::render() { if(popupMenu.getVisible() == true) { Renderer &renderer= Renderer::getInstance(); renderer.renderPopupMenu(&popupMenu); } } void MainWindow::showLanguages() { Lang &lang= Lang::getInstance(); std::vector menuItems; map languageList = lang.getDiscoveredLanguageList(true); for(map::iterator iterMap = languageList.begin(); iterMap != languageList.end(); ++iterMap) { menuItems.push_back(iterMap->first + "-" + iterMap->second); } menuItems.push_back(lang.getString("Exit")); cancelLanguageSelection = (int)menuItems.size()-1; popupMenu.setW(100); popupMenu.setH(100); popupMenu.init(lang.getString("GameMenuTitle"),menuItems); popupMenu.setEnabled(true); popupMenu.setVisible(true); } void MainWindow::toggleLanguage(string language) { popupMenu.setEnabled(false); popupMenu.setVisible(false); this->triggerLanguageToggle = false; this->triggerLanguage = ""; Lang &lang= Lang::getInstance(); string currentLanguage = lang.getLanguage(); string newLanguageSelected = language; if(language == "") { newLanguageSelected = currentLanguage; vector langResults; string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); string userDataPath = getGameCustomCoreDataPath(data_path, ""); findAll(userDataPath + "data/lang/*.lng", langResults, true, false); vector langResults2; findAll(data_path + "data/lang/*.lng", langResults2, true); if(langResults2.empty() && langResults.empty()) { throw megaglest_runtime_error("There are no lang files"); } for(unsigned int i = 0; i < langResults2.size(); ++i) { string testLanguage = langResults2[i]; if(std::find(langResults.begin(),langResults.end(),testLanguage) == langResults.end()) { langResults.push_back(testLanguage); } } for(unsigned int i = 0; i < langResults.size(); ++i) { string testLanguage = langResults[i]; if(testLanguage == currentLanguage) { if( i+1 < langResults.size()) { newLanguageSelected = langResults[i+1]; } else { newLanguageSelected = langResults[0]; } break; } } } if(newLanguageSelected != currentLanguage) { lang.loadGameStrings(newLanguageSelected); program->reloadUI(); program->consoleAddLine(lang.getString("Language") + " " + newLanguageSelected); } } bool MainWindow::eventTextInput(std::string text) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%s]\n",__FILE__,__FUNCTION__,__LINE__,text.c_str()); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); } bool result = program->textInput(text); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); return result; } bool MainWindow::eventSdlKeyDown(SDL_KeyboardEvent key) { if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); } return program->sdlKeyDown(key); } void MainWindow::eventKeyDown(SDL_KeyboardEvent key) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym); //printf("In mainwindow checking keypress for key [%d]\n",key.keysym.sym); SDL_keysym keystate = key.keysym; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c][%d]\n",__FILE__,__FUNCTION__,__LINE__,key,key); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); } if(popupMenu.getVisible() == true && isKeyPressed(SDLK_ESCAPE,key) == true) { this->popupMenu.setEnabled(false); this->popupMenu.setVisible(false); return; } program->keyDown(key); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(keystate.mod & (KMOD_LALT | KMOD_RALT)) { //if(key == vkReturn) { if(isKeyPressed(SDLK_RETURN,key) == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ALT-ENTER pressed\n",__FILE__,__FUNCTION__,__LINE__); // This stupidity only required in win32. // We reload the textures so that the canvas paints textures properly #ifdef WIN32 if(Window::getAllowAltEnterFullscreenToggle() == true) { Renderer &renderer= Renderer::getInstance(); renderer.reinitAll(); } #endif SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } } //printf("In mainwindow checking keypress for key [%d] mod [%d] modvalue: %d\n",key.keysym.sym,keystate.mod,(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL))); if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); vector modifiersToCheck; modifiersToCheck.push_back(KMOD_LCTRL); modifiersToCheck.push_back(KMOD_RCTRL); modifiersToCheck.push_back(KMOD_LALT); modifiersToCheck.push_back(KMOD_RALT); modifiersToCheck.push_back(KMOD_LSHIFT); modifiersToCheck.push_back(KMOD_RSHIFT); Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); if(isKeyPressed(configKeys.getSDLKey("HotKeyShowDebug"),key) == true) { Renderer &renderer= Renderer::getInstance(); if(keystate.mod & (KMOD_LALT | KMOD_RALT)) { renderer.cycleShowDebugUILevel(); printf("**Cycled Debug UI level to: %d\n",renderer.getShowDebugUILevel()); } else { bool showDebugUI = renderer.getShowDebugUI(); renderer.setShowDebugUI(!showDebugUI); } } else if((keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) && isKeyPressed(configKeys.getSDLKey("SwitchLanguage"),key) == true) { if((keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) { this->triggerLanguageToggle = true; this->triggerLanguage = ""; } else { showLanguages(); } } else if(isKeyPressed(configKeys.getSDLKey("ReloadINI"),key,modifiersToCheck) == true) { Config &config = Config::getInstance(); config.reload(); } else if(isKeyPressed(configKeys.getSDLKey("Screenshot"),key,modifiersToCheck) == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot key pressed\n"); string userData = Config::getInstance().getString("UserData_Root",""); if(userData != "") { endPathWithSlash(userData); } string path = userData + GameConstants::folder_path_screenshots; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot checking path [%s]\n",path.c_str()); if(isdir(path.c_str()) == false) { createDirectoryPaths(path); } if(isdir(path.c_str()) == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot path [%s]\n",path.c_str()); Config &config= Config::getInstance(); string fileFormat = config.getString("ScreenShotFileType","jpg"); unsigned int queueSize = Renderer::getInstance().getSaveScreenQueueSize(); for(int i=0; i < 5000; ++i) { path = userData + GameConstants::folder_path_screenshots; path += string("screen") + intToStr(i + queueSize) + string(".") + fileFormat; #ifdef WIN32 FILE *f= _wfopen(utf8_decode(path).c_str(), L"rb"); #else FILE *f= fopen(path.c_str(), "rb"); #endif if(f == NULL) { Lang &lang= Lang::getInstance(); char szBuf[8096]=""; if(lang.getString("ScreenshotSavedTo").length() > 0 && lang.getString("ScreenshotSavedTo")[0] != '?') { snprintf(szBuf,8096,lang.getString("ScreenshotSavedTo").c_str(),path.c_str()); } else { snprintf(szBuf,8096,"Screenshot will be saved to: %s",path.c_str()); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf); bool showScreenshotSavedMsg = Config::getInstance().getBool("DisableScreenshotConsoleText","false"); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot console showScreenshotSavedMsg = %d\n",showScreenshotSavedMsg); if(showScreenshotSavedMsg == false) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot console [%s]\n",szBuf); program->consoleAddLine(szBuf); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Screenshot save to [%s]\n",path.c_str()); Renderer::getInstance().saveScreen(path); break; } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CANNOT save Screenshot [%s]\n",path.c_str()); fclose(f); } } } } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } void MainWindow::eventKeyUp(SDL_KeyboardEvent key) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyUp] ERROR, program == NULL!"); } program->keyUp(key); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key); } void MainWindow::eventKeyPress(SDL_KeyboardEvent c) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); } program->keyPress(c); if(program != NULL && program->isInSpecialKeyCaptureEvent() == false) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); if(isKeyPressed(configKeys.getSDLKey("HotKeyToggleOSMouseEnabled"),c) == true) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); bool showCursorState = false; int state = SDL_ShowCursor(SDL_QUERY); if(state == SDL_DISABLE) { showCursorState = true; } showCursor(showCursorState); Renderer &renderer= Renderer::getInstance(); renderer.setNo2DMouseRendering(showCursorState); Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState); } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c); } void MainWindow::eventWindowEvent(SDL_WindowEvent event) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,event.event); if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); } // if(program->getState() != NULL && dynamic_cast(program->getState()) != NULL) { // printf("In eventWindowEvent skip\n"); // return; // } //Renderer &renderer= Renderer::getInstance(); switch(event.event) { case SDL_WINDOWEVENT_ENTER: { //printf("In SDL_WINDOWEVENT_ENTER\n"); // bool showCursorState = Window::lastShowMouseState; // showCursor(showCursorState); // renderer.setNo2DMouseRendering(showCursorState); // // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState); } break; case SDL_WINDOWEVENT_LEAVE: { //printf("In SDL_WINDOWEVENT_LEAVE\n"); // bool showCursorState = false; // int state = SDL_ShowCursor(SDL_QUERY); // if(state == SDL_DISABLE) { // showCursorState = true; // } // showCursor(showCursorState); // renderer.setNo2DMouseRendering(showCursorState); // // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState); } break; case SDL_WINDOWEVENT_FOCUS_GAINED: { //printf("SDL_WINDOWEVENT_FOCUS_GAINED\n"); // bool showCursorState = Window::lastShowMouseState; // showCursor(showCursorState); // renderer.setNo2DMouseRendering(showCursorState); // // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState); } break; case SDL_WINDOWEVENT_FOCUS_LOST: { //printf("SDL_WINDOWEVENT_FOCUS_LOST\n"); // bool showCursorState = false; // int state = SDL_ShowCursor(SDL_QUERY); // if(state == SDL_DISABLE) { // showCursorState = true; // } // showCursor(showCursorState); // renderer.setNo2DMouseRendering(showCursorState); // // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::lastShowMouseState = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::lastShowMouseState); } break; } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] [%d]\n",__FILE__,__FUNCTION__,__LINE__,event.event); } void MainWindow::eventActivate(bool active) { if(!active){ //minimize(); } } void MainWindow::eventResize(SizeState sizeState) { if(program == NULL) { throw megaglest_runtime_error("In [MainWindow::eventResize] ERROR, program == NULL!"); } program->resize(sizeState); } void MainWindow::eventClose(){ delete program; program= NULL; } void MainWindow::setProgram(Program *program) { this->program= program; } // ===================================================== // Main // ===================================================== SystemFlags debugger; void print_SDL_version(const char *preamble, SDL_version *v) { printf("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch); } int setupGameItemPaths(int argc, char** argv, Config *config) { // Setup path cache for files and folders used in the game std::map &pathCache = CacheManager::getCachedItem< std::map >(GameConstants::pathCacheLookupKey); Properties devProperties; string devPropertyFile = Properties::getApplicationPath() + "glest-dev.ini"; if(fileExists(devPropertyFile) == true) { devProperties.load(devPropertyFile); if(devProperties.hasString("ServerListPath") == true) { string devItem = devProperties.getString("ServerListPath"); if(devItem != "") { endPathWithSlash(devItem); } if(config != NULL) { config->setString("ServerListPath",devItem,true); } } if(devProperties.hasString("GlestKeysIniPath") == true) { string devItem = devProperties.getString("GlestKeysIniPath"); if(devItem != "") { endPathWithSlash(devItem); } if(config != NULL) { config->setString("GlestKeysIniPath",devItem,true); } } } //GAME_ARG_DATA_PATH if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DATA_PATH]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DATA_PATH]),&foundParamIndIndex); } string customPath = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(customPath,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string customPathValue = paramPartTokens[1]; Properties::applyTagsToValue(customPathValue); if(customPathValue != "") { endPathWithSlash(customPathValue); } pathCache[GameConstants::path_data_CacheLookupKey] = customPathValue; Properties::setApplicationDataPath(pathCache[GameConstants::path_data_CacheLookupKey]); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom data path [%s]\n",customPathValue.c_str()); } else { printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],false); return 1; } } else if(config != NULL) { bool foundPath = false; string customPathValue = ""; if(fileExists(devPropertyFile) == true && devProperties.hasString("DataPath") == true) { foundPath = true; customPathValue = devProperties.getString("DataPath",""); } else if(config->getString("DataPath","") != "") { foundPath = true; customPathValue = config->getString("DataPath",""); } if(foundPath == true) { pathCache[GameConstants::path_data_CacheLookupKey] = customPathValue; if(customPathValue != "") { endPathWithSlash(customPathValue); } Properties::setApplicationDataPath(pathCache[GameConstants::path_data_CacheLookupKey]); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified data path [%s]\n",config->getString("DataPath","").c_str()); } } //GAME_ARG_INI_PATH if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_INI_PATH]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_INI_PATH]),&foundParamIndIndex); } string customPath = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(customPath,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string customPathValue = paramPartTokens[1]; Properties::applyTagsToValue(customPathValue); pathCache[GameConstants::path_ini_CacheLookupKey]=customPathValue; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom ini path [%s]\n",customPathValue.c_str()); } else { printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],false); return 1; } } //GAME_ARG_LOG_PATH if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LOG_PATH]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOG_PATH]),&foundParamIndIndex); } string customPath = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(customPath,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string customPathValue = paramPartTokens[1]; Properties::applyTagsToValue(customPathValue); pathCache[GameConstants::path_logs_CacheLookupKey]=customPathValue; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom logs path [%s]\n",customPathValue.c_str()); } else { printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],false); return 1; } } else if(config != NULL) { bool foundPath = false; string customPathValue = ""; if(fileExists(devPropertyFile) == true && devProperties.hasString("LogPath") == true) { foundPath = true; customPathValue = devProperties.getString("LogPath",""); } else if(config->getString("LogPath","") != "") { foundPath = true; customPathValue = config->getString("LogPath",""); } if(foundPath == true) { pathCache[GameConstants::path_logs_CacheLookupKey] = customPathValue; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using ini specified logs path [%s]\n",config->getString("LogPath","").c_str()); } } Text::DEFAULT_FONT_PATH = pathCache[GameConstants::path_data_CacheLookupKey]; if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FONT_PATH]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_PATH]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_PATH]),&foundParamIndIndex); } string customPath = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(customPath,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string customPathValue = paramPartTokens[1]; Properties::applyTagsToValue(customPathValue); Text::DEFAULT_FONT_PATH_ABSOLUTE = customPathValue; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using custom fonts path [%s]\n",customPathValue.c_str()); } else { printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],false); return 1; } } return 0; } void setupLogging(Config &config, bool haveSpecialOutputCommandLineOption) { SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = config.getBool("DebugMode","false"); SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = config.getBool("DebugNetwork","false"); SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled = config.getBool("DebugPerformance","false"); SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled = config.getBool("DebugWorldSynch","false"); SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled = config.getBool("DebugUnitCommands","false"); SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled = config.getBool("DebugPathFinder","false"); SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled = config.getBool("DebugLUA","false"); LuaScript::setDebugModeEnabled(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled); SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled = config.getBool("DebugSound","false"); SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled = config.getBool("DebugError","true"); string userData = config.getString("UserData_Root",""); if(userData != "") { endPathWithSlash(userData); } #ifdef HAVE_GOOGLE_BREAKPAD if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 In setting up errorHandlerPtr->set_dump_path [%p]...\n",errorHandlerPtr.get()); if(errorHandlerPtr.get() != NULL) { string dumpFilePath; if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { dumpFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); } else { dumpFilePath = userData; } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 In setting up errorHandlerPtr->set_dump_path...\n"); #if defined(WIN32) wstring dumpfilepath = utf8_decode(dumpFilePath); if(SystemFlags::VERBOSE_MODE_ENABLED) wprintf(L"Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",dumpfilepath.c_str()); errorHandlerPtr->set_dump_path(dumpfilepath); #else if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n",dumpFilePath.c_str()); //errorHandlerPtr->set_dump_path(dumpfilepath); google_breakpad::MinidumpDescriptor descriptor(dumpFilePath); errorHandlerPtr->set_minidump_descriptor(descriptor); #endif } #endif string debugLogFile = config.getString("DebugLogFile",""); if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLogFile; } else { debugLogFile = userData + debugLogFile; } string debugWorldSynchLogFile = config.getString("DebugLogFileWorldSynch",""); if(debugWorldSynchLogFile == "") { debugWorldSynchLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugWorldSynchLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugWorldSynchLogFile; } else { debugWorldSynchLogFile = userData + debugWorldSynchLogFile; } string debugPerformanceLogFile = config.getString("DebugLogFilePerformance",""); if(debugPerformanceLogFile == "") { debugPerformanceLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugPerformanceLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPerformanceLogFile; } else { debugPerformanceLogFile = userData + debugPerformanceLogFile; } string debugNetworkLogFile = config.getString("DebugLogFileNetwork",""); if(debugNetworkLogFile == "") { debugNetworkLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugNetworkLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugNetworkLogFile; } else { debugNetworkLogFile = userData + debugNetworkLogFile; } string debugUnitCommandsLogFile = config.getString("DebugLogFileUnitCommands",""); if(debugUnitCommandsLogFile == "") { debugUnitCommandsLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugUnitCommandsLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugUnitCommandsLogFile; } else { debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile; } string debugPathFinderLogFile = config.getString("DebugLogFilePathFinder",""); if(debugPathFinderLogFile == "") { debugPathFinderLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugPathFinderLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugPathFinderLogFile; } else { debugPathFinderLogFile = userData + debugPathFinderLogFile; } string debugLUALogFile = config.getString("DebugLogFileLUA",""); if(debugLUALogFile == "") { debugLUALogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugLUALogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugLUALogFile; } else { debugLUALogFile = userData + debugLUALogFile; } string debugSoundLogFile = config.getString("DebugLogFileSound",""); if(debugSoundLogFile == "") { debugSoundLogFile = debugLogFile; } else if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { debugSoundLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugSoundLogFile; } else { debugSoundLogFile = userData + debugSoundLogFile; } string debugErrorLogFile = config.getString("DebugLogFileError",""); SystemFlags::getSystemSettingType(SystemFlags::debugSystem).debugLogFileName = debugLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).debugLogFileName = debugNetworkLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).debugLogFileName = debugPerformanceLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).debugLogFileName = debugWorldSynchLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).debugLogFileName = debugUnitCommandsLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).debugLogFileName = debugPathFinderLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugLUA).debugLogFileName = debugLUALogFile; SystemFlags::getSystemSettingType(SystemFlags::debugSound).debugLogFileName = debugSoundLogFile; SystemFlags::getSystemSettingType(SystemFlags::debugError).debugLogFileName = debugErrorLogFile; if(haveSpecialOutputCommandLineOption == false) { 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", SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled, debugLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled, debugNetworkLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled, debugPerformanceLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled, debugWorldSynchLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled, debugUnitCommandsLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled, debugPathFinderLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled, debugLUALogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled, debugSoundLogFile.c_str(), SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled, debugErrorLogFile.c_str()); } } void runTilesetValidationForPath(string tilesetPath, string tilesetName, World &world, bool purgeUnusedFiles,bool purgeDuplicateFiles, bool showDuplicateFiles, bool gitPurgeFiles,double &purgedMegaBytes) { Checksum checksum; //bool techtree_errors = false; std::map > > loadedFileList; vector pathList; pathList.push_back(tilesetPath); world.loadTileset(pathList, tilesetName,&checksum, loadedFileList); // Fixup paths with .. { std::map > > newLoadedFileList; for( std::map > >::iterator iterMap = loadedFileList.begin(); iterMap != loadedFileList.end(); ++iterMap) { string loadedFile = iterMap->first; replaceAll(loadedFile,"//","/"); replaceAll(loadedFile,"\\\\","\\"); updatePathClimbingParts(loadedFile); if(newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) { for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { pair &newVal = iterMap->second[xx1]; replaceAll(newVal.first,"//","/"); replaceAll(newVal.first,"\\\\","\\"); updatePathClimbingParts(newVal.first); replaceAll(newVal.second,"//","/"); replaceAll(newVal.second,"\\\\","\\"); updatePathClimbingParts(newVal.second); newLoadedFileList[loadedFile].push_back(newVal); } } else { for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { pair &newVal = iterMap->second[xx1]; replaceAll(newVal.first,"//","/"); replaceAll(newVal.first,"\\\\","\\"); updatePathClimbingParts(newVal.first); replaceAll(newVal.second,"//","/"); replaceAll(newVal.second,"\\\\","\\"); updatePathClimbingParts(newVal.second); } newLoadedFileList[loadedFile] = iterMap->second; } } loadedFileList = newLoadedFileList; } // Validate the faction setup to ensure we don't have any bad associations // std::vector resultErrors = world.validateFactionTypes(); // Now check for unused files in the techtree std::map > > foundFileList; for(unsigned int i = 0; i < pathList.size(); ++i) { string path = pathList[i]; endPathWithSlash(path); path = path + tilesetName + "/"; replaceAll(path, "//", "/"); replaceAll(path, "\\\\", "\\"); vector foundFiles = getFolderTreeContentsListRecursively(path + "*.", ""); for(unsigned int j = 0; j < foundFiles.size(); ++j) { string file = foundFiles[j]; replaceAll(file, "//", "/"); replaceAll(file, "\\\\", "\\"); replaceAll(file,"//","/"); replaceAll(file,"\\\\","\\"); foundFileList[file].push_back(make_pair(path,path)); } } printf("Found tileset filecount = " MG_SIZE_T_SPECIFIER ", used = " MG_SIZE_T_SPECIFIER "\n",foundFileList.size(),loadedFileList.size()); int purgeCount = 0; bool foundUnusedFile = false; for( std::map > >::iterator iterMap = foundFileList.begin(); iterMap != foundFileList.end(); ++iterMap) { string foundFile = iterMap->first; replaceAll(foundFile, "//", "/"); replaceAll(foundFile, "\\\\", "\\"); if(loadedFileList.find(foundFile) == loadedFileList.end() && foundFile.find("lang/") == foundFile.npos) { if(foundUnusedFile == false) { printf("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",__LINE__); } foundUnusedFile = true; printf("[%s]\n",foundFile.c_str()); string fileName = extractFileFromDirectoryPath(foundFile); if(loadedFileList.find(fileName) != loadedFileList.end()) { printf("possible match on [%s] ?\n",loadedFileList.find(fileName)->first.c_str()); } else if(purgeUnusedFiles == true) { off_t fileSize = getFileSize(foundFile); // convert to MB purgedMegaBytes += ((double)fileSize / 1048576.0); purgeCount++; if(gitPurgeFiles == true) { char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",foundFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } } else { removeFile(foundFile); } } } } if(foundUnusedFile == true) { if(purgedMegaBytes > 0) { printf("Purged %.2f MB (%d) in files\n",purgedMegaBytes,purgeCount); } printf("\nLine ref: %d, Warning, unused files were detected - END:\n",__LINE__); } if(showDuplicateFiles == true) { std::map > mapDuplicateFiles; // Now check for duplicate data content for(std::map > >::iterator iterMap = loadedFileList.begin(); iterMap != loadedFileList.end(); ++iterMap) { string fileName = iterMap->first; Checksum checksum; checksum.addFile(fileName); uint32 crcValue = checksum.getSum(); mapDuplicateFiles[crcValue].push_back(fileName); } double duplicateMegaBytesPurged=0; int duplicateCountPurged=0; double duplicateMegaBytes=0; int duplicateCount=0; bool foundDuplicates = false; for(std::map >::iterator iterMap = mapDuplicateFiles.begin(); iterMap != mapDuplicateFiles.end(); ++iterMap) { vector &fileList = iterMap->second; if(fileList.size() > 1) { if(foundDuplicates == false) { foundDuplicates = true; printf("\nWarning, duplicate files were detected - START:\n=====================\n"); } map parentList; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; if(idx > 0) { off_t fileSize = getFileSize(duplicateFile); // convert to MB duplicateMegaBytes += ((double)fileSize / 1048576.0); duplicateCount++; } else { printf("\n"); } printf("[%s]\n",duplicateFile.c_str()); std::map > >::iterator iterFind = loadedFileList.find(duplicateFile); if(iterFind != loadedFileList.end()) { for(unsigned int jdx = 0; jdx < iterFind->second.size(); jdx++) { parentList[iterFind->second[jdx].first]++; } } } for(map::iterator iterMap1 = parentList.begin(); iterMap1 != parentList.end(); ++iterMap1) { if(iterMap1 == parentList.begin()) { printf("\tParents:\n"); } printf("\t[%s]\n",iterMap1->first.c_str()); } if(purgeDuplicateFiles == true) { string newCommonFileName = ""; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { off_t fileSize = getFileSize(duplicateFile); if(idx == 0) { newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile); string expandedNewCommonFileName = newCommonFileName; std::map mapExtraTagReplacementValues; mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues); Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues); replaceAll(expandedNewCommonFileName, "//", "/"); createDirectoryPaths(extractDirectoryPathFromFile(expandedNewCommonFileName)); if(gitPurgeFiles == true) { copyFileTo(duplicateFile, expandedNewCommonFileName); char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",duplicateFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } printf("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str()); } else { //int result = 0; int result = rename(duplicateFile.c_str(),expandedNewCommonFileName.c_str()); if(result != 0) { char szBuf[8096]=""; char *errmsg = strerror(errno); snprintf(szBuf,8096,"!!! Error [%s] Could not rename [%s] to [%s]!",errmsg,duplicateFile.c_str(),expandedNewCommonFileName.c_str()); throw megaglest_runtime_error(szBuf); } else { printf("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str()); } } } else { if(gitPurgeFiles == true) { char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",duplicateFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } printf("*** Duplicate file:\n[%s]\nwas git rm\n",duplicateFile.c_str()); } else { removeFile(duplicateFile); } printf("*** Duplicate file:\n[%s]\nwas removed\n",duplicateFile.c_str()); // convert to MB duplicateMegaBytesPurged += ((double)fileSize / 1048576.0); duplicateCountPurged++; } } } std::map mapUniqueParentList; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { std::map > >::iterator iterFind2 = loadedFileList.find(duplicateFile); if(iterFind2 != loadedFileList.end()) { for(unsigned int jdx1 = 0; jdx1 < iterFind2->second.size(); jdx1++) { string parentFile = iterFind2->second[jdx1].first; string searchText = iterFind2->second[jdx1].second; if(mapUniqueParentList.find(parentFile) == mapUniqueParentList.end()) { 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()); bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false); printf("foundText = %d\n",foundText); if(foundText == false) { char szBuf[8096]=""; snprintf(szBuf,8096,"Line ref = %d, Error finding text [%s] in file [%s]",__LINE__,searchText.c_str(),parentFile.c_str()); throw megaglest_runtime_error(szBuf); } mapUniqueParentList[parentFile]++; } } } } } } else { string newCommonFileName = ""; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { //off_t fileSize = getFileSize(duplicateFile); if(idx == 0) { newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile); break; } } } for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { std::map > >::iterator iterFind4 = loadedFileList.find(duplicateFile); if(iterFind4 != loadedFileList.end()) { for(unsigned int jdx = 0; jdx < iterFind4->second.size(); jdx++) { string parentFile = iterFind4->second[jdx].first; string searchText = iterFind4->second[jdx].second; bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true); if(foundText == false) { char szBuf[8096]=""; 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()); printf("\n\n=================================================\n%s",szBuf); throw megaglest_runtime_error(szBuf); } } } } } } } } if(foundDuplicates == true) { printf("Duplicates %.2f MB (%d) in files\n",duplicateMegaBytes,duplicateCount); printf("Duplicates purged %.2f MB (%d) in files\n",duplicateMegaBytesPurged,duplicateCountPurged); printf("\nWarning, duplicate files were detected - END:\n"); } } //if(techtree_errors == false) { printf("\nValidation found NO ERRORS for tilesetPath [%s] tilesetName [%s]:\n",tilesetPath.c_str(), tilesetName.c_str()); //} printf("----------------------------------------------------------------"); } void runTechValidationForPath(string techPath, string techName, const std::vector &filteredFactionList, World &world, bool purgeUnusedFiles,bool purgeDuplicateFiles, bool showDuplicateFiles, bool gitPurgeFiles,double &purgedMegaBytes) { string techTreeFolder = techPath + techName; string techTreeFactionFolder = techTreeFolder + "/factions/"; vector factionsList; findDirs(techTreeFactionFolder, factionsList, false, false); if(factionsList.empty() == false) { Checksum checksum; set factions; for(int j = 0; j < (int)factionsList.size(); ++j) { if( filteredFactionList.empty() == true || std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) { factions.insert(factionsList[j]); } } printf("\n----------------------------------------------------------------"); printf("\nChecking techPath [%s] techName [%s] total faction count = %d\n",techPath.c_str(), techName.c_str(),(int)factionsList.size()); for(int j = 0; j < (int)factionsList.size(); ++j) { if( filteredFactionList.empty() == true || std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) { printf("Using faction [%s]\n",factionsList[j].c_str()); } } if(factions.empty() == false) { bool techtree_errors = false; std::map > > loadedFileList; vector pathList; pathList.push_back(techPath); Config &config = Config::getInstance(); vector otherTechPaths = config.getPathListForType(ptTechs,""); pathList.insert(pathList.end(), otherTechPaths.begin(), otherTechPaths.end()); try { world.loadTech(pathList, techName, factions, &checksum, loadedFileList, true); // Fixup paths with .. { std::map > > newLoadedFileList; for( std::map > >::iterator iterMap = loadedFileList.begin(); iterMap != loadedFileList.end(); ++iterMap) { string loadedFile = iterMap->first; replaceAll(loadedFile,"//","/"); replaceAll(loadedFile,"\\\\","\\"); updatePathClimbingParts(loadedFile); if(newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) { for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { pair &newVal = iterMap->second[xx1]; replaceAll(newVal.first,"//","/"); replaceAll(newVal.first,"\\\\","\\"); updatePathClimbingParts(newVal.first); replaceAll(newVal.second,"//","/"); replaceAll(newVal.second,"\\\\","\\"); updatePathClimbingParts(newVal.second); newLoadedFileList[loadedFile].push_back(newVal); } } else { for(unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { pair &newVal = iterMap->second[xx1]; replaceAll(newVal.first,"//","/"); replaceAll(newVal.first,"\\\\","\\"); updatePathClimbingParts(newVal.first); replaceAll(newVal.second,"//","/"); replaceAll(newVal.second,"\\\\","\\"); updatePathClimbingParts(newVal.second); } newLoadedFileList[loadedFile] = iterMap->second; } } loadedFileList = newLoadedFileList; } // Validate the faction setup to ensure we don't have any bad associations std::vector resultErrors = world.validateFactionTypes(); if(resultErrors.empty() == false) { techtree_errors = true; // Display the validation errors string errorText = "\nErrors were detected:\n=====================\n"; for(int i = 0; i < (int)resultErrors.size(); ++i) { if(i > 0) { errorText += "\n"; } errorText = errorText + resultErrors[i]; } errorText += "\n=====================\n"; printf("%s",errorText.c_str()); } // Validate the faction resource setup to ensure we don't have any bad associations printf("\nChecking resources, count = %d\n",world.getTechTree()->getResourceTypeCount()); for(int i = 0; i < world.getTechTree()->getResourceTypeCount(); ++i) { printf("Found techtree resource [%s]\n",world.getTechTree()->getResourceType(i)->getName().c_str()); } resultErrors = world.validateResourceTypes(); if(resultErrors.empty() == false) { techtree_errors = true; // Display the validation errors string errorText = "\nErrors were detected:\n=====================\n"; for(int i = 0; i < (int)resultErrors.size(); ++i) { if(i > 0) { errorText += "\n"; } errorText = errorText + resultErrors[i]; } errorText += "\n=====================\n"; printf("%s",errorText.c_str()); } // Now check for unused files in the techtree std::map > > foundFileList; for(unsigned int i = 0; i < pathList.size(); ++i) { string path = pathList[i]; endPathWithSlash(path); path = path + techName + "/"; replaceAll(path, "//", "/"); replaceAll(path, "\\\\", "\\"); vector foundFiles = getFolderTreeContentsListRecursively(path + "*.", ""); for(unsigned int j = 0; j < foundFiles.size(); ++j) { string file = foundFiles[j]; replaceAll(file, "//", "/"); replaceAll(file, "\\\\", "\\"); // ignore loading screen, preview screen and hud if( file.find(GameConstants::LOADING_SCREEN_FILE) != string::npos || file.find(GameConstants::PREVIEW_SCREEN_FILE) != string::npos || file.find(GameConstants::HUD_SCREEN_FILE) != string::npos) { continue; } // ignore commondata since we are not loading all factions if(filteredFactionList.size() > 0) { if( file.find("/commondata/") != string::npos) { continue; } } if(file.find("/factions/") != string::npos) { bool includeFaction = false; for ( set::iterator it = factions.begin(); it != factions.end(); ++it ) { string currentFaction = *it; if(file.find("/factions/" + currentFaction) != string::npos) { includeFaction = true; break; } } if(includeFaction == false) { continue; } } replaceAll(file,"//","/"); replaceAll(file,"\\\\","\\"); foundFileList[file].push_back(make_pair(path,path)); } } printf("Found techtree filecount = " MG_SIZE_T_SPECIFIER ", used = " MG_SIZE_T_SPECIFIER "\n",foundFileList.size(),loadedFileList.size()); int purgeCount = 0; bool foundUnusedFile = false; for( std::map > >::iterator iterMap = foundFileList.begin(); iterMap != foundFileList.end(); ++iterMap) { string foundFile = iterMap->first; replaceAll(foundFile, "//", "/"); replaceAll(foundFile, "\\\\", "\\"); if(loadedFileList.find(foundFile) == loadedFileList.end() && foundFile.find("lang/") == foundFile.npos) { if(foundUnusedFile == false) { printf("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n",__LINE__); } foundUnusedFile = true; printf("[%s]\n",foundFile.c_str()); string fileName = extractFileFromDirectoryPath(foundFile); if(loadedFileList.find(fileName) != loadedFileList.end()) { printf("possible match on [%s] ?\n",loadedFileList.find(fileName)->first.c_str()); } else if(purgeUnusedFiles == true) { off_t fileSize = getFileSize(foundFile); // convert to MB purgedMegaBytes += ((double)fileSize / 1048576.0); purgeCount++; if(gitPurgeFiles == true) { char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",foundFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } } else { removeFile(foundFile); } } } } if(foundUnusedFile == true) { if(purgedMegaBytes > 0) { printf("Purged %.2f MB (%d) in files\n",purgedMegaBytes,purgeCount); } printf("\nLine ref: %d, Warning, unused files were detected - END:\n",__LINE__); } if(showDuplicateFiles == true) { std::map > mapDuplicateFiles; // Now check for duplicate data content for(std::map > >::iterator iterMap = loadedFileList.begin(); iterMap != loadedFileList.end(); ++iterMap) { string fileName = iterMap->first; Checksum checksum; checksum.addFile(fileName); uint32 crcValue = checksum.getSum(); if(crcValue == 0) { char szBuf[8096]=""; snprintf(szBuf,8096,"Error calculating CRC for file [%s]",fileName.c_str()); throw megaglest_runtime_error(szBuf); } mapDuplicateFiles[crcValue].push_back(fileName); } double duplicateMegaBytesPurged=0; int duplicateCountPurged=0; double duplicateMegaBytes=0; int duplicateCount=0; bool foundDuplicates = false; for(std::map >::iterator iterMap = mapDuplicateFiles.begin(); iterMap != mapDuplicateFiles.end(); ++iterMap) { vector &fileList = iterMap->second; if(fileList.size() > 1) { if(foundDuplicates == false) { foundDuplicates = true; printf("\nWarning, duplicate files were detected - START:\n=====================\n"); } 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()); map parentList; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; if(idx > 0) { off_t fileSize = getFileSize(duplicateFile); // convert to MB duplicateMegaBytes += ((double)fileSize / 1048576.0); duplicateCount++; } else { printf("\n"); } printf("[%s]\n",duplicateFile.c_str()); std::map > >::iterator iterFind = loadedFileList.find(duplicateFile); if(iterFind != loadedFileList.end()) { for(unsigned int jdx = 0; jdx < iterFind->second.size(); jdx++) { parentList[iterFind->second[jdx].first]++; } } string newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile); string expandedNewCommonFileName = newCommonFileName; std::map mapExtraTagReplacementValues; string techCommonData = techPath + techName + "/commondata/"; replaceAll(techCommonData, "//", "/"); mapExtraTagReplacementValues["$COMMONDATAPATH"] = techCommonData; mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues); Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues); replaceAll(expandedNewCommonFileName, "//", "/"); } printf("----- Finding parents for duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str()); for(map::iterator iterMap1 = parentList.begin(); iterMap1 != parentList.end(); ++iterMap1) { if(iterMap1 == parentList.begin()) { printf("\tParents:\n"); } printf("\t[%s]\n",iterMap1->first.c_str()); } if(purgeDuplicateFiles == true) { printf("----- move / remove duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str()); // First move first duplicate to commondata and delete all other copies string newCommonFileName = ""; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { off_t fileSize = getFileSize(duplicateFile); printf("#1 [%u / " MG_SIZE_T_SPECIFIER "] removing duplicate [%s]\n",idx,fileList.size(),duplicateFile.c_str()); if(idx == 0) { newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile); string expandedNewCommonFileName = newCommonFileName; std::map mapExtraTagReplacementValues; string techCommonData = techPath + techName + "/commondata/"; replaceAll(techCommonData, "//", "/"); mapExtraTagReplacementValues["$COMMONDATAPATH"] = techCommonData; mapExtraTagReplacementValues = Properties::getTagReplacementValues(&mapExtraTagReplacementValues); Properties::applyTagsToValue(expandedNewCommonFileName,&mapExtraTagReplacementValues); replaceAll(expandedNewCommonFileName, "//", "/"); createDirectoryPaths(extractDirectoryPathFromFile(expandedNewCommonFileName)); if(gitPurgeFiles == true) { copyFileTo(duplicateFile, expandedNewCommonFileName); char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",duplicateFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } printf("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str()); } else { printf("moving duplicate [%s] to common data [%s] expanded to [%s]\n",duplicateFile.c_str(),newCommonFileName.c_str(),expandedNewCommonFileName.c_str()); int result = rename(duplicateFile.c_str(),expandedNewCommonFileName.c_str()); if(result != 0) { char szBuf[8096]=""; char *errmsg = strerror(errno); snprintf(szBuf,8096,"!!! Error [%s] Could not rename [%s] to [%s]!",errmsg,duplicateFile.c_str(),expandedNewCommonFileName.c_str()); throw megaglest_runtime_error(szBuf); } else { printf("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n",duplicateFile.c_str(),expandedNewCommonFileName.c_str()); } } } else { if(gitPurgeFiles == true) { char szBuf[8096]=""; snprintf(szBuf,8096,"git rm \"%s\"",duplicateFile.c_str()); bool gitOk = executeShellCommand(szBuf,0); if(gitOk == false) { throw megaglest_runtime_error("Call to command failed [" + string(szBuf) + "]"); } printf("*** Duplicate file:\n[%s]\nwas git rm\n",duplicateFile.c_str()); } else { printf("removing duplicate [%s]\n",duplicateFile.c_str()); removeFile(duplicateFile); } printf("*** Duplicate file:\n[%s]\nwas removed\n",duplicateFile.c_str()); // convert to MB duplicateMegaBytesPurged += ((double)fileSize / 1048576.0); duplicateCountPurged++; } } } printf("----- update XML files for duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str()); std::map mapUniqueParentList; // Update the XML files to point to the new single copy in commondata for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { std::map > >::iterator iterFind2 = loadedFileList.find(duplicateFile); if(iterFind2 != loadedFileList.end()) { for(unsigned int jdx1 = 0; jdx1 < iterFind2->second.size(); jdx1++) { string parentFile = iterFind2->second[jdx1].first; string searchText = iterFind2->second[jdx1].second; if(mapUniqueParentList.find(parentFile) == mapUniqueParentList.end()) { 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()); bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false); printf("foundText = %d\n",foundText); if(foundText == false) { string techCommonData = techPath + techName + "/commondata/"; replaceAll(techCommonData, "//", "/"); if(StartsWith(searchText, techCommonData) == true) { printf("WARNING #1 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", foundText,parentFile.c_str(),techCommonData.c_str(),searchText.c_str(),newCommonFileName.c_str()); replaceAll(searchText, techCommonData, "$COMMONDATAPATH/"); foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, false); printf("WARNING #2 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", foundText,parentFile.c_str(),techCommonData.c_str(),searchText.c_str(),newCommonFileName.c_str()); } if(foundText == false) { char szBuf[8096]=""; 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()); printf("\n\n=================================================\n%s",szBuf); throw megaglest_runtime_error(szBuf); } } mapUniqueParentList[parentFile]++; } } } } } } else { string newCommonFileName = ""; for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { //off_t fileSize = getFileSize(duplicateFile); if(idx == 0) { newCommonFileName = "$COMMONDATAPATH/sounds/" + extractFileFromDirectoryPath(duplicateFile); break; } } } for(unsigned int idx = 0; idx < fileList.size(); ++idx) { string duplicateFile = fileList[idx]; string fileExt = extractExtension(duplicateFile); if(fileExt == "wav" || fileExt == "ogg") { std::map > >::iterator iterFind4 = loadedFileList.find(duplicateFile); if(iterFind4 != loadedFileList.end()) { for(unsigned int jdx = 0; jdx < iterFind4->second.size(); jdx++) { string parentFile = iterFind4->second[jdx].first; string searchText = iterFind4->second[jdx].second; bool foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true); if(foundText == false) { string techCommonData = techPath + techName + "/commondata/"; replaceAll(techCommonData, "//", "/"); if(StartsWith(searchText, techCommonData) == true) { replaceAll(searchText, techCommonData, "$COMMONDATAPATH/"); foundText = searchAndReplaceTextInFile(parentFile, searchText, newCommonFileName, true); } if(foundText == false) { // Check if the sound file already references commandata foundText = searchAndReplaceTextInFile(parentFile, newCommonFileName, newCommonFileName, true); if(foundText == false) { char szBuf[8096]=""; 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()); printf("\n\n=================================================\n%s",szBuf); throw megaglest_runtime_error(szBuf); } } } } } } } } printf("----- END duplicate files [" MG_SIZE_T_SPECIFIER "] first file is [%s]\n",fileList.size(),fileList[0].c_str()); } } if(foundDuplicates == true) { printf("Duplicates %.2f MB (%d) in files\n",duplicateMegaBytes,duplicateCount); printf("Duplicates purged %.2f MB (%d) in files\n",duplicateMegaBytesPurged,duplicateCountPurged); printf("\nWarning, duplicate files were detected - END:\n"); } } } catch(const megaglest_runtime_error &ex) { techtree_errors = true; printf("\n\n****ERROR**** detected while validating the techName: %s\nMESSAGE: %s\n",techName.c_str(),ex.what()); } if(techtree_errors == false) { printf("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n",techPath.c_str(), techName.c_str(),(int)factions.size()); for ( set::iterator it = factions.begin(); it != factions.end(); ++it ) { printf("Faction [%s]\n",(*it).c_str()); } } } printf("----------------------------------------------------------------"); } else if(folderExists(techTreeFolder) == true) { printf("\nWarning, No factions were found for the techtree located in: [%s]\n",techTreeFolder.c_str()); } } void runTechTranslationExtractionForPath(string techPath, string techName, const std::vector &filteredFactionList, World &world) { vector factionsList; findDirs(techPath + techName + "/factions/", factionsList, false, false); if(factionsList.empty() == false) { Checksum checksum; set factions; for(int j = 0; j < (int)factionsList.size(); ++j) { if( filteredFactionList.empty() == true || std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) { factions.insert(factionsList[j]); } } printf("\n----------------------------------------------------------------"); printf("\nChecking techPath [%s] techName [%s] total faction count = %d\n",techPath.c_str(), techName.c_str(),(int)factionsList.size()); for(int j = 0; j < (int)factionsList.size(); ++j) { if( filteredFactionList.empty() == true || std::find(filteredFactionList.begin(),filteredFactionList.end(),factionsList[j]) != filteredFactionList.end()) { printf("Using faction [%s]\n",factionsList[j].c_str()); } } if(factions.empty() == false) { std::map > > loadedFileList; vector pathList; pathList.push_back(techPath); Config &config = Config::getInstance(); vector otherTechPaths = config.getPathListForType(ptTechs,""); pathList.insert(pathList.end(), otherTechPaths.begin(), otherTechPaths.end()); try { world.loadTech(pathList, techName, factions, &checksum, loadedFileList, true); const TechTree *techtree = world.getTechTree(); string translationFile = techtree->getPath(); endPathWithSlash(translationFile); translationFile += "lang/" + techName + "_default.lng"; if(fileExists(translationFile) == false) { string txFilePath = extractDirectoryPathFromFile(translationFile); createDirectoryPaths(txFilePath); #if defined(WIN32) && !defined(__MINGW32__) FILE *fp = _wfopen(utf8_decode(translationFile).c_str(), L"w"); std::ofstream txFile(fp); #else std::ofstream txFile; txFile.open(translationFile.c_str(), ios_base::out | ios_base::trunc); #endif if(txFile.is_open() == true) { string _transl_TechTreeName = techName; replaceAll(_transl_TechTreeName,"_"," "); txFile << "; TechTree" << std::endl; txFile << "TechTreeName=" << _transl_TechTreeName << std::endl; txFile << "; -------------------------------------" << std::endl; txFile << "; Types of Armor" << std::endl; for(int index = 0; index < techtree->getArmorTypeCount(); ++index) { const ArmorType *at = techtree->getArmorTypeByIndex(index); string _transl_ArmorTypeName = at->getName(false); replaceAll(_transl_ArmorTypeName,"_"," "); txFile << "ArmorTypeName_" << at->getName(false) << "=" << _transl_ArmorTypeName << std::endl; } txFile << "; --------------------" << std::endl; txFile << "; Types of Attack" << std::endl; for(int index = 0; index < techtree->getAttackTypeCount(); ++index) { const AttackType *at = techtree->getAttackTypeByIndex(index); string _transl_AttackTypeName = at->getName(false); replaceAll(_transl_AttackTypeName,"_"," "); txFile << "AttackTypeName_" << at->getName(false) << "=" << _transl_AttackTypeName << std::endl; } txFile << "; --------------------" << std::endl; txFile << "; Types of Resources" << std::endl; for(int index = 0; index < techtree->getResourceTypeCount(); ++index) { const ResourceType *rt = techtree->getResourceType(index); string _transl_ResourceTypeName = rt->getName(false); replaceAll(_transl_ResourceTypeName,"_"," "); txFile << "ResourceTypeName_" << rt->getName(false) << "=" << _transl_ResourceTypeName << std::endl; } //txFile << "FactionName_" << GameConstants::OBSERVER_SLOTNAME << "=" << GameConstants::OBSERVER_SLOTNAME << std::endl; //txFile << "FactionName_" << GameConstants::RANDOMFACTION_SLOTNAME << "=" << GameConstants::RANDOMFACTION_SLOTNAME << std::endl; for(int index = 0; index < techtree->getTypeCount(); ++index) { const FactionType *ft = techtree->getType(index); string _transl_FactionName = ft->getName(false); replaceAll(_transl_FactionName,"_"," "); txFile << "; -----------------------------------------------------------------------------" << std::endl; txFile << "; Faction" << std::endl; txFile << "FactionName_" << ft->getName(false) << "=" << _transl_FactionName << std::endl; txFile << "; -------------------------------------" << std::endl; txFile << "; Types of Upgrades for this Faction" << std::endl; for(int upgradeIndex = 0; upgradeIndex < ft->getUpgradeTypeCount(); ++upgradeIndex) { const UpgradeType *upt = ft->getUpgradeType(upgradeIndex); string _transl_UpgradeTypeName = upt->getName(false); replaceAll(_transl_UpgradeTypeName,"_"," "); txFile << "UpgradeTypeName_" << upt->getName(false) << "=" << _transl_UpgradeTypeName << std::endl; } for(int unitIndex = 0; unitIndex < ft->getUnitTypeCount(); ++unitIndex) { const UnitType *ut = ft->getUnitType(unitIndex); string _transl_UnitTypeName = ut->getName(false); replaceAll(_transl_UnitTypeName,"_"," "); txFile << "; -------------------------------------" << std::endl; txFile << "; Unit" << std::endl; txFile << "UnitTypeName_" << ut->getName(false) << "=" << _transl_UnitTypeName << std::endl; txFile << "; --------------------" << std::endl; txFile << "; Levels for this Unit" << std::endl; for(int levelIndex = 0; levelIndex < ut->getLevelCount(); ++levelIndex) { const Level *level = ut->getLevel(levelIndex); string _transl_LevelName = level->getName(false); replaceAll(_transl_LevelName,"_"," "); txFile << "LevelName_" << level->getName(false) << "=" << _transl_LevelName << std::endl; } txFile << "; --------------------" << std::endl; txFile << "; Types of Commands for this Unit" << std::endl; for(int commandIndex = 0; commandIndex < ut->getCommandTypeCount(); ++commandIndex) { const CommandType *ct = ut->getCommandType(commandIndex); string _transl_CommandName = ct->getName(false); replaceAll(_transl_CommandName,"_"," "); txFile << "CommandName_" << ct->getName(false) << "=" << _transl_CommandName << std::endl; } } } txFile << "; -------------------------------------" << std::endl; } txFile.close(); #if defined(WIN32) && !defined(__MINGW32__) if(fp) { fclose(fp); } #endif } else { 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()); } } catch(const megaglest_runtime_error &ex) { printf("\n\n****ERROR**** detected while loading the techName: %s\nMESSAGE: %s\n",techName.c_str(),ex.what()); } } printf("----------------------------------------------------------------"); } } void runTechTranslationExtraction(int argc, char** argv) { printf("====== Started Translation Extraction ======\n"); Config &config = Config::getInstance(); // Did the user pass a specific list of factions to validate? std::vector filteredFactionList; vector results; findDirs(config.getPathListForType(ptTechs), results); vector techTreeFiles = results; // Did the user pass a specific list of techtrees to validate? std::vector filteredTechTreeList; if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string techtreeList = paramPartTokens[1]; Tokenize(techtreeList,filteredTechTreeList,","); if(filteredTechTreeList.empty() == false) { printf("Filtering techtrees and only looking for the following:\n"); for(int idx = 0; idx < (int)filteredTechTreeList.size(); ++idx) { filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]); printf("%s\n",filteredTechTreeList[idx].c_str()); } } } } { printf("\n---------------- Loading factions inside world ----------------"); World world; vector techPaths = config.getPathListForType(ptTechs); for(int idx = 0; idx < (int)techPaths.size(); idx++) { string &techPath = techPaths[idx]; endPathWithSlash(techPath); for(int idx2 = 0; idx2 < (int)techTreeFiles.size(); idx2++) { string &techName = techTreeFiles[idx2]; if( filteredTechTreeList.empty() == true || std::find(filteredTechTreeList.begin(),filteredTechTreeList.end(),techName) != filteredTechTreeList.end()) { runTechTranslationExtractionForPath(techPath, techName, filteredFactionList,world); } } } printf("\n====== Finished Translation ======\n"); } } void runTechValidationReport(int argc, char** argv) { printf("====== Started Validation ======\n"); bool purgeDuplicateFiles = false; bool showDuplicateFiles = true; bool purgeUnusedFiles = false; bool gitPurgeFiles = false; double purgedMegaBytes=0; Config &config = Config::getInstance(); // Did the user pass a specific scenario to validate? if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string validateScenarioName = paramPartTokens[1]; printf("Filtering scenario: %s\n",validateScenarioName.c_str()); if(paramPartTokens.size() >= 3) { if(paramPartTokens[2] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused scenario files will be deleted!\n"); } } { printf("\n---------------- Loading scenario inside world ----------------\n"); bool scenarioFound = false; World world; std::vector filteredFactionList; vector scenarioPaths = config.getPathListForType(ptScenarios); for(int idx = 0; idx < (int)scenarioPaths.size(); idx++) { string &scenarioPath = scenarioPaths[idx]; endPathWithSlash(scenarioPath); vector scenarioList; findDirs(scenarioPath, scenarioList, false, false); for(int idx2 = 0; idx2 < (int)scenarioList.size(); idx2++) { string &scenarioName = scenarioList[idx2]; if(scenarioName == validateScenarioName) { scenarioFound = true; string file = scenarioPath + scenarioName + "/" + scenarioName + ".xml"; XmlTree xmlTree; xmlTree.load(file,Properties::getTagReplacementValues()); const XmlNode *scenarioNode= xmlTree.getRootNode(); string techName = scenarioNode->getChild("tech-tree")->getAttribute("value")->getValue(); // Self Contained techtree? string scenarioTechtree = scenarioPath + scenarioName + "/" + techName + "/" + techName + ".xml"; printf("\nFound Scenario [%s] looking for techtree [%s]...\n",scenarioName.c_str(),scenarioTechtree.c_str()); if(fileExists(scenarioTechtree) == true) { string techPath = scenarioPath + scenarioName + "/"; printf("\nFound Scenario [%s] with custom techtree [%s] validating...\n",scenarioName.c_str(),techName.c_str()); runTechValidationForPath(techPath, techName, filteredFactionList, world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes); } else { vector techPaths = config.getPathListForType(ptTechs); for(int idx = 0; idx < (int)techPaths.size(); idx++) { string &techPath = techPaths[idx]; endPathWithSlash(techPath); scenarioTechtree = techPath + "/" + techName + "/" + techName + ".xml"; if(fileExists(scenarioTechtree) == true) { printf("\nFound Scenario [%s] with techtree [%s] validating...\n",scenarioName.c_str(),techName.c_str()); runTechValidationForPath(techPath, techName, filteredFactionList, world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes); break; } } } } } } if(scenarioFound == false) { printf("\nWARNING, the scenario [%s] was NOT FOUND!\n",validateScenarioName.c_str()); } printf("\n====== Finished Validation ======\n"); } return; } else { printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return; } } // Did the user pass a specific list of factions to validate? std::vector filteredFactionList; if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string factionList = paramPartTokens[1]; Tokenize(factionList,filteredFactionList,","); if(filteredFactionList.empty() == false) { printf("Filtering factions and only looking for the following:\n"); for(int idx = 0; idx < (int)filteredFactionList.size(); ++idx) { filteredFactionList[idx] = trim(filteredFactionList[idx]); printf("%s\n",filteredFactionList[idx].c_str()); } } if(paramPartTokens.size() >= 3) { if(paramPartTokens[2] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused faction files will be deleted!\n"); } } } } vector results; findDirs(config.getPathListForType(ptTechs), results); vector techTreeFiles = results; // Did the user pass a specific list of techtrees to validate? std::vector filteredTechTreeList; if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string techtreeList = paramPartTokens[1]; Tokenize(techtreeList,filteredTechTreeList,","); if(filteredTechTreeList.empty() == false) { printf("Filtering techtrees and only looking for the following:\n"); for(int idx = 0; idx < (int)filteredTechTreeList.size(); ++idx) { filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]); printf("%s\n",filteredTechTreeList[idx].c_str()); } } if(paramPartTokens.size() >= 3) { if(paramPartTokens[2] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused techtree files will be deleted!\n"); } else if(paramPartTokens[2] == "purgeduplicates") { purgeDuplicateFiles = true; printf("*NOTE All duplicate techtree files will be merged!\n"); } else if(paramPartTokens[2] == "gitdelete") { gitPurgeFiles = true; printf("*NOTE All unused / duplicate techtree files will be removed from git!\n"); } else if(paramPartTokens[2] == "hideduplicates") { showDuplicateFiles = false; printf("*NOTE All duplicate techtree files will NOT be shown!\n"); } } if(paramPartTokens.size() >= 4) { if(paramPartTokens[3] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused techtree files will be deleted!\n"); } else if(paramPartTokens[3] == "purgeduplicates") { purgeDuplicateFiles = true; printf("*NOTE All duplicate techtree files will be merged!\n"); } else if(paramPartTokens[3] == "gitdelete") { gitPurgeFiles = true; printf("*NOTE All unused / duplicate techtree files will be removed from git!\n"); } else if(paramPartTokens[3] == "hideduplicates") { showDuplicateFiles = false; printf("*NOTE All duplicate techtree files will NOT be shown!\n"); } } if(paramPartTokens.size() >= 5) { if(paramPartTokens[4] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused techtree files will be deleted!\n"); } else if(paramPartTokens[4] == "purgeduplicates") { purgeDuplicateFiles = true; printf("*NOTE All duplicate techtree files will be merged!\n"); } else if(paramPartTokens[4] == "gitdelete") { gitPurgeFiles = true; printf("*NOTE All unused / duplicate techtree files will be removed from git!\n"); } else if(paramPartTokens[4] == "hideduplicates") { showDuplicateFiles = false; printf("*NOTE All duplicate techtree files will NOT be shown!\n"); } } } } { printf("\n---------------- Loading factions inside world ----------------"); World world; vector techPaths = config.getPathListForType(ptTechs); for(int idx = 0; idx < (int)techPaths.size(); idx++) { string &techPath = techPaths[idx]; endPathWithSlash(techPath); for(int idx2 = 0; idx2 < (int)techTreeFiles.size(); idx2++) { string &techName = techTreeFiles[idx2]; if( filteredTechTreeList.empty() == true || std::find(filteredTechTreeList.begin(),filteredTechTreeList.end(),techName) != filteredTechTreeList.end()) { runTechValidationForPath(techPath, techName, filteredFactionList, world, purgeUnusedFiles,purgeDuplicateFiles, showDuplicateFiles,gitPurgeFiles,purgedMegaBytes); } } } printf("\n====== Finished Validation ======\n"); } } void runTilesetValidationReport(int argc, char** argv) { printf("====== Started Validation ======\n"); Config &config = Config::getInstance(); // Did the user pass a specific tileset to validate? if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string validateTilesetName = paramPartTokens[1]; printf("Filtering tileset: %s\n",validateTilesetName.c_str()); bool purgeUnusedFiles = false; if(paramPartTokens.size() >= 3) { if(paramPartTokens[2] == "purgeunused") { purgeUnusedFiles = true; printf("*NOTE All unused tileset files will be deleted!\n"); } } { printf("\n---------------- Loading tileset inside world ----------------\n"); World world; double purgedMegaBytes=0; bool showDuplicateFiles = true; bool tilesetFound = false; vector tilesetPaths = config.getPathListForType(ptTilesets); for(int idx = 0; idx < (int)tilesetPaths.size(); idx++) { string &tilesetPath = tilesetPaths[idx]; endPathWithSlash(tilesetPath); vector tilesetList; findDirs(tilesetPath, tilesetList, false, false); for(int idx2 = 0; idx2 < (int)tilesetList.size(); idx2++) { string &tilesetName = tilesetList[idx2]; if(tilesetName == validateTilesetName) { tilesetFound = true; runTilesetValidationForPath(tilesetPath, tilesetName, world, purgeUnusedFiles, showDuplicateFiles, false, false, purgedMegaBytes); } } } if(tilesetFound == false) { printf("*ERROR The specified tileset [%s] was NOT FOUND!\n",validateTilesetName.c_str()); } printf("\n====== Finished Validation ======\n"); } return; } else { printf("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return; } } else { printf("\nInvalid missing tileset specified on commandline\n\n"); return; } } void ShowINISettings(int argc, char **argv,Config &config,Config &configKeys) { if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) { vector filteredPropertyList; if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("=")) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("="),&foundParamIndIndex); string filterList = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(filterList,paramPartTokens,"="); if(paramPartTokens.size() >= 2) { string tokenList = paramPartTokens[1]; Tokenize(tokenList,filteredPropertyList,","); if(filteredPropertyList.empty() == false) { printf("Filtering properties and only looking for the following:\n"); for(int idx = 0; idx < (int)filteredPropertyList.size(); ++idx) { filteredPropertyList[idx] = trim(filteredPropertyList[idx]); printf("%s\n",filteredPropertyList[idx].c_str()); } } } } printf("\nMain settings report\n"); printf("====================\n"); vector > mergedMainSettings = config.getMergedProperties(); vector > mergedKeySettings = configKeys.getMergedProperties(); // Figure out the max # of tabs we need to format display nicely int tabCount = 1; for(int i = 0; i < (int)mergedMainSettings.size(); ++i) { const pair &nameValue = mergedMainSettings[i]; bool displayProperty = false; if(filteredPropertyList.empty() == false) { if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) { displayProperty = true; } } else { displayProperty = true; } if(displayProperty == true) { int requredTabs = ((int)nameValue.first.length() / 8)+1; if(nameValue.first.length() % 8) { requredTabs++; } if(requredTabs > tabCount) { tabCount = requredTabs; } } } for(int i = 0; i < (int)mergedKeySettings.size(); ++i) { const pair &nameValue = mergedKeySettings[i]; bool displayProperty = false; if(filteredPropertyList.empty() == false) { if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) { displayProperty = true; } } else { displayProperty = true; } if(displayProperty == true) { int requredTabs = ((int)nameValue.first.length() / 8)+1; if(nameValue.first.length() % 8) { requredTabs++; } if(requredTabs > tabCount) { tabCount = requredTabs; } } } // Output the properties for(int i = 0; i < (int)mergedMainSettings.size(); ++i) { const pair &nameValue = mergedMainSettings[i]; bool displayProperty = false; if(filteredPropertyList.empty() == false) { if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) { displayProperty = true; } } else { displayProperty = true; } if(displayProperty == true) { printf("Property Name [%s]",nameValue.first.c_str()); int tabs = ((int)nameValue.first.length() / 8) + 1; for(int j = 0; j < (tabCount - tabs); ++j) { printf("\t"); } string displayValue = nameValue.second; if(nameValue.first == "TranslationGetURLPassword") { displayValue = "*****"; } printf("Value [%s]\n",displayValue.c_str()); } } printf("\n\nMain key binding settings report\n"); printf("====================================\n"); for(int i = 0; i < (int)mergedKeySettings.size(); ++i) { const pair &nameValue = mergedKeySettings[i]; bool displayProperty = false; if(filteredPropertyList.empty() == false) { if(find(filteredPropertyList.begin(),filteredPropertyList.end(),nameValue.first) != filteredPropertyList.end()) { displayProperty = true; } } else { displayProperty = true; } if(displayProperty == true) { printf("Property Name [%s]",nameValue.first.c_str()); int tabs = ((int)nameValue.first.length() / 8) + 1; for(int j = 0; j < (tabCount - tabs); ++j) { printf("\t"); } printf("Value [%s]\n",nameValue.second.c_str()); } } } } Steam & initSteamInstance() { Steam *&steamInstance = CacheManager::getCachedItem< Steam *>(GameConstants::steamCacheInstanceKey); if(steamInstance == NULL) { steamInstance = new Steam(); } return *steamInstance; } void setupSteamSettings(bool steamEnabled, bool steamResetStats, bool debugEnabled) { Config &config = Config::getInstance(); config.setBool("SteamEnabled",steamEnabled,true); if(steamEnabled) { printf("*NOTE: Steam Integration Enabled.\n"); if(debugEnabled) { printf("*NOTE: Steam Debugging Enabled.\n"); } Steam::setDebugEnabled(debugEnabled); Steam &steam = initSteamInstance(); // For Debugging purposes: if(steamResetStats) { printf("*WARNING: Steam Stats / Achievements are being RESET by request!\n"); steam.resetStats(true); } string steamPlayerName = steam.userName(); string steamLang = steam.lang(); printf("Steam Integration Enabled!\nSteam User Name is [%s] Language is [%s]\n", steamPlayerName.c_str(), steamLang.c_str()); bool needToSaveConfig=false; string currentPLayerName = config.getString("NetPlayerName",""); if( currentPLayerName == "newbie" || currentPLayerName == "" ) { config.setString("NetPlayerName",steamPlayerName); needToSaveConfig=true; } if( needToSaveConfig == true ) { config.save(); } } } void CheckForDuplicateData() { Config &config = Config::getInstance(); string duplicateWarnings=""; try { { string scenarioDir = ""; vector pathList = config.getPathListForType(ptMaps,scenarioDir); vector invalidMapList; vector maps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList); std::sort(maps.begin(),maps.end()); if(maps.empty() == true) { throw megaglest_runtime_error("No maps were found!",true); } else if(invalidMapList.empty() == false) { string errorMsg = "Warning invalid maps were detected (will be ignored):\n"; for(int i = 0; i < (int)invalidMapList.size(); ++i) { char szBuf[8096]=""; snprintf(szBuf,8096,"map [%s]\n",invalidMapList[i].c_str()); errorMsg += szBuf; } duplicateWarnings += errorMsg; } vector duplicateMapsToRename; for(int i = 0; i < (int)maps.size(); ++i) { string map1 = maps[i]; for(int j = 0; j < (int)maps.size(); ++j) { if(i != j) { string map2 = maps[j]; if(map1 == map2) { if(std::find(duplicateMapsToRename.begin(),duplicateMapsToRename.end(),map1) == duplicateMapsToRename.end()) { duplicateMapsToRename.push_back(map1); } } } } } if(duplicateMapsToRename.empty() == false) { string errorMsg = "Warning duplicate maps were detected and renamed:\n"; for(int i = 0; i < (int)duplicateMapsToRename.size(); ++i) { string currentPath = pathList[1]; endPathWithSlash(currentPath); string oldFile = currentPath + duplicateMapsToRename[i]; string newFile = currentPath + duplicateMapsToRename[i]; string ext = extractExtension(newFile); newFile = newFile.substr( 0, newFile.length()-ext.length()-1); newFile = newFile + "_custom." + ext; char szBuf[8096]=""; int result = rename(oldFile.c_str(),newFile.c_str()); if(result != 0) { char *errmsg = strerror(errno); snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str()); throw megaglest_runtime_error(szBuf,true); } else { snprintf(szBuf,8096,"map [%s] in [%s]\nwas renamed to [%s]",duplicateMapsToRename[i].c_str(),oldFile.c_str(),newFile.c_str()); } errorMsg += szBuf; } duplicateWarnings += errorMsg; } } { //tilesets std::vector tileSets; vector tilesetPaths = config.getPathListForType(ptTilesets); findDirs(tilesetPaths, tileSets, false, true); if (tileSets.empty()) { throw megaglest_runtime_error("No tilesets were found!",true); } vector duplicateTilesetsToRename; for(int i = 0; i < (int)tileSets.size(); ++i) { string tileSet1 = tileSets[i]; for(int j = 0; j < (int)tileSets.size(); ++j) { if(i != j) { string tileSet2= tileSets[j]; if(tileSet1 == tileSet2) { if(std::find(duplicateTilesetsToRename.begin(),duplicateTilesetsToRename.end(),tileSet1) == duplicateTilesetsToRename.end()) { duplicateTilesetsToRename.push_back(tileSet1); } } } } } if(duplicateTilesetsToRename.empty() == false) { string errorMsg = "Warning duplicate tilesets were detected and renamed:\n"; for(int i = 0; i < (int)duplicateTilesetsToRename.size(); ++i) { string currentPath = tilesetPaths[1]; endPathWithSlash(currentPath); string oldFile = currentPath + duplicateTilesetsToRename[i]; string newFile = currentPath + duplicateTilesetsToRename[i]; newFile = newFile + "_custom"; char szBuf[8096]=""; int result = rename(oldFile.c_str(),newFile.c_str()); if(result != 0) { char *errmsg = strerror(errno); snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str()); throw megaglest_runtime_error(szBuf,true); } else { snprintf(szBuf,8096,"tileset [%s] in [%s]\nwas renamed to [%s]",duplicateTilesetsToRename[i].c_str(),oldFile.c_str(),newFile.c_str()); string tilesetName = extractFileFromDirectoryPath(oldFile); oldFile = newFile + "/" + tilesetName + ".xml"; newFile = newFile + "/" + tilesetName + "_custom.xml"; result = rename(oldFile.c_str(),newFile.c_str()); if(result != 0) { char *errmsg = strerror(errno); snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str()); throw megaglest_runtime_error(szBuf,true); } } errorMsg += szBuf; } duplicateWarnings += errorMsg; } } { vector techPaths = config.getPathListForType(ptTechs); vector techTrees; findDirs(techPaths, techTrees, false, true); if(techTrees.empty()) { throw megaglest_runtime_error("No tech-trees were found (dup)!",true); } vector duplicateTechtreesToRename; for(int i = 0; i < (int)techTrees.size(); ++i) { string techtree1 = techTrees[i]; for(int j = 0; j < (int)techTrees.size(); ++j) { if(i != j) { string techtree2 = techTrees[j]; if(techtree1 == techtree2) { if(std::find(duplicateTechtreesToRename.begin(),duplicateTechtreesToRename.end(),techtree1) == duplicateTechtreesToRename.end()) { duplicateTechtreesToRename.push_back(techtree1); } } } } } if(duplicateTechtreesToRename.empty() == false) { string errorMsg = "Warning duplicate techtrees were detected and renamed:\n"; for(int i = 0; i < (int)duplicateTechtreesToRename.size(); ++i) { string currentPath = techPaths[1]; endPathWithSlash(currentPath); string oldFile = currentPath + duplicateTechtreesToRename[i]; string newFile = currentPath + duplicateTechtreesToRename[i]; newFile = newFile + "_custom"; char szBuf[8096]=""; int result = rename(oldFile.c_str(),newFile.c_str()); if(result != 0) { char *errmsg = strerror(errno); snprintf(szBuf,8096,"Error [%s]\nCould not rename [%s] to [%s]!",errmsg,oldFile.c_str(),newFile.c_str()); throw megaglest_runtime_error(szBuf,true); } else { snprintf(szBuf,8096,"techtree [%s] in [%s]\nwas renamed to [%s]",duplicateTechtreesToRename[i].c_str(),oldFile.c_str(),newFile.c_str()); string tilesetName = extractFileFromDirectoryPath(oldFile); oldFile = newFile + "/" + tilesetName + ".xml"; newFile = newFile + "/" + tilesetName + "_custom.xml"; int rename_result = rename(oldFile.c_str(),newFile.c_str()); if(rename_result != 0) { printf("Error renaming [%s] to [%s]\n",oldFile.c_str(),newFile.c_str()); } } errorMsg += szBuf; } duplicateWarnings += errorMsg; } } } catch(const megaglest_runtime_error &ex) { if(mainProgram) { mainProgram->getState()->setForceMouseRender(true); } ExceptionHandler::DisplayMessage(ex.what(), false); } if(duplicateWarnings != "") { if(mainProgram) { mainProgram->getState()->setForceMouseRender(true); } ExceptionHandler::DisplayMessage(duplicateWarnings.c_str(), false); } } int handleCreateDataArchivesCommand(int argc, char** argv) { int return_value = 1; if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string compress_item = paramPartTokens[1]; bool includeMainData = false; if(paramPartTokens.size() >= 3 && paramPartTokens[2] == "include_main") { includeMainData = true; } Config &config = Config::getInstance(); string fileArchiveExtension = config.getString("FileArchiveExtension",""); string fileArchiveCompressCommand = config.getString("FileArchiveCompressCommand",""); string fileArchiveCompressCommandParameters = config.getString("FileArchiveCompressCommandParameters",""); int32 fileArchiveCompressCommandSuccessResult = config.getInt("FileArchiveCompressCommandSuccessResult","0"); string userData = config.getString("UserData_Root",""); if(userData != "") { endPathWithSlash(userData); } int typesSelected = 0; if(compress_item == "techtrees" || compress_item == "all") { typesSelected++; vector pathList = config.getPathListForType(ptTechs,""); vector results; findDirs(pathList, results); printf("Techtrees found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; for(unsigned int j = 0; j < pathList.size(); ++j) { string techPath = pathList[j]; if(techPath != "") { endPathWithSlash(techPath); } vector results2; findDirs(techPath + name + "/factions", results2, false,true); if(results2.empty() == false) { string techtreePath = techPath + name; if(includeMainData == false) { if(techtreePath.find(userData) == techPath.npos) { printf("Skipping techtree: [%s]\n",techtreePath.c_str()); continue; } } string downloadArchive = techtreePath + fileArchiveExtension; if(fileExists(downloadArchive) == true) { bool removed = removeFile(downloadArchive); if(removed == false) { printf("Error could not remove old file: [%s]\n",downloadArchive.c_str()); } } string compressCmd = getFullFileArchiveCompressCommand( fileArchiveCompressCommand, fileArchiveCompressCommandParameters, downloadArchive,techtreePath ); printf("Running compression command: %s\n",compressCmd.c_str()); if(executeShellCommand(compressCmd,fileArchiveCompressCommandSuccessResult) == false) { printf("Error could not create new file: [%s]\n",downloadArchive.c_str()); } if(fileExists(downloadArchive) == true) { off_t fileSize = getFileSize(downloadArchive); // convert to MB double megaBytes = ((double)fileSize / 1048576.0); printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes); } } } } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size()); } if(compress_item == "tilesets" || compress_item == "all") { typesSelected++; vector pathList = config.getPathListForType(ptTilesets,""); vector results; findDirs(pathList, results); printf("Tilesets found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; for(unsigned int j = 0; j < pathList.size(); ++j) { string tilesetPath = pathList[j]; if(tilesetPath != "") { endPathWithSlash(tilesetPath); } if(fileExists(tilesetPath + name + "/" + name + ".xml") == true) { string tilesetDataPath = tilesetPath + name; if(includeMainData == false) { if(tilesetPath.find(userData) == tilesetPath.npos) { printf("Skipping tileset data: [%s]\n",tilesetDataPath.c_str()); continue; } } string downloadArchive = tilesetDataPath + fileArchiveExtension; if(fileExists(downloadArchive) == true) { bool removed = removeFile(downloadArchive); if(removed == false) { printf("Error could not remove old file: [%s]\n",downloadArchive.c_str()); } } string compressCmd = getFullFileArchiveCompressCommand( fileArchiveCompressCommand, fileArchiveCompressCommandParameters, downloadArchive,tilesetDataPath ); printf("Running compression command: %s\n",compressCmd.c_str()); if(executeShellCommand(compressCmd,fileArchiveCompressCommandSuccessResult) == false) { printf("Error could not create new file: [%s]\n",downloadArchive.c_str()); } if(fileExists(downloadArchive) == true) { off_t fileSize = getFileSize(downloadArchive); // convert to MB double megaBytes = ((double)fileSize / 1048576.0); printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes); } break; } } } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size()); } if(typesSelected == 0) { printf("Compress item [%s] is not valid!\n",compress_item.c_str()); return_value = 1; } else return_value = 0; } else { printf("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return_value = 1; } } return return_value; } int handleShowCRCValuesCommand(int argc, char** argv) { int return_value = 1; if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemName = paramPartTokens[1]; string file = Config::getMapPath(itemName,"",false); if(file != "") { Checksum checksum; checksum.addFile(file); uint32 crcValue = checksum.getSum(); printf("CRC value for map [%s] file [%s] is [%u]\n",itemName.c_str(),file.c_str(),crcValue); return_value = 0; } else { printf("Map [%s] was NOT FOUND\n",itemName.c_str()); return_value = 1; } } else { printf("\nInvalid missing map specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return_value = 1; } } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemName = paramPartTokens[1]; Config &config = Config::getInstance(); uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,""), string("/") + itemName + string("/*"), ".xml", NULL, true); if(crcValue != 0) { printf("CRC value for tileset [%s] is [%u]\n",itemName.c_str(),crcValue); return_value = 0; } else { printf("Tileset [%s] was NOT FOUND\n",itemName.c_str()); return_value = 1; } } else { printf("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return_value = 1; } } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemName = paramPartTokens[1]; Config &config = Config::getInstance(); uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + itemName + "/*", ".xml", NULL, true); if(crcValue != 0) { printf("CRC value for techtree [%s] is [%u]\n",itemName.c_str(),crcValue); return_value = 0; } else { printf("Techtree [%s] was NOT FOUND\n",itemName.c_str()); return_value = 1; } } else { printf("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return_value = 1; } } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemName = paramPartTokens[1]; Config &config = Config::getInstance(); uint32 crcValue = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptScenarios,""), "/" + itemName + "/*", ".xml", NULL, true); if(crcValue != 0) { printf("CRC value for scenario [%s] is [%u]\n",itemName.c_str(),crcValue); return_value = 0; } else { printf("Scenario [%s] was NOT FOUND\n",itemName.c_str()); return_value = 1; } } else { printf("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return_value = 0; } } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) { string itemName = paramPartTokens[1]; string itemNameFilter = paramPartTokens[2]; uint32 crcValue = getFolderTreeContentsCheckSumRecursively(itemName, itemNameFilter, NULL, true); printf("CRC value for path [%s] filter [%s] is [%u]\n",itemName.c_str(),itemNameFilter.c_str(),crcValue); return_value = 0; } else { if(paramPartTokens.size() < 2) { printf("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); } if(paramPartTokens.size() < 3) { printf("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 3 ? paramPartTokens[2].c_str() : NULL)); } return_value = 1; } } return return_value; } int handleListDataCommand(int argc, char** argv) { int return_value = 1; if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_MAPS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_MAPS]),&foundParamIndIndex); } Config &config = Config::getInstance(); vector pathList = config.getPathListForType(ptMaps,""); vector maps = MapPreview::findAllValidMaps(pathList,"",false,true); std::sort(maps.begin(),maps.end()); string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemNameFilter = paramPartTokens[1]; printf("Using filter for maps list [%s]\n",itemNameFilter.c_str()); vector filteredMaps; for(unsigned int i = 0; i < maps.size(); ++i) { string mapName = maps[i]; if(itemNameFilter.find("*") != itemNameFilter.npos) { if(StartsWith(mapName, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) { filteredMaps.push_back(mapName); } } else if(mapName == itemNameFilter) { filteredMaps.push_back(mapName); } } maps = filteredMaps; } printf("Maps found:\n===========================================\n"); for(unsigned int i = 0; i < maps.size(); ++i) { string mapName = maps[i]; printf("%s\n",mapName.c_str()); } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",maps.size()); return_value = 0; } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]),&foundParamIndIndex); } Config &config = Config::getInstance(); vector pathList = config.getPathListForType(ptTechs,""); vector results; findDirs(pathList, results); bool showfactions=false; string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string cmd = paramPartTokens[1]; if(cmd == "showfactions") { showfactions = true; } else { throw megaglest_runtime_error("unknown command for techtreelist [" + cmd + "]"); } printf("Using special command for techtree list [%s]\n",cmd.c_str()); } printf("Techtrees found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; for(unsigned int j = 0; j < pathList.size(); ++j) { string techPath = pathList[j]; if(techPath != "") { endPathWithSlash(techPath); } vector results2; findDirs(techPath + name + "/factions", results2, false,true); if(results2.empty() == false) { string downloadArchive = techPath + name + ".7z"; if(fileExists(downloadArchive) == true) { off_t fileSize = getFileSize(downloadArchive); // convert to MB double megaBytes = ((double)fileSize / 1048576.0); printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes); } else { printf("%s\n",name.c_str()); } if(showfactions == true) { printf("--> Factions:\n"); for(unsigned int k = 0; k < results2.size(); ++k) { string name2 = results2[k]; printf("--> %s\n",name2.c_str()); } printf("--> Total Factions: " MG_SIZE_T_SPECIFIER "\n",results2.size()); break; } } } } printf("===========================================\nTotal Techtrees: " MG_SIZE_T_SPECIFIER "\n",results.size()); return_value = 0; } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]),&foundParamIndIndex); } Config &config = Config::getInstance(); vector pathList = config.getPathListForType(ptScenarios,""); vector results; findDirs(pathList, results); string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemNameFilter = paramPartTokens[1]; printf("Using filter for scenarios list [%s]\n",itemNameFilter.c_str()); vector filtered; for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; if(itemNameFilter.find("*") != itemNameFilter.npos) { if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) { filtered.push_back(name); } } else if(name == itemNameFilter) { filtered.push_back(name); } } results = filtered; } printf("Scenarios found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; printf("%s\n",name.c_str()); } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size()); return_value = 0; } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TILESETS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TILESETS]),&foundParamIndIndex); } Config &config = Config::getInstance(); vector pathList = config.getPathListForType(ptTilesets,""); vector results; findDirs(pathList, results); string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemNameFilter = paramPartTokens[1]; printf("Using filter for tilesets list [%s]\n",itemNameFilter.c_str()); vector filtered; for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; if(itemNameFilter.find("*") != itemNameFilter.npos) { if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) { filtered.push_back(name); } } else if(name == itemNameFilter) { filtered.push_back(name); } } results = filtered; } printf("Tilesets found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; for(unsigned int j = 0; j < pathList.size(); ++j) { string tilesetPath = pathList[j]; if(tilesetPath != "") { endPathWithSlash(tilesetPath); } if(fileExists(tilesetPath + name + "/" + name + ".xml") == true) { string downloadArchive = tilesetPath + name + ".7z"; if(fileExists(downloadArchive) == true) { off_t fileSize = getFileSize(downloadArchive); // convert to MB double megaBytes = ((double)fileSize / 1048576.0); printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes); } else { printf("%s\n",name.c_str()); } break; } } } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size()); return_value = 0; } else if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]),&foundParamIndIndex); } Config &config = Config::getInstance(); vector pathList = config.getPathListForType(ptTutorials,""); vector results; findDirs(pathList, results); string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string itemNameFilter = paramPartTokens[1]; printf("Using filter for tutorials list [%s]\n",itemNameFilter.c_str()); vector filtered; for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; if(itemNameFilter.find("*") != itemNameFilter.npos) { if(StartsWith(name, itemNameFilter.substr(0,itemNameFilter.find("*"))) == true) { filtered.push_back(name); } } else if(name == itemNameFilter) { filtered.push_back(name); } } results = filtered; } printf("Tutorials found:\n===========================================\n"); for(unsigned int i = 0; i < results.size(); ++i) { string name = results[i]; for(unsigned int j = 0; j < pathList.size(); ++j) { string tutorialsPath = pathList[j]; if(tutorialsPath != "") { endPathWithSlash(tutorialsPath); } if(fileExists(tutorialsPath + name + "/" + name + ".xml") == true) { string downloadArchive = tutorialsPath + name + ".7z"; if(fileExists(downloadArchive) == true) { off_t fileSize = getFileSize(downloadArchive); // convert to MB double megaBytes = ((double)fileSize / 1048576.0); printf("%s [download archive %.2fMB]\n",name.c_str(),megaBytes); } else { printf("%s\n",name.c_str()); } break; } } } printf("===========================================\nTotal: " MG_SIZE_T_SPECIFIER "\n",results.size()); return_value = 0; } return return_value; } int glestMain(int argc, char** argv) { #ifdef SL_LEAK_DUMP //AllocInfo::set_application_binary(executable_path(argv[0],true)); string &app = AllocInfo::get_application_binary(); app = executable_path(argv[0],true); //want_full_leak_stacktrace = true; //want_full_leak_stacktrace_line_numbers = true; #endif Thread::setMainThreadId(); // printf("START ALLOC char 200\n"); //char *ptr = new char[200]; // printf("END ALLOC char 200\n"); // return -1; SystemFlags::VERBOSE_MODE_ENABLED = false; if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == true) { SystemFlags::VERBOSE_MODE_ENABLED = true; Thread::setEnableVerboseMode(true); //LuaScript::setDebugModeEnabled(true); } // DEbug testing threads //Thread::setEnableVerboseMode(true); PlatformExceptionHandler::application_binary= executable_path(argv[0],true); mg_app_name = GameConstants::application_name; mailStringSupport = mailString; SystemFlags::ENABLE_THREADED_LOGGING = false; disableBacktrace = false; bool foundInvalidArgs = false; preCacheThread=NULL; Properties::setApplicationPath(executable_path(argv[0])); Properties::setApplicationDataPath(executable_path(argv[0])); Properties::setGameVersion(glestVersionString); ServerSocket::setMaxPlayerCount(GameConstants::maxPlayers); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true) { disableBacktrace = true; } PlatformExceptionHandler::disableBacktrace= disableBacktrace; #if defined(CUSTOM_DATA_INSTALL_PATH) if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n",formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)).c_str()); #endif const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); for(int idx = 1; idx < argc; ++idx) { if( hasCommandArgument(knownArgCount, (char **)&GAME_ARGS[0], argv[idx], NULL, 0, true) == false) { foundInvalidArgs = true; printf("\nInvalid argument: %s",argv[idx]); } } if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_HELP]) == true || foundInvalidArgs == true) { printParameterHelp(argv[0],foundInvalidArgs); return 2; } if( hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { //isMasterServerModeEnabled = true; //Window::setMasterserverMode(isMasterServerModeEnabled); GlobalStaticFlags::setIsNonGraphicalModeEnabled(true); int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string headless_command_list = paramPartTokens[1]; vector paramHeadlessCommandList; Tokenize(headless_command_list,paramHeadlessCommandList,","); for(unsigned int i = 0; i < paramHeadlessCommandList.size(); ++i) { string headless_command = paramHeadlessCommandList[i]; if(headless_command == "exit") { printf("Forcing quit after game has completed [%s]\n",headless_command.c_str()); Program::setWantShutdownApplicationAfterGame(true); } else if(headless_command == "vps") { printf("Disabled reading from console [%s]\n",headless_command.c_str()); disableheadless_console = true; } else if(headless_command == "lan") { printf("Forcing local LAN mode [%s]\n",headless_command.c_str()); GlobalStaticFlags::setFlag(gsft_lan_mode); } } } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SERVER_TITLE]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SERVER_TITLE]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SERVER_TITLE]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { Config &config = Config::getInstance(); string serverTitle = paramPartTokens[1]; printf("Forcing serverTitle[%s]\n",serverTitle.c_str()); config.setString("ServerTitle",serverTitle,true); } else { printf("\nInvalid missing server title specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } //#ifdef WIN32 //SocketManager winSockManager; //#endif bool haveSpecialOutputCommandLineOption = false; if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { haveSpecialOutputCommandLineOption = true; } if( haveSpecialOutputCommandLineOption == false || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true) { printf("%s %s",extractFileFromDirectoryPath(argv[0]).c_str(),getNetworkPlatformFreeVersionString().c_str()); // 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")); printf("\nCompiled using: %s platform: %s endianness: %s",getCompilerNameString().c_str(),getPlatformNameString().c_str(),(::Shared::PlatformByteOrder::isBigEndian() == true ? "big" : "little")); // 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)); // // Config::getInstance().setBool("DebugNetworkPackets",true,true); // NetworkMessageIntro data(424336, "mg_version_x","player_x", 3, nmgstOk,444444, 555555, "english"); // unsigned char *buf = data.packMessage(); // printf("\nSend packet size = %u\n%s\n",data.getPackedSize(),data.toString().c_str()); // data.dump_packet("Send data", buf, data.getPackedSize()); // //delete [] buf; // // NetworkMessageIntro data2; // data2.unpackMessage(buf); // printf("\nReceive packet size = %u\n%s\n",data2.getPackedSize(),data2.toString().c_str()); // data2.dump_packet("nReceive data", buf, data2.getPackedSize()); // delete [] buf; // SwitchSetupRequest data("factionname", 3,-1,2,"softcoder",10, 11,"eng"); // // unsigned char *buf = data.packMessage(); // 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()); // //delete [] buf; // // data.unpackMessage(buf); // 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()); // delete [] buf; // int8 a = 1; // uint8 b = 2; // int16 c = 3; // uint16 d = 4; // int32 e = 5; // uint32 f = 6; // // printf("\nPack test #1: [%d][%u][%d][%u][%d][%u]\n,",a,b,c,d,e,f); // // unsigned char *buf = new unsigned char[100]; // unsigned int packedsize = pack(buf, "cChHlL", // a, // b, // c, // d, // e, // f); // // printf("Pack test #2: [%u][%s]\n,",packedsize,buf); // // int8 a1 = 0; // uint8 b1 = 0; // int16 c1 = 0; // uint16 d1 = 0; // int32 e1 = 0; // uint32 f1 = 0; // // unpack(buf, "cChHlL", // &a1, // &b1, // &c1, // &d1, // &e1, // &f1); // // printf("UnPack test #3: [%d][%u][%d][%u][%d][%u]\n,",a1,b1,c1,d1,e1,f1); if(SystemFlags::VERBOSE_MODE_ENABLED == true) { int8 testVar = 111; printf("\nEndian value = %d",testVar); testVar = ::Shared::PlatformByteOrder::toCommonEndian(testVar); printf("\nEndian to common value = %d",testVar); testVar = ::Shared::PlatformByteOrder::fromCommonEndian(testVar); printf("\nEndian from common value = %d",testVar); printf("\nint8 sizeof = " MG_SIZE_T_SPECIFIER "",sizeof(int8)); printf("\nSwitchSetupRequest sizeof = " MG_SIZE_T_SPECIFIER "",SwitchSetupRequest().getDataSize()); } printf("\nGIT: [%s]",getGITRevisionString().c_str()); #ifdef USE_STREFLOP #if defined(STREFLOP_SSE) const char *instruction_set = "[SSE]"; #elif defined(STREFLOP_X87) const char *instruction_set = "[X87]"; #elif defined(STREFLOP_SOFT) const char *instruction_set = "[SOFTFLOAT]"; #else const char *instruction_set = "[none]"; #endif #if defined(STREFLOP_NO_DENORMALS) const char *denormals = "[no-denormals]"; #else const char *denormals = "[denormals]"; #endif printf(" - using STREFLOP %s - %s\n",instruction_set,denormals); #else printf("\n"); #endif } setGameVersion(glestVersionString); setGameGITVersion(getRAWGITRevisionString()); #ifdef WIN32 CheckPacketThrottling(); #endif if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { VideoPlayer::setDisabled(true); } //throw megaglest_runtime_error("Test!"); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true) { SDL_version ver; // Prints the compile time version SDL_VERSION(&ver); print_SDL_version("SDL compile-time version", &ver); // Prints the run-time version SDL_GetVersion(&ver); print_SDL_version("SDL runtime version", &ver); //const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo(); //printf("Video card Memory: %u\n",vidInfo->video_mem); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true) { printf("LUA version: %s\n", LUA_RELEASE); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true) { curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW); 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)); if(curlVersion->protocols != NULL && curlVersion->protocols[0] != NULL) { printf("protocols: "); for(unsigned int i = 0; curlVersion->protocols != NULL && curlVersion->protocols[i] != NULL; ++i) { printf("%s ", curlVersion->protocols[i]); if(i > 0 && i % 10 == 0) { printf("\n "); } } printf("\n"); } } #if defined(WANT_XERCES) if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) { printf("XERCES version: %s\n", XERCES_FULLVERSIONDOT); } #endif if( (hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == false && hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == false) { return 0; } if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD])) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MOD]),&foundParamIndIndex); } string scenarioName = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(scenarioName,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string autoloadModName = paramPartTokens[1]; if(Properties::applyTagsToValue(autoloadModName) == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s]\n",Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName.c_str()); } Config::setCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME,autoloadModName); printf("Setting mod active [%s]\n",autoloadModName.c_str()); } else { printf("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); return 1; } } SystemFlags::init(haveSpecialOutputCommandLineOption); //SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true; //SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true; MainWindow *mainWindow= NULL; Program *program= NULL; ExceptionHandler exceptionHandler; exceptionHandler.install( getCrashDumpFileName() ); int shutdownFadeSoundMilliseconds = 1000; Chrono chronoshutdownFadeSound; SimpleTaskThread *soundThreadManager = NULL; try { // Setup paths to game items (like data, logs, ini etc) int setupResult = setupGameItemPaths(argc, argv, NULL); if(setupResult != 0) { return setupResult; } // Attempt to read ini files Config &config = Config::getInstance(); setupGameItemPaths(argc, argv, &config); setupSteamSettings(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_STEAM]), hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_STEAM_RESET_STATS]), hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_STEAM_DEBUG])); if(config.getString("PlayerId","") == "") { char uuid_str[38]; get_uuid_string(uuid_str,sizeof(uuid_str)); config.setString("PlayerId",uuid_str); config.save(); } //printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str()); if(config.getBool("DisableLuaSandbox","false") == true) { LuaScript::setDisableSandbox(true); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKETS]) == true) { printf("*NOTE: debugging network packets.\n"); config.setBool("DebugNetworkPackets",true,true); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_SIZES]) == true) { printf("*NOTE: debugging network packet SIZES.\n"); config.setBool("DebugNetworkPacketSizes",true,true); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_STATS]) == true) { printf("*NOTE: debugging network packet STATISTICS.\n"); config.setBool("DebugNetworkPacketStats",true,true); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_ENABLE_NEW_PROTOCOL]) == true) { printf("*NOTE: enabling new network protocol.\n"); NetworkMessage::useOldProtocol = false; } Socket::setBroadCastPort(config.getInt("BroadcastPort",intToStr(Socket::getBroadCastPort()).c_str())); Socket::disableNagle = config.getBool("DisableNagle","false"); if(Socket::disableNagle) { printf("*WARNING users wants to disable the socket nagle algorithm.\n"); } Socket::DEFAULT_SOCKET_SENDBUF_SIZE = config.getInt("DefaultSocketSendBufferSize",intToStr(Socket::DEFAULT_SOCKET_SENDBUF_SIZE).c_str()); if(Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) { printf("*WARNING users wants to set default socket send buffer size to: %d\n",Socket::DEFAULT_SOCKET_SENDBUF_SIZE); } Socket::DEFAULT_SOCKET_RECVBUF_SIZE = config.getInt("DefaultSocketReceiveBufferSize",intToStr(Socket::DEFAULT_SOCKET_RECVBUF_SIZE).c_str()); if(Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) { printf("*WARNING users wants to set default socket receive buffer size to: %d\n",Socket::DEFAULT_SOCKET_RECVBUF_SIZE); } shutdownFadeSoundMilliseconds = config.getInt("ShutdownFadeSoundMilliseconds",intToStr(shutdownFadeSoundMilliseconds).c_str()); string userData = config.getString("UserData_Root",""); if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { userData = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); } if(userData != "") { endPathWithSlash(userData); } string data_path_check = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); string userDataPath_check = getGameCustomCoreDataPath(data_path_check, ""); if(data_path_check == userDataPath_check) { printf("****WARNING**** your game data path and user data path are the same.\nThis will likely create problems: %s\n",data_path_check.c_str()); throw megaglest_runtime_error("Regular and User data paths cannot have the same value [" + userDataPath_check + "]"); } if(userData != "") { if(isdir(userData.c_str()) == false) { createDirectoryPaths(userData); } } string crcCachePath = userData + "cache/"; if(isdir(crcCachePath.c_str()) == false) { createDirectoryPaths(crcCachePath); } setCRCCacheFilePath(crcCachePath); string savedGamePath = userData + "saved/"; if(isdir(savedGamePath.c_str()) == false) { createDirectoryPaths(savedGamePath); } string tempDataPath = userData + "temp/"; tempDataLocation = tempDataPath; if(isdir(tempDataPath.c_str()) == true) { removeFolder(tempDataPath); } createDirectoryPaths(tempDataPath); string binaryNameOld = Properties::getApplicationPath() + extractFileFromDirectoryPath(PlatformExceptionHandler::application_binary) + "__REMOVE"; if(fileExists(binaryNameOld)) { removeFile(binaryNameOld); } string netInterfaces = config.getString("NetworkInterfaces",""); if(netInterfaces != "") { //printf("Using network interfaces: %s\n",netInterfaces.c_str()); std::vector intfList; Tokenize(netInterfaces,intfList,","); Socket::setIntfTypes(intfList); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_PORTS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_PORTS]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string portsToUse = paramPartTokens[1]; vector paramPartPortsTokens; Tokenize(portsToUse,paramPartPortsTokens,","); if(paramPartPortsTokens.size() >= 2 && paramPartPortsTokens[1].length() > 0) { int internalPort = strToInt(paramPartPortsTokens[0]); int externalPort = strToInt(paramPartPortsTokens[1]); printf("Forcing internal port# %d, external port# %d\n",internalPort,externalPort); config.setInt("PortServer",internalPort,true); config.setInt("PortExternal",externalPort,true); config.setInt("FTPServerPort",internalPort+1,true); if(paramPartPortsTokens.size() >= 3 && paramPartPortsTokens[2].length() > 0) { int statusPort = strToInt(paramPartPortsTokens[2]); printf("Forcing status port# %d\n",statusPort); config.setInt("ServerAdminPort",statusPort,true); } } else { printf("\nInvalid ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } else { printf("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) == true) { Ip ip("localhost"); int port = Config::getInstance().getInt("ServerAdminPort", intToStr(GameConstants::serverAdminPort).c_str()); ClientSocket clientSocket; clientSocket.setBlock(false); clientSocket.connect(ip, port); if(clientSocket.isConnected() == true) { clientSocket.setBlock(true); char szBuf[8096]=""; clientSocket.receive(&szBuf[0],8095,false); std::cout << szBuf << std::endl; } else { std::cout << "Could not connect (possibly no clients connected) to host: " << ip.getString() << " port: " << port << std::endl; } return 0; } if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_SOUND]) == true || hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { config.setString("FactorySound","None",true); if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { //Logger::getInstance().setMasterserverMode(true); //Model::setMasterserverMode(true); //Shared::Sound::Sound::setMasterserverMode(true); } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]) == true || config.getBool("CheckGlCaps") == false) { printf("**WARNING** disabling opengl capability checking...\n"); config.setBool("CheckGlCaps",false,true); } bool enableATIHacks = config.getBool("EnableATIHacks","false"); if(enableATIHacks == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**WARNING** Enabling ATI video card hacks\n"); TextureGl::setEnableATIHacks(enableATIHacks); } Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str()); if(config.getBool("EnableLegacyFonts","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) == true) { ::Shared::Graphics::Font::forceLegacyFonts = true; Renderer::renderText3DEnabled = false; printf("**WARNING** Forcing Legacy Fonts Enabled\n"); } else { Renderer::renderText3DEnabled = config.getBool("Enable3DFontRendering",intToStr(Renderer::renderText3DEnabled).c_str()); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string settings = paramPartTokens[1]; printf("Forcing resolution [%s]\n",settings.c_str()); paramPartTokens.clear(); Tokenize(settings,paramPartTokens,"x"); if(paramPartTokens.size() >= 2) { int newScreenWidth = strToInt(paramPartTokens[0]); config.setInt("ScreenWidth",newScreenWidth,true); int newScreenHeight = strToInt(paramPartTokens[1]); config.setInt("ScreenHeight",newScreenHeight,true); } else { printf("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } else { printf("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_COLORBITS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_COLORBITS]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string settings = paramPartTokens[1]; printf("Forcing colorbits [%s]\n",settings.c_str()); int newColorBits = strToInt(settings); config.setInt("ColorBits",newColorBits,true); } else { printf("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string settings = paramPartTokens[1]; printf("Forcing depthbits [%s]\n",settings.c_str()); int newDepthBits = strToInt(settings); config.setInt("DepthBits",newDepthBits,true); } else { printf("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string settings = paramPartTokens[1]; printf("Forcing fullscreen [%s]\n",settings.c_str()); bool newFullScreenMode = strToBool(settings); config.setBool("Windowed",!newFullScreenMode,true); } else { printf("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SET_GAMMA]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SET_GAMMA]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string settings = paramPartTokens[1]; printf("Forcing gamma [%s]\n",settings.c_str()); float newGammaValue = strToFloat(settings); config.setFloat("GammaValue",newGammaValue,true); } else { printf("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]) == true) { VideoPlayer::setDisabled(true); } else if(config.getBool("EnableVideos","true") == false) { VideoPlayer::setDisabled(true); } // Set some statics based on ini entries SystemFlags::ENABLE_THREADED_LOGGING = config.getBool("ThreadedLogging","true"); FontGl::setDefault_fontType(config.getString("DefaultFont",FontGl::getDefault_fontType().c_str())); UPNP_Tools::isUPNP = !config.getBool("DisableUPNP","false"); Texture::useTextureCompression = config.getBool("EnableTextureCompression","false"); // 256 for English // 30000 for Chinese ::Shared::Graphics::Font::charCount = config.getInt("FONT_CHARCOUNT",intToStr(::Shared::Graphics::Font::charCount).c_str()); ::Shared::Graphics::Font::fontTypeName = config.getString("FONT_TYPENAME",::Shared::Graphics::Font::fontTypeName.c_str()); ::Shared::Graphics::Font::fontIsMultibyte = config.getBool("FONT_MULTIBYTE",intToStr(::Shared::Graphics::Font::fontIsMultibyte).c_str()); ::Shared::Graphics::Font::fontIsRightToLeft = config.getBool("FONT_RIGHTTOLEFT",intToStr(::Shared::Graphics::Font::fontIsRightToLeft).c_str()); ::Shared::Graphics::Font::baseSize = config.getInt("FONT_BASE_SIZE",intToStr(::Shared::Graphics::Font::baseSize).c_str()); ::Shared::Graphics::Font::scaleFontValue = config.getFloat("FONT_SCALE_SIZE",floatToStr(::Shared::Graphics::Font::scaleFontValue).c_str()); ::Shared::Graphics::Font::scaleFontValueCenterHFactor = config.getFloat("FONT_SCALE_CENTERH_FACTOR",floatToStr(::Shared::Graphics::Font::scaleFontValueCenterHFactor).c_str()); ::Shared::Graphics::Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",::Shared::Graphics::Font::langHeightText.c_str()); ::Shared::Graphics::Font::fontSupportMixedRightToLeft = config.getBool("FONT_RIGHTTOLEFT_MIXED_SUPPORT",intToStr(::Shared::Graphics::Font::fontSupportMixedRightToLeft).c_str()); // Example values: // DEFAULT_CHARSET (English) = 1 // GB2312_CHARSET (Chinese) = 134 ::Shared::Platform::PlatformContextGl::charSet = config.getInt("FONT_CHARSET",intToStr(::Shared::Platform::PlatformContextGl::charSet).c_str()); if(config.getBool("No2DMouseRendering","false") == false) { showCursor(false); //showWindowCursorState = false; } if(config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str()) >= 0) { SystemFlags::DEFAULT_HTTP_TIMEOUT = config.getInt("DEFAULT_HTTP_TIMEOUT",intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT).c_str()); } bool allowAltEnterFullscreenToggle = config.getBool("AllowAltEnterFullscreenToggle",boolToStr(::Shared::Platform::Window::getAllowAltEnterFullscreenToggle()).c_str()); ::Shared::Platform::Window::setAllowAltEnterFullscreenToggle(allowAltEnterFullscreenToggle); if(config.getBool("noTeamColors","false") == true) { MeshCallbackTeamColor::noTeamColors = true; } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_DEBUG]) == true) { printf("Forcing LUA debugging enabled!\n"); config.setBool("DebugLUA",true, true); } // Setup debug logging etc setupLogging(config, haveSpecialOutputCommandLineOption); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,::Shared::Graphics::Font::charCount,::Shared::Graphics::Font::fontTypeName.c_str(),::Shared::Platform::PlatformContextGl::charSet,::Shared::Graphics::Font::fontIsMultibyte, ::Shared::Graphics::Font::fontIsRightToLeft); NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage); MenuStateMasterserver::setDisplayMessageFunction(ExceptionHandler::DisplayMessage); #ifdef USE_STREFLOP SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP enabled.\n",getNetworkVersionString().c_str()); #else SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s, STREFLOP NOT enabled.\n",getNetworkVersionString().c_str()); #endif SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"START\n"); SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"START\n"); // Setup hotkeys from key ini files Config &configKeys = Config::getInstance( std::pair(cfgMainKeys,cfgUserKeys), std::pair(Config::glestkeys_ini_filename,Config::glestuserkeys_ini_filename), std::pair(true,false),config.getString("GlestKeysIniPath","")); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) { ShowINISettings(argc,argv,config,configKeys); return 0; } // Explicitly disable VBO's if(config.getBool("DisableVBO","false") == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) { setVBOSupported(false); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**INFO** Disabling VBOs\n"); } if(config.getBool("DisableVertexInterpolation","false") || hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_DISABLE_VERTEX_INTERPOLATION])) { InterpolationData::setEnableInterpolation(false); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**INFO** Disabling Interpolation\n"); } if(config.getBool("EnableVSynch","false") == true) { ::Shared::Platform::Window::setTryVSynch(true); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**ENABLED OPENGL VSYNCH**\n"); } //float pingTime = Socket::getAveragePingMS("soft-haus.com"); //printf("Ping time = %f\n",pingTime); // Load the language strings Lang &lang= Lang::getInstance(); string language = config.getString("Lang"); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_LANGUAGE]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { language = paramPartTokens[1]; printf("Forcing language [%s]\n",language.c_str()); } else { printf("\nInvalid missing language specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } else { #ifdef _WIN32 int localeBufferSize = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, NULL, 0); wchar_t *sysLocale = new wchar_t[localeBufferSize]; GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, sysLocale,localeBufferSize); //String langValue(sysLocale); //const char *lang_locale = langValue.c_str(); char langValue[1024]=""; wcstombs(langValue,sysLocale, 1023); const char *lang_locale = &langValue[0]; delete [] sysLocale; #else const char *lang_locale = setlocale(LC_ALL,""); #endif if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Locale is: [%s]\n", lang_locale); if(lang_locale != NULL && strlen(lang_locale) >= 2) { if(config.getBool("AutoLocaleLanguageDetect","true") == true) { language = lang_locale; language = language.substr(0,2); printf("Auto setting language [%s]\n",language.c_str()); config.setString("AutoLocaleLanguageDetect","false"); config.save(); } } } if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true || Config::getInstance().getBool("AutoTest","false") == true) { printf("Running in auto test mode\n"); } if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true) { Config::getInstance().setBool("AutoTest",true,true); int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTO_TEST]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { vector paramPartTokens2; Tokenize(paramPartTokens[1],paramPartTokens2,","); if(paramPartTokens2.empty() == false && paramPartTokens2[0].length() > 0) { string newMaxSeconds = paramPartTokens2[0]; time_t newTimeMaxSeconds = strToInt(newMaxSeconds); AutoTest::setMaxGameTime(newTimeMaxSeconds); printf("Forcing maximum game time to [%ld] seconds (%.2f minutes)\n",(long int)newTimeMaxSeconds,((double)newTimeMaxSeconds / 60.0)); } if(paramPartTokens2.size() >= 3 && paramPartTokens2[2].length() > 0) { string autoTestCmd = paramPartTokens2[2]; if(autoTestCmd == "exit") { printf("Detected auto test command [%s], will exit after game.\n",autoTestCmd.c_str()); AutoTest::setWantExitGameWhenDone(true); } else { printf("WARNING: Detected and UNKNOWN auto test command [%s].\n",autoTestCmd.c_str()); } } if(paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) { string newGameSettingsFileToLoad = paramPartTokens2[1]; printf("About to auto test using game settings file [%s]\n",newGameSettingsFileToLoad.c_str()); AutoTest::setLoadGameSettingsFile(newGameSettingsFileToLoad); } } } Renderer &renderer= Renderer::getInstance(); lang.loadGameStrings(language,false, true); if( lang.hasString("FONT_HEIGHT_TEXT")) { ::Shared::Graphics::Font::langHeightText = config.getString("FONT_HEIGHT_TEXT",::Shared::Graphics::Font::langHeightText.c_str()); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_FONT_BASESIZE]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string newfontBaseSize = paramPartTokens[1]; printf("Forcing font base size[%s]\n",newfontBaseSize.c_str()); ::Shared::Graphics::Font::baseSize = strToInt(newfontBaseSize); } else { printf("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",__FILE__,__FUNCTION__,__LINE__,::Shared::Graphics::Font::charCount,::Shared::Graphics::Font::fontTypeName.c_str(),::Shared::Platform::PlatformContextGl::charSet,::Shared::Graphics::Font::fontIsMultibyte,::Shared::Graphics::Font::fontIsRightToLeft); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",::Shared::Graphics::Font::charCount,::Shared::Graphics::Font::fontTypeName.c_str(),::Shared::Platform::PlatformContextGl::charSet,::Shared::Graphics::Font::fontIsMultibyte,::Shared::Graphics::Font::fontIsRightToLeft); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_USE_FONT]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_USE_FONT]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string newfont = paramPartTokens[1]; Properties::applyTagsToValue(newfont); printf("Forcing font [%s]\n",newfont.c_str()); #if defined(WIN32) string newEnvValue = "MEGAGLEST_FONT=" + newfont; _putenv(newEnvValue.c_str()); #else setenv("MEGAGLEST_FONT",newfont.c_str(),1); #endif } else { printf("\nInvalid missing font specified on commandline [%s] value [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); return 1; } } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { return handleCreateDataArchivesCommand(argc, argv); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) { return handleShowCRCValuesCommand(argc, argv); } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) { return handleListDataCommand(argc, argv); } program= new Program(); mainProgram = program; renderer.setProgram(program); if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) { renderer.setAllowRenderUnitTitles(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled); SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n",__FILE__,__FUNCTION__,__LINE__,SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled); } renderer.setAllowRenderUnitTitles(true); string screenShotsPath = userData + GameConstants::folder_path_screenshots; if(isdir(screenShotsPath.c_str()) == false) { createDirectoryPaths(screenShotsPath); } // Cache Player textures - START string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); for(int index = 0; index < GameConstants::maxPlayers; ++index) { string playerTexture = getGameCustomCoreDataPath(data_path, "data/core/faction_textures/faction" + intToStr(index) + ".tga"); if(fileExists(playerTexture) == true) { Texture2D *texture = Renderer::getInstance().newTexture2D(rsGlobal); if(texture) { texture->load(playerTexture); } crcPlayerTextureCache[index] = texture; } else { crcPlayerTextureCache[index] = NULL; } } // Cache Player textures - END SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); mainWindow= new MainWindow(program); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); GameSettings startupGameSettings; //parse command line if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SERVER]) == true) { program->initServer(mainWindow,false,true); gameInitialized = true; } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { program->initServer(mainWindow,false,true,true); gameInitialized = true; } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) { program->initServer(mainWindow,true,false); gameInitialized = true; } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == true) { string fileName = ""; int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]) + string("="),&foundParamIndIndex); if(foundParamIndIndex >= 0) { string loadfileName = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(loadfileName,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { fileName = paramPartTokens[1]; if(fileExists(fileName) == false) { // Save the file now string saveGameFile = "saved/" + fileName; if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { saveGameFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + saveGameFile; } else { saveGameFile = userData + saveGameFile; } if(fileExists(saveGameFile) == true) { fileName = saveGameFile; } } if(fileExists(fileName) == false) { char szBuf[8096]=""; snprintf(szBuf,8096,"File specified for loading a saved game cannot be found: [%s]",fileName.c_str()); printf("\n\n======================================================================================\n%s\n======================================================================================\n\n\n",szBuf); throw megaglest_runtime_error(szBuf); } } } program->initSavedGame(mainWindow,false,fileName); gameInitialized = true; } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]),&foundParamIndIndex); } string mapName = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(mapName,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { vector paramPartTokens2; string tileset="forest"; Tokenize(paramPartTokens[1],paramPartTokens2,","); if(paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) { tileset = paramPartTokens2[1]; } string autoloadMapName = paramPartTokens2[0]; GameSettings *gameSettings = &startupGameSettings; gameSettings->setMap(autoloadMapName); gameSettings->setTileset(tileset); gameSettings->setTech("megapack"); gameSettings->setDefaultUnits(false); gameSettings->setDefaultResources(false); gameSettings->setDefaultVictoryConditions(true); gameSettings->setFogOfWar(false); gameSettings->setAllowObservers(true); gameSettings->setPathFinderType(pfBasic); for(int i = 0; i < GameConstants::maxPlayers; ++i) { ControlType ct= ctClosed; gameSettings->setNetworkPlayerStatuses(i, npst_None); gameSettings->setFactionControl(i, ct); gameSettings->setStartLocationIndex(i, i); gameSettings->setResourceMultiplierIndex(i, 10); gameSettings->setNetworkPlayerName(i, GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); } ControlType ct= ctHuman; gameSettings->setNetworkPlayerStatuses(0, npst_None); gameSettings->setFactionControl(0, ct); gameSettings->setFactionTypeName(0, formatString(GameConstants::OBSERVER_SLOTNAME)); gameSettings->setTeam(0, GameConstants::maxPlayers + fpt_Observer - 1); gameSettings->setStartLocationIndex(0, 0); gameSettings->setNetworkPlayerName(0, GameConstants::OBSERVER_SLOTNAME); gameSettings->setFactionCount(1); Config &config = Config::getInstance(); gameSettings->setEnableServerControlledAI(config.getBool("ServerControlledAI","true")); gameSettings->setNetworkFramePeriod(config.getInt("NetworkSendFrameCount","20")); program->initServer(mainWindow,gameSettings); gameInitialized = true; } else { printf("\nInvalid map name specified on commandline [%s] map [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); delete mainWindow; mainWindow=NULL; return 1; } } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT])) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONNECT]),&foundParamIndIndex); } string serverToConnectTo = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(serverToConnectTo,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string autoConnectServer = paramPartTokens[1]; int port = config.getInt("PortServer",intToStr(GameConstants::serverPort).c_str()); vector paramPartTokens2; Tokenize(autoConnectServer,paramPartTokens2,":"); autoConnectServer = paramPartTokens2[0]; if(paramPartTokens2.size() >= 2 && paramPartTokens2[1].length() > 0) { port = strToInt(paramPartTokens2[1]); } printf("Connecting to host [%s] using port: %d\n",autoConnectServer.c_str(),port); if(autoConnectServer == "auto-connect") { program->initClientAutoFindHost(mainWindow); } else { program->initClient(mainWindow, autoConnectServer,port); } gameInitialized = true; } else { printf("\nInvalid host specified on commandline [%s] host [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); delete mainWindow; mainWindow=NULL; return 1; } } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT])) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CLIENT]),&foundParamIndIndex); } string serverToConnectTo = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(serverToConnectTo,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string autoConnectServer = paramPartTokens[1]; if(autoConnectServer == "auto-connect") { program->initClientAutoFindHost(mainWindow); } else { program->initClient(mainWindow, autoConnectServer); } gameInitialized = true; } else { printf("\nInvalid host specified on commandline [%s] host [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); delete mainWindow; mainWindow=NULL; return 1; } } else if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_LOADSCENARIO]),&foundParamIndIndex); } string scenarioName = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(scenarioName,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string autoloadScenarioName = paramPartTokens[1]; program->initScenario(mainWindow, autoloadScenarioName); gameInitialized = true; } else { printf("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); delete mainWindow; mainWindow=NULL; return 1; } } else { program->initNormal(mainWindow); } SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] OpenGL Info:\n%s\n",__FILE__,__FUNCTION__,__LINE__,renderer.getGlInfo().c_str()); if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true) { printf("%s",renderer.getGlInfo().c_str()); printf("%s",renderer.getGlMoreInfo().c_str()); delete mainWindow; mainWindow=NULL; return 0; } if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true) { int foundParamIndIndex = -1; hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]) + string("="),&foundParamIndIndex); if(foundParamIndIndex < 0) { hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]),&foundParamIndIndex); } string paramValue = argv[foundParamIndIndex]; vector paramPartTokens; Tokenize(paramValue,paramPartTokens,"="); if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { string modelFile = paramPartTokens[1]; printf("About to convert model(s) [%s]\n",modelFile.c_str()); string textureFormat = ""; if(paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) { textureFormat = paramPartTokens[2]; printf("About to convert using texture format [%s]\n",textureFormat.c_str()); } bool keepsmallest = false; if(paramPartTokens.size() >= 4 && paramPartTokens[1].length() > 0) { keepsmallest = (paramPartTokens[3] == "keepsmallest"); printf("About to convert using keepsmallest = %d\n",keepsmallest); } showCursor(true); const Metrics &metrics= Metrics::getInstance(); renderer.clearBuffers(); renderer.clearZBuffer(); renderer.reset2d(); if(CoreData::getInstance().getMenuFontBig3D() != NULL) { renderer.renderText3D( "Please wait, converting models...", CoreData::getInstance().getMenuFontBig3D(), Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400, (metrics.getScreenH() / 2), true); } else { renderer.renderText( "Please wait, converting models...", CoreData::getInstance().getMenuFontBig(), Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400, (metrics.getScreenH() / 2), true); } renderer.swapBuffers(); std::vector models; if(isdir(modelFile.c_str()) == true) { models = getFolderTreeContentsListRecursively(modelFile, ".g3d"); } else { models.push_back(modelFile); } sleep(0); ::Shared::Platform::Window::handleEvent(); SDL_PumpEvents(); int result = 0; char szTextBuf[8096]=""; for(unsigned int i =0; i < models.size(); ++i) { string &file = models[i]; renderer.clearBuffers(); renderer.clearZBuffer(); renderer.reset2d(); snprintf(szTextBuf,8096,"Please wait, converting models [%u of " MG_SIZE_T_SPECIFIER "] ...",i,models.size()); if(CoreData::getInstance().getMenuFontBig3D() != NULL) { renderer.renderText3D( szTextBuf, CoreData::getInstance().getMenuFontBig3D(), Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400, (metrics.getScreenH() / 2), true); } else { renderer.renderText( szTextBuf, CoreData::getInstance().getMenuFontBig(), Vec3f(1.f, 1.f, 0.f), (metrics.getScreenW() / 2) - 400, (metrics.getScreenH() / 2), true); } renderer.swapBuffers(); sleep(0); ::Shared::Platform::Window::handleEvent(); SDL_PumpEvents(); try { printf("About to load model [%s] [%u of " MG_SIZE_T_SPECIFIER "]\n",file.c_str(),i,models.size()); Model *model = renderer.newModel(rsGlobal, file); printf("About to save converted model [%s]\n",file.c_str()); model->save(file,textureFormat,keepsmallest); Renderer::getInstance().endModel(rsGlobal, model); } catch(const exception &ex) { result = 1; printf("ERROR loading model [%s] message [%s]\n",file.c_str(),ex.what()); } } delete mainWindow; mainWindow=NULL; return result; } else { printf("\nInvalid model specified on commandline [%s] texture [%s]\n\n",argv[foundParamIndIndex],(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); printParameterHelp(argv[0],foundInvalidArgs); delete mainWindow; mainWindow=NULL; return 1; } } if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true || hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true) { runTechValidationReport(argc, argv); delete mainWindow; mainWindow=NULL; return 0; } if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true) { runTechTranslationExtraction(argc, argv); delete mainWindow; mainWindow=NULL; return 0; } if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true) { runTilesetValidationReport(argc, argv); delete mainWindow; mainWindow=NULL; return 0; } gameInitialized = true; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); CheckForDuplicateData(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); //throw "BLAH!"; // START Test out SIGSEGV error handling //int *foo = (int*)-1; // make a bad pointer //printf("%d\n", *foo); // causes segfault // END bool startCRCPrecacheThread = config.getBool("PreCacheCRCThread","true"); //printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] precache thread enabled = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread); if (startCRCPrecacheThread == true && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); vector techDataPaths = config.getPathListForType(ptTechs); FileCRCPreCacheThread::setPreCacheThreadCacheLookupKey(GameConstants::preCacheThreadCacheLookupKey); FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(GameConstants::preCacheThreadCacheLookupKey); if(preCacheCRCThreadPtr == NULL) { preCacheCRCThreadPtr = new FileCRCPreCacheThread(); } preCacheThread = preCacheCRCThreadPtr; preCacheThread->setUniqueID(mutexOwnerId); preCacheThread->setTechDataPaths(techDataPaths); //preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame); preCacheThread->start(); } auto_ptr lngCacheGen; auto_ptr languageCacheGen; bool startNativeLanguageNamesPrecacheThread = config.getBool("PreCacheNativeLanguageNamesThread","true"); if(startNativeLanguageNamesPrecacheThread == true && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { lngCacheGen.reset(new NavtiveLanguageNameListCacheGenerator()); languageCacheGen.reset(new SimpleTaskThread(lngCacheGen.get(),1)); languageCacheGen->start(); } // test //Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0); //throw megaglest_runtime_error("test!"); //ExceptionHandler::DisplayMessage("test!", false); // Check for commands being input from stdin string command=""; #ifndef WIN32 pollfd cinfd[1]; #else HANDLE h = 0; #endif if(disableheadless_console == false) { #ifndef WIN32 // Theoretically this should always be 0, but one fileno call isn't going to hurt, and if // we try to run somewhere that stdin isn't fd 0 then it will still just work cinfd[0].fd = fileno(stdin); cinfd[0].events = POLLIN; #else h = GetStdHandle(STD_INPUT_HANDLE); //DWORD dwMode; //GetConsoleMode(h, &dwMode); //SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT); FlushConsoleInputBuffer(h); #endif } if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { printf("Headless server is now running...\n"); printf("To shutdown type: quit\n"); printf("All commands require you to press ENTER\n"); } //throw megaglest_runtime_error("Test!"); //printf("About to throw an exception...\n"); //throw 123; //main loop while(program->isShutdownApplicationEnabled() == false && ::Shared::Platform::Window::handleEvent()) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { if(disableheadless_console == false) { #ifndef WIN32 int pollresult = poll(cinfd, 1, 0); int pollerror = errno; if(pollresult) #else // This is problematic because input on Windows is not line-buffered so this will return // even if getline may block. I haven't found a good way to fix it, so for the moment // I just strongly suggest only running the server from the Python frontend, which does // line buffer input. This does work okay as long as the user doesn't enter characters // without pressing enter, and then try to end the server another way (say a remote // console command), in which case we'll still be waiting for the stdin EOL and hang. DWORD saveMode; GetConsoleMode(h, &saveMode); DWORD dwMode = saveMode; dwMode &= ~ENABLE_MOUSE_INPUT; dwMode &= ~ENABLE_WINDOW_INPUT; SetConsoleMode(h, dwMode); bool gotData = (WaitForSingleObject(h, 0) == WAIT_OBJECT_0); SetConsoleMode(h, saveMode); if(gotData == true) #endif { #ifdef WIN32 bool skip = true; DWORD nNumberOfCharsToRead = 1024; DWORD nRead = 0; INPUT_RECORD irInRec[1025]; PeekConsoleInput(h,&irInRec[0],nNumberOfCharsToRead,&nRead); for(int i = 0; i < nRead; ++i) { INPUT_RECORD &inr = irInRec[i]; //printf("inr.EventType = %d\n",inr.EventType); if(inr.EventType == KEY_EVENT) { if(inr.Event.KeyEvent.bKeyDown) { char cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar; if(cHoldKey == '\r') { skip = false; break; } } } } #else bool skip = false; #endif if(skip == false) { getline(cin, command); cin.clear(); printf("server command [%s]\n",command.c_str()); if(command == "quit") { break; } #ifndef WIN32 if (cinfd[0].revents & POLLNVAL) { printf("invalid file descriptor\n"); } if (cinfd[0].revents & POLLERR) { printf("error in file descriptor\n"); } if (cinfd[0].revents & POLLHUP) { printf("hang up in file descriptor\n"); } if(pollresult < 0) { printf("pollresult = %d errno = %d [%s]\n",pollresult,pollerror,strerror(pollerror)); cinfd[0].fd = fileno(stdin); cinfd[0].events = POLLIN; } #endif } } } //printf("looping\n"); } program->loop(); // Because OpenGL really doesn't do multi-threading well // if(difftime(time(NULL),lastTextureLoadEvent) >= 3) { // lastTextureLoadEvent = time(NULL); // vector textureList = preCacheThread->getPendingTextureList(1); // for(unsigned int i = 0; i < textureList.size(); ++i) { // Texture2D * factionLogo = textureList[i]; // if(factionLogo != NULL) { // printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str()); // //Renderer::findTexture(factionLogo); // renderer.initTexture(rsGlobal,factionLogo); // } // } // } } if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { printf("\nHeadless server is about to quit...\n"); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] starting normal application shutdown\n",__FILE__,__FUNCTION__,__LINE__); if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = program->getSoundThreadManager(true); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } } cleanupCRCThread(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); showCursor(true); //showWindowCursorState = true; SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } catch(const megaglest_runtime_error &e) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } if(program != NULL && program->getTryingRendererInit() == true && program->getRendererInitOk() == false) { message(e.what(),GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } } if(program == NULL || program->getTryingRendererInit() == false || (program->getTryingRendererInit() == true && program->getRendererInitOk() == true)) { ExceptionHandler::handleRuntimeError(e); } } catch(const exception &e) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } } ExceptionHandler::handleRuntimeError(e.what(),true); } catch(const char *e) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } } ExceptionHandler::handleRuntimeError(e,true); } catch(const string &ex) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } } ExceptionHandler::handleRuntimeError(ex.c_str(),true); } #if !defined(HAVE_GOOGLE_BREAKPAD) catch(...) { if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { soundThreadManager = (program != NULL ? program->getSoundThreadManager(true) : NULL); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); chronoshutdownFadeSound.start(); } } ExceptionHandler::handleRuntimeError("Unknown error [main]!",true); } #endif cleanupCRCThread(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete mainWindow; mainWindow = NULL; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); GraphicComponent::clearRegisteredComponents(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(soundThreadManager) { SoundRenderer &soundRenderer= SoundRenderer::getInstance(); if( Config::getInstance().getString("FactorySound","") != "None" && soundRenderer.isVolumeTurnedOff() == false) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); for(;chronoshutdownFadeSound.getMillis() <= shutdownFadeSoundMilliseconds;) { sleep(10); } } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); BaseThread::shutdownAndWait(soundThreadManager); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); delete soundThreadManager; soundThreadManager = NULL; } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return 0; } #if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD) void handleSIGSEGV(int sig) { char szBuf[8096]=""; snprintf(szBuf, 8096,"In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig); printf("%s",szBuf); //abort(); ExceptionHandler::handleRuntimeError(szBuf,true); } #endif #if defined(HAVE_GOOGLE_BREAKPAD) #if defined(WIN32) // Callback when minidump written. static bool MinidumpCallback(const wchar_t *dump_path, const wchar_t *minidump_id, void *context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded) { printf("\n======= In MinidumpCallback...\n"); 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); if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { wchar_t szBuf[8096]; 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); szBuf[bufBytes] = '\0'; MessageBox(NULL, szBuf, L"Unhandled error", MB_OK|MB_SYSTEMMODAL); } return succeeded; } #else // Callback when minidump written. static bool MinidumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { printf("\n======= In MinidumpCallback...\n"); printf("\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s\nSucceeded: %d\n", descriptor.directory().c_str(),descriptor.path(),succeeded); if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { char szBuf[8096]; 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()); message(szBuf,GlobalStaticFlags::getIsNonGraphicalModeEnabled(),tempDataLocation); } return succeeded; } #endif #endif #ifdef WIN32 void EnableCrashingOnCrashes() { typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags); typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags); const DWORD EXCEPTION_SWALLOWING = 0x1; HMODULE kernel32 = LoadLibraryA("kernel32.dll"); if(kernel32 != 0) { tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); if (pGetPolicy && pSetPolicy) { DWORD dwFlags; if (pGetPolicy(&dwFlags)) { // Turn off the filter pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); } } } } #endif int glestMainSEHWrapper(int argc, char** argv) { int result = 0; #ifdef WIN32_STACK_TRACE //printf("Hooking up WIN32_STACK_TRACE...\n"); __try { #endif //application_binary= executable_path(argv[0],true); //printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str()); #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false) { signal(SIGSEGV, handleSIGSEGV); } // http://developerweb.net/viewtopic.php?id=3013 //signal(SIGPIPE, SIG_IGN); #endif initSpecialStrings(); IRCThread::setGlobalCacheContainerName(GameConstants::ircClientCacheLookupKey); result = glestMain(argc, argv); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); cleanupProcessObjects(); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); #ifdef WIN32 //delete winSockManager; //winSockManager = NULL; #endif if(sdl_quitCalled == false) { sdl_quitCalled = true; SDL_Quit(); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); #ifdef WIN32_STACK_TRACE } __except(stackdumper(0, GetExceptionInformation(),true), EXCEPTION_CONTINUE_SEARCH) { return 0; } #endif return result; } int glestMainWrapper(int argc, char** argv) { //setlocale(LC_ALL, "zh_TW.UTF-8"); //setlocale(LC_ALL, ""); #ifdef WIN32 EnableCrashingOnCrashes(); #endif #if defined(HAVE_GOOGLE_BREAKPAD) /* handler = new ExceptionHandler(const wstring& dump_path, FilterCallback filter, MinidumpCallback callback, void* callback_context, int handler_types, MINIDUMP_TYPE dump_type, const wchar_t* pipe_name, const CustomClientInfo* custom_info); */ // 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/ //DWORD dwFlags; //if (GetProcessUserModeExceptionPolicy(&dwFlags)) { // SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1 //} //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n"); #if defined(WIN32) wstring dumpfilepath = utf8_decode("."); //google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true); errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(dumpfilepath, NULL, MinidumpCallback, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL)); #else google_breakpad::MinidumpDescriptor descriptor("."); errorHandlerPtr.reset(new google_breakpad::ExceptionHandler(descriptor, NULL, MinidumpCallback, NULL, true,-1)); #endif // ExceptionHandler(const wstring& dump_path, // FilterCallback filter, // MinidumpCallback callback, // void* callback_context, // int handler_types); #endif #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) //#ifdef DEBUG //printf("MTRACE will be called...\n"); //mtrace (); //#endif #endif #ifdef WIN32 //winSockManager = new SocketManager(); SocketManager winSockManager; #endif bool isSteamMode = hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_STEAM]); if (isSteamMode == true) { if (!STEAMSHIM_init()) { printf("\nSteam API init failed, terminating.\n"); return 42; } } int result = glestMainSEHWrapper(argc, argv); if (isSteamMode == true) { printf("\nSteam API deinit.\n"); STEAMSHIM_deinit(); } return result; } }}//end namespace MAIN_FUNCTION(Glest::Game::glestMainWrapper)