/////////////////////////////////////////////////////////////// // // CServerIdManagerImpl::StaticSaveServerIdMap // // // /////////////////////////////////////////////////////////////// void CServerIdManagerImpl::StaticSaveServerIdMap ( void ) { CXMLFile* pConfigFile = g_pCore->GetXML ()->CreateXML ( CalcMTASAPath ( MTA_SERVERID_LOOKUP_XML ) ); if ( !pConfigFile ) return; pConfigFile->Reset (); CXMLNode* pRoot = pConfigFile->GetRootNode (); if ( !pRoot ) pRoot = pConfigFile->CreateRootNode ( "root" ); // Transfer each item from m_ServerIdMap into the file for ( std::map < CServerIdKey, CServerIdInfo >::iterator it = ms_ServerIdMap.begin () ; it != ms_ServerIdMap.end () ; ++it ) { const SString& strId = it->first.strId; const SString& strDir = it->second.strDir; CXMLNode* pSubNode = pRoot->CreateSubNode ( "id" ); pSubNode->SetTagContent ( strId ); pSubNode->GetAttributes().Create ( "dir" )->SetValue ( strDir ); } pConfigFile->Write (); delete pConfigFile; }
/////////////////////////////////////////////////////////////// // // CServerIdManagerImpl::LoadServerIdMap // // Load server id data from xml file // /////////////////////////////////////////////////////////////// bool CServerIdManagerImpl::LoadServerIdMap ( void ) { // Load config XML file CXMLFile* pConfigFile = g_pCore->GetXML ()->CreateXML ( CalcMTASAPath ( MTA_SERVERID_LOOKUP_XML ) ); if ( !pConfigFile ) return false; pConfigFile->Parse (); CXMLNode* pRoot = pConfigFile->GetRootNode (); if ( !pRoot ) pRoot = pConfigFile->CreateRootNode ( "root" ); m_ServerIdMap.clear (); // Read each node for ( uint i = 0 ; i < pRoot->GetSubNodeCount () ; i++ ) { CXMLNode* pSubNode = pRoot->GetSubNode ( i ); CServerIdKey key; CServerIdInfo info; key.strId = pSubNode->GetTagContent (); if ( CXMLAttribute* pAttribute = pSubNode->GetAttributes().Find ( "dir" ) ) info.strDir = pAttribute->GetValue (); if ( !info.strDir.empty () ) MapSet ( m_ServerIdMap, key, info ); } // Maybe one day remove unwanted directories delete pConfigFile; return true; }
////////////////////////////////////////////////////////// // // HandleNotUsedMainMenu // // Called when a problem occured before the main menu was used by user // If fullscreen, then maybe change fullscreen mode // ////////////////////////////////////////////////////////// void HandleNotUsedMainMenu ( void ) { AddReportLog( 9310, "Loader - HandleNotUsedMainMenu" ); { // Slighty hacky way of checking in-game settings SString strCoreConfigFilename = CalcMTASAPath( PathJoin( "mta", "config", "coreconfig.xml" ) ); SString strCoreConfig; FileLoad( strCoreConfigFilename, strCoreConfig ); SString strWindowed = strCoreConfig.SplitRight( "<display_windowed>" ).Left( 1 ); SString strFullscreenStyle = strCoreConfig.SplitRight( "<display_fullscreen_style>" ).Left( 1 ); if ( strFullscreenStyle == "1" ) { AddReportLog( 9315, "Loader - HandleNotUsedMainMenu - Already Borderless window" ); } else if ( !strWindowed.empty() && !strFullscreenStyle.empty()) { if ( strWindowed == "0" && strFullscreenStyle == "0" ) // 0=FULLSCREEN_STANDARD { // Inform user SString strMessage = _("Are you having problems running MTA:SA?.\n\nDo you want to change the following setting?"); strMessage += "\n" + _("Fullscreen mode:") + " -> " + _("Borderless window"); HideSplash(); int iResponse = MessageBoxUTF8 ( NULL, strMessage, "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST ); if ( iResponse == IDYES ) { // Very hacky way of changing in-game settings strCoreConfig = strCoreConfig.Replace( "<display_fullscreen_style>0", "<display_fullscreen_style>1" ); FileSave( strCoreConfigFilename, strCoreConfig ); AddReportLog( 9311, "Loader - HandleNotUsedMainMenu - User change to Borderless window" ); } else AddReportLog( 9313, "Loader - HandleNotUsedMainMenu - User said no" ); } else AddReportLog( 9314, "Loader - HandleNotUsedMainMenu - Mode not fullscreen standard" ); } else { // If no valid settings file yet, do the change without asking strCoreConfig = "<mainconfig><settings><display_fullscreen_style>1</display_fullscreen_style></settings></mainconfig>"; FileSave( strCoreConfigFilename, strCoreConfig ); AddReportLog( 9312, "Loader - HandleNotUsedMainMenu - Set Borderless window" ); } } // Check if Evolve is active for ( auto processId : MyEnumProcesses( true ) ) { SString strFilename = ExtractFilename( GetProcessPathFilename( processId ) ); if ( strFilename.BeginsWithI( "Evolve" ) ) { SString strMessage = _("Are you having problems running MTA:SA?.\n\nTry disabling the following products for GTA and MTA:"); strMessage += "\n\nEvolve"; DisplayErrorMessageBox ( strMessage, _E("CL43"), "not-used-menu-evolve" ); break; } } }
bool CWebCore::Initialise () { CefMainArgs mainArgs; void* sandboxInfo = nullptr; CefRefPtr<CCefApp> app { new CCefApp }; #if CEF_ENABLE_SANDBOX CefScopedSandboxInfo scopedSandbox; sandboxInfo = scopedSandbox.sandbox_info(); #endif if ( CefExecuteProcess ( mainArgs, app, sandboxInfo ) >= 0 ) return false; CefSettings settings; #if !CEF_ENABLE_SANDBOX settings.no_sandbox = true; #endif // Specifiy sub process executable path #ifndef MTA_DEBUG CefString ( &settings.browser_subprocess_path ).FromWString( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\CEFLauncher.exe" ) ) ); #else CefString ( &settings.browser_subprocess_path ).FromWString( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\CEFLauncher_d.exe" ) ) ); #endif CefString ( &settings.resources_dir_path ).FromWString ( FromUTF8( CalcMTASAPath( "MTA\\CEF") ) ); CefString ( &settings.locales_dir_path ).FromWString( FromUTF8( CalcMTASAPath( "MTA\\CEF\\locales" ) ) ); CefString ( &settings.log_file ).FromWString ( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\cefdebug.txt" ) ) ); #ifdef MTA_DEBUG settings.log_severity = cef_log_severity_t::LOGSEVERITY_INFO; #else settings.log_severity = cef_log_severity_t::LOGSEVERITY_WARNING; #endif settings.multi_threaded_message_loop = true; settings.windowless_rendering_enabled = true; bool state = CefInitialize ( mainArgs, settings, app, sandboxInfo ); // Register custom scheme handler factory CefRegisterSchemeHandlerFactory ( "mtalocal", "", app ); CefRegisterSchemeHandlerFactory ( "http", "mta", app ); return state; }
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing) { CFilePathTranslator FileTranslator; std::string WorkingDirectory; if ( dwReason == DLL_PROCESS_ATTACH ) { WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) ); if ( IsGTAProcess() ) { WriteDebugEvent( SString( "ModuleFileName: %s", *GetLaunchPathFilename() ) ); AddUtf8FileHooks(); // Set low frag heap for XP ULONG heapInfo = 2 ; HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &heapInfo, sizeof( heapInfo ) ); FileTranslator.GetGTARootDirectory ( WorkingDirectory ); SetCurrentDirectory ( WorkingDirectory.c_str ( ) ); // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode' // Meaning it will search the supplied path before the system and windows directory. // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx SetDllDirectory( CalcMTASAPath ( "MTA" ) ); g_pCore = new CCore; FileTranslator.GetGTARootDirectory ( WorkingDirectory ); SetCurrentDirectory ( WorkingDirectory.c_str ( ) ); } } else if (dwReason == DLL_PROCESS_DETACH) { WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) ); if ( IsGTAProcess () ) { RemoveUtf8FileHooks(); AddReportLog( 7102, "Core - PROCESS_DETACH" ); // For now, TerminateProcess if any destruction is attempted (or we'll crash) TerminateProcess ( GetCurrentProcess (), 0 ); if ( g_pCore ) { delete g_pCore; g_pCore = NULL; } } } return TRUE; }
////////////////////////////////////////////////////////// // // CheckLibVersions // // Ensure DLLs are the correct version // ////////////////////////////////////////////////////////// void CheckLibVersions( void ) { #if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE const char* moduleList [] = { "MTA\\loader.dll" ,"MTA\\cgui.dll" ,"MTA\\core.dll" ,"MTA\\game_sa.dll" ,"MTA\\multiplayer_sa.dll" ,"MTA\\netc.dll" ,"MTA\\xmll.dll" ,"MTA\\game_sa.dll" ,"mods\\deathmatch\\client.dll" ,"mods\\deathmatch\\pcre3.dll" }; SString strReqFileVersion; for ( uint i = 0 ; i < NUMELMS( moduleList ) ; i++ ) { SString strFilename = moduleList[i]; #ifdef MTA_DEBUG strFilename = ExtractBeforeExtension( strFilename ) + "_d." + ExtractExtension( strFilename ); #endif SLibVersionInfo fileInfo; if ( FileExists( CalcMTASAPath( strFilename ) ) ) { SString strFileVersion = "0.0.0.0"; if ( GetLibVersionInfo( CalcMTASAPath( strFilename ), &fileInfo ) ) strFileVersion = SString( "%d.%d.%d.%d", fileInfo.dwFileVersionMS >> 16, fileInfo.dwFileVersionMS & 0xFFFF , fileInfo.dwFileVersionLS >> 16, fileInfo.dwFileVersionLS & 0xFFFF ); if ( strReqFileVersion.empty() ) strReqFileVersion = strFileVersion; else if ( strReqFileVersion != strFileVersion ) { DisplayErrorMessageBox ( SStringX(_( "File version mismatch error." " Reinstall MTA:SA if you experience problems.\n" ) + SString( "\n[%s %s/%s]\n", *strFilename, *strFileVersion, *strReqFileVersion ) ), _E("CL40"), "bad-file-version" ); break; } } else { DisplayErrorMessageBox ( SStringX(_( "Some files are missing." " Reinstall MTA:SA if you experience problems.\n" ) + SString( "\n[%s]\n", *strFilename ) ), _E("CL41"), "missing-file" ); break; } }
/////////////////////////////////////////////////////////////// // // CServerIdManagerImpl::CServerIdManagerImpl // // // /////////////////////////////////////////////////////////////// CServerIdManagerImpl::CServerIdManagerImpl ( void ) { // Calc private dir root m_strServerIdLookupBaseDir = CalcMTASAPath ( MTA_SERVERID_LOOKUP_DIR ); MakeSureDirExists ( PathJoin ( m_strServerIdLookupBaseDir, "" ) ); // Calc temp dir path incase of server id error m_strTempErrorDir = PathJoin ( m_strServerIdLookupBaseDir, "_error" ); // If temp dir has been used, clean it if ( DirectoryExists ( m_strTempErrorDir ) ) DelTree ( m_strTempErrorDir, m_strServerIdLookupBaseDir ); LoadServerIdMap (); }
////////////////////////////////////////////////////////// // // RequiresAltTabFix // // Return true if there might be an alt-tab black screen problem when using gta_sa.exe // ////////////////////////////////////////////////////////// bool RequiresAltTabFix( void ) { // Exception for optimus because of better hi-perf detection when using gta_sa.exe if ( GetApplicationSettingInt( "nvhacks", "optimus" ) ) return false; // Check for problem combo of: Windows 10 + NVidia card + full screen if ( IsWindows10OrGreater() && GetApplicationSettingInt( "nvhacks", "nvidia" ) ) { // Slighty hacky way of checking in-game settings SString strCoreConfig; FileLoad( CalcMTASAPath( PathJoin( "mta", "config", "coreconfig.xml" ) ), strCoreConfig ); int iWindowed = atoi( strCoreConfig.SplitRight( "<display_windowed>" ) ); int iFullscreenStyle = atoi( strCoreConfig.SplitRight( "<display_fullscreen_style>" ) ); if ( iWindowed == 0 && iFullscreenStyle == 0 ) // 0=FULLSCREEN_STANDARD return true; } return false; }
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing) { CFilePathTranslator FileTranslator; std::string WorkingDirectory; if ( dwReason == DLL_PROCESS_ATTACH ) { WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) ); if ( IsRealDeal () ) { FileTranslator.GetGTARootDirectory ( WorkingDirectory ); SetCurrentDirectory ( WorkingDirectory.c_str ( ) ); // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode' // Meaning it will search the supplied path before the system and windows directory. // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx SetDllDirectory( CalcMTASAPath ( "MTA" ) ); g_pCore = new CCore; FileTranslator.GetGTARootDirectory ( WorkingDirectory ); SetCurrentDirectory ( WorkingDirectory.c_str ( ) ); } } else if (dwReason == DLL_PROCESS_DETACH) { WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) ); if ( IsRealDeal () ) { // For now, TerminateProcess if any destruction is attempted (or we'll crash) TerminateProcess ( GetCurrentProcess (), 0 ); if ( g_pCore ) { delete g_pCore; g_pCore = NULL; } } } return TRUE; }
void CCrashDumpWriter::DumpMiniDump ( _EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation ) { WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump" ); // Try to load the DLL in our directory HMODULE hDll = NULL; char szDbgHelpPath [MAX_PATH]; if ( GetModuleFileNameA ( NULL, szDbgHelpPath, MAX_PATH ) ) { char* pSlash = _tcsrchr ( szDbgHelpPath, '\\' ); if ( pSlash ) { _tcscpy ( pSlash + 1, "DBGHELP.DLL" ); hDll = LoadLibrary ( szDbgHelpPath ); } } // If we couldn't load the one in our dir, load any version available if ( !hDll ) { hDll = LoadLibrary( "DBGHELP.DLL" ); } if ( !hDll ) AddReportLog( 9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL" ); // We could load a dll? if ( hDll ) { // Grab the MiniDumpWriteDump proc address MINIDUMPWRITEDUMP pDump = reinterpret_cast < MINIDUMPWRITEDUMP > ( GetProcAddress( hDll, "MiniDumpWriteDump" ) ); if ( !pDump ) AddReportLog( 9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump" ); if ( pDump ) { // Create the file HANDLE hFile = CreateFile ( CalcMTASAPath ( "mta\\core.dmp" ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) AddReportLog( 9203, SString( "CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath ( "mta\\core.dmp" ) ) ); if ( hFile != INVALID_HANDLE_VALUE ) { // Create an exception information struct _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = GetCurrentThreadId (); ExInfo.ExceptionPointers = pException; ExInfo.ClientPointers = FALSE; // Write the dump BOOL bResult = pDump ( GetCurrentProcess(), GetCurrentProcessId(), hFile, (MINIDUMP_TYPE)( MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory ), &ExInfo, NULL, NULL ); if ( !bResult ) AddReportLog( 9204, SString( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", GetLastError() ) ); else WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded" ); // Close the dumpfile CloseHandle ( hFile ); // Grab the current time // Ask windows for the system time. SYSTEMTIME SystemTime; GetLocalTime ( &SystemTime ); // Create the dump directory CreateDirectory ( CalcMTASAPath ( "mta\\dumps" ), 0 ); CreateDirectory ( CalcMTASAPath ( "mta\\dumps\\private" ), 0 ); SString strModuleName = pExceptionInformation->GetModuleBaseName (); strModuleName = strModuleName.ReplaceI ( ".dll", "" ).Replace ( ".exe", "" ).Replace ( "_", "" ).Replace ( ".", "" ).Replace ( "-", "" ); if ( strModuleName.length () == 0 ) strModuleName = "unknown"; SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) ); SString strSerialPart = GetApplicationSetting ( "serial" ).substr ( 0, 5 ); uint uiServerIP = GetApplicationSettingInt ( "last-server-ip" ); uint uiServerPort = GetApplicationSettingInt ( "last-server-port" ); int uiServerTime = GetApplicationSettingInt ( "last-server-time" ); int uiServerDuration = _time32 ( NULL ) - uiServerTime; uiServerDuration = Clamp ( 0, uiServerDuration + 1, 0xfff ); // Get path to mta dir SString strPathCode; { std::vector < SString > parts; PathConform ( CalcMTASAPath ( "" ) ).Split ( PATH_SEPERATOR, parts ); for ( uint i = 0 ; i < parts.size () ; i++ ) { if ( parts[i].CompareI ( "Program Files" ) ) strPathCode += "Pr"; else if ( parts[i].CompareI ( "Program Files (x86)" ) ) strPathCode += "Px"; else if ( parts[i].CompareI ( "MTA San Andreas" ) ) strPathCode += "Mt"; else if ( parts[i].BeginsWithI ( "MTA San Andreas" ) ) strPathCode += "Mb"; else strPathCode += parts[i].Left ( 1 ).ToUpper (); } } // Ensure filename parts match up with EDumpFileNameParts SString strFilename ( "mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp", strMTAVersionFull.c_str (), strModuleName.c_str (), pExceptionInformation->GetAddressModuleOffset (), pExceptionInformation->GetCode () & 0xffff, strPathCode.c_str (), uiServerIP, uiServerPort, uiServerDuration, strSerialPart.c_str (), SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute ); SString strPathFilename = CalcMTASAPath ( strFilename ); // Copy the file CopyFile ( CalcMTASAPath ( "mta\\core.dmp" ), strPathFilename, false ); // For the dump uploader SetApplicationSetting ( "diagnostics", "last-dump-extra", "none" ); SetApplicationSetting ( "diagnostics", "last-dump-save", strPathFilename ); // Try to append pool sizes info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-pools" ); CBuffer poolInfo; GetPoolInfo ( poolInfo ); AppendToDumpFile ( strPathFilename, poolInfo, 'POLs', 'POLe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-pools" ); // Try to append d3d state info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-d3d" ); CBuffer d3dInfo; GetD3DInfo ( d3dInfo ); AppendToDumpFile ( strPathFilename, d3dInfo, 'D3Ds', 'D3De' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-d3d" ); // Try to append crash averted stats to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-crash-averted" ); CBuffer crashAvertedStats; GetCrashAvertedStats ( crashAvertedStats ); AppendToDumpFile ( strPathFilename, crashAvertedStats, 'CASs', 'CASe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-crash-averted" ); // Try to append log info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-log" ); CBuffer logInfo; GetLogInfo ( logInfo ); AppendToDumpFile ( strPathFilename, logInfo, 'LOGs', 'LOGe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-log" ); // Try to append dx info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" ); CBuffer dxInfo; GetDxInfo ( dxInfo ); AppendToDumpFile ( strPathFilename, dxInfo, 'DXIs', 'DXIe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" ); // Try to append misc info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" ); CBuffer miscInfo; GetMiscInfo ( miscInfo ); AppendToDumpFile ( strPathFilename, miscInfo, 'MSCs', 'MSCe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" ); // Try to append memory info to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-mem" ); CBuffer memInfo; GetMemoryInfo ( memInfo ); AppendToDumpFile ( strPathFilename, memInfo, 'MEMs', 'MEMe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-mem" ); // Try to logfile.txt to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-logfile" ); CBuffer logfileContent; logfileContent.LoadFromFile( CalcMTASAPath( PathJoin( "mta", "logs", "logfile.txt" ) ) ); AppendToDumpFile ( strPathFilename, logfileContent, 'LOGs', 'LOGe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-logfile" ); // Try to report.log to dump file SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-report" ); CBuffer reportLogContent; reportLogContent.LoadFromFile( PathJoin( GetMTADataPath(), "report.log" ) ); AppendToDumpFile ( strPathFilename, reportLogContent, 'REPs', 'REPe' ); SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-report" ); } } // Free the DLL again FreeLibrary ( hDll ); } // Auto-fixes // Check if crash was in volumetric shadow code if ( ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2 ) { CVARS_SET( "volumetric_shadows", false ); CCore::GetSingleton().SaveConfig(); AddReportLog( 9205, "Disabled volumetric shadows" ); } CNet* pNet = CCore::GetSingleton().GetNetwork(); if ( pNet ) pNet->PostCrash(); }
void CCrashDumpWriter::DumpCoreLog ( CExceptionInformation* pExceptionInformation ) { // Write crash flag for next launch (Simple flag in case of double faults later) fclose( fopen ( CalcMTASAPath ( "mta\\core.log.flag" ), "w" ) ); // Write a log with the generic exception information FILE* pFile = fopen ( CalcMTASAPath ( "mta\\core.log" ), "a+" ); if ( pFile ) { // Header fprintf ( pFile, "%s", "** -- Unhandled exception -- **\n\n" ); // Write the time time_t timeTemp; time ( &timeTemp ); SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) ); SString strInfo; strInfo += SString ( "Version = %s\n", strMTAVersionFull.c_str () ); strInfo += SString ( "Time = %s", ctime ( &timeTemp ) ); strInfo += SString ( "Module = %s\n", pExceptionInformation->GetModulePathName () ); // Write the basic exception information strInfo += SString ( "Code = 0x%08X\n", pExceptionInformation->GetCode () ); strInfo += SString ( "Offset = 0x%08X\n\n", pExceptionInformation->GetAddressModuleOffset () ); // Write the register info strInfo += SString ( "EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n" \ "EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n" \ "CS=%04X DS=%04X SS=%04X ES=%04X " \ "FS=%04X GS=%04X\n\n", pExceptionInformation->GetEAX (), pExceptionInformation->GetEBX (), pExceptionInformation->GetECX (), pExceptionInformation->GetEDX (), pExceptionInformation->GetESI (), pExceptionInformation->GetEDI (), pExceptionInformation->GetEBP (), pExceptionInformation->GetESP (), pExceptionInformation->GetEIP (), pExceptionInformation->GetEFlags (), pExceptionInformation->GetCS (), pExceptionInformation->GetDS (), pExceptionInformation->GetSS (), pExceptionInformation->GetES (), pExceptionInformation->GetFS (), pExceptionInformation->GetGS () ); fprintf ( pFile, "%s", strInfo.c_str () ); // End of unhandled exception fprintf ( pFile, "%s", "** -- End of unhandled exception -- **\n\n\n" ); // Close the file fclose ( pFile ); // For the crash dialog SetApplicationSetting ( "diagnostics", "last-crash-info", strInfo ); WriteDebugEvent ( strInfo.Replace( "\n", " " ) ); } }
bool CWebCore::MakeSureXMLNodesExist () { // Check xml file if ( !m_pXmlConfig ) { SString browserDataPath = CalcMTASAPath ( MTA_BROWSERDATA_PATH ); bool exists = FileExists ( browserDataPath ); m_pXmlConfig = g_pCore->GetXML ()->CreateXML ( browserDataPath ); if ( !m_pXmlConfig || ( exists && !m_pXmlConfig->Parse () ) ) return false; } CXMLNode* pRootNode = m_pXmlConfig->GetRootNode (); if ( !pRootNode ) { pRootNode = m_pXmlConfig->CreateRootNode ( "browserdata" ); if ( !pRootNode ) return false; } if ( !pRootNode->FindSubNode ( "lastupdate" ) ) { CXMLNode* pNode = pRootNode->CreateSubNode ( "lastupdate" ); if ( !pNode ) return false; pNode->SetTagContent ( 0 ); } if ( !pRootNode->FindSubNode ( "whitelistrev" ) ) { if ( !pRootNode->CreateSubNode ( "whitelistrev" ) ) return false; } if ( !pRootNode->FindSubNode ( "blacklistrev" ) ) { if ( !pRootNode->CreateSubNode ( "blacklistrev" ) ) return false; } if ( !pRootNode->FindSubNode ( "globalwhitelist" ) ) { if ( !pRootNode->CreateSubNode ( "globalwhitelist" ) ) return false; } if ( !pRootNode->FindSubNode ( "globalblacklist" ) ) { if ( !pRootNode->CreateSubNode ( "globalblacklist" ) ) return false; } if ( !pRootNode->FindSubNode ( "customblacklist" ) ) { if ( !pRootNode->CreateSubNode ( "customblacklist" ) ) return false; } if ( !pRootNode->FindSubNode ( "customwhitelist" ) ) { if ( !pRootNode->CreateSubNode ( "customwhitelist" ) ) return false; } return true; }
////////////////////////////////////////////////////////// // // PreLaunchWatchDogs // // // ////////////////////////////////////////////////////////// void PreLaunchWatchDogs ( void ) { assert ( !CreateSingleInstanceMutex () ); // // "L0" is opened before the launch sequence and is closed if MTA shutsdown with no error // "L1" is opened before the launch sequence and is closed if GTA is succesfully started // "CR1" is a counter which is incremented if GTA was not started and MTA shutsdown with an error // // "L2" is opened before the launch sequence and is closed if the GTA loading screen is shown // "CR2" is a counter which is incremented at startup, if the previous run didn't make it to the loading screen // // "L3" is opened before the launch sequence and is closed if the GTA loading screen is shown, or a startup problem is handled elsewhere // // Check for unclean stop on previous run #ifndef MTA_DEBUG if ( WatchDogIsSectionOpen ( "L0" ) ) WatchDogSetUncleanStop ( true ); // Flag to maybe do things differently if MTA exit code on last run was not 0 else #endif WatchDogSetUncleanStop ( false ); SString strCrashFlagFilename = CalcMTASAPath( "mta\\core.log.flag" ); if ( FileExists( strCrashFlagFilename ) ) { FileDelete( strCrashFlagFilename ); WatchDogSetLastRunCrash( true ); // Flag to maybe do things differently if MTA crashed last run } else WatchDogSetLastRunCrash( false ); // Reset counter if gta game was run last time if ( !WatchDogIsSectionOpen ( "L1" ) ) WatchDogClearCounter ( "CR1" ); // If crashed 3 times in a row before starting the game, do something if ( WatchDogGetCounter ( "CR1" ) >= 3 ) { WatchDogReset (); HandleTrouble (); } // Check for possible gta_sa.set problems if ( WatchDogIsSectionOpen ( "L2" ) ) { WatchDogIncCounter ( "CR2" ); // Did not reach loading screen last time WatchDogCompletedSection ( "L2" ); } else WatchDogClearCounter ( "CR2" ); // If didn't reach loading screen 5 times in a row, do something if ( WatchDogGetCounter ( "CR2" ) >= 5 ) { WatchDogClearCounter ( "CR2" ); HandleResetSettings (); } // Clear down freeze on quit detection WatchDogCompletedSection( "Q0" ); WatchDogBeginSection ( "L0" ); // Gets closed if MTA exits with a return code of 0 WatchDogBeginSection ( "L1" ); // Gets closed when online game has started SetApplicationSetting ( "diagnostics", "gta-fopen-fail", "" ); SetApplicationSetting ( "diagnostics", "last-crash-reason", "" ); SetApplicationSetting ( "diagnostics", "gta-fopen-last", "" ); }
////////////////////////////////////////////////////////// // // CInstallManager::_ProcessLayoutChecks // // Make sure new reg/dir structure is ok // ////////////////////////////////////////////////////////// SString CInstallManager::_ProcessLayoutChecks ( void ) { // // Validation // // Check data dir exists { if ( !DirectoryExists ( GetMTADataPath () ) ) ShowLayoutError ( "[Data directory not present]" ); // Can't find directory } // Check reg key exists //{ // if ( GetRegistryValue ( "", "Last Install Location" ).empty () ) // ShowLayoutError ( "[Registry key not present]" ); // Can't find reg key //} // Check data dir writable { SString strTestFilePath = PathJoin ( GetMTADataPath (), "testdir", "testfile.txt" ); FileDelete ( strTestFilePath ); RemoveDirectory ( ExtractPath ( strTestFilePath ) ); SString strContent = "test"; if ( !FileSave ( strTestFilePath, strContent ) ) ShowLayoutError ( "[Data directory not writable]" ); // Can't save file FileDelete ( strTestFilePath ); RemoveDirectory ( ExtractPath ( strTestFilePath ) ); } // Check reg key writable { RemoveRegistryKey ( "testkeypath" ); SString strValue = GetTimeString( true, true ); SetRegistryValue ( "testkeypath", "testname", strValue ); SString strValueCheck = GetRegistryValue ( "testkeypath", "testname" ); if ( strValueCheck != strValue ) ShowLayoutError ( "[Registry key not writable]" ); // Can't write reg key RemoveRegistryKey ( "testkeypath" ); } // Check install dir writable { SString strTestFilePath = CalcMTASAPath ( PathJoin ( "mta", "writetest.txt" ) ); FileDelete ( strTestFilePath ); SString strContent = "test"; if ( !FileSave ( strTestFilePath, strContent ) ) ShowLayoutError ( "[Install directory not writable]" ); // Can't save file FileDelete ( strTestFilePath ); } // // Migration // // If news/temp/upcache folder doesn't exist in new, but does in old place, move it { const char* folders[] = { "news", "temp", "upcache" }; for ( uint i = 0 ; i < NUMELMS( folders ) ; i++ ) { SString strSrc = PathJoin ( GetSystemLocalAppDataPath (), "MTA San Andreas " + GetMajorVersionString (), folders[i] ); SString strDest = PathJoin ( GetMTADataPath (), folders[i] ); if ( !DirectoryExists ( strDest ) && DirectoryExists ( strSrc ) ) MoveFile ( strSrc, strDest ); } } // If aero option reg entry doesn't exist in new, but does in old place, move it { if ( GetApplicationSetting ( "aero-enabled" ).empty () ) { SString strLegacyValue = GetVersionRegistryValueLegacy ( GetMajorVersionString (), PathJoin ( "Settings", "general" ), "aero-enabled" ); if ( !strLegacyValue.empty () ) SetApplicationSettingInt ( "aero-enabled", atoi ( strLegacyValue ) ); else SetApplicationSettingInt ( "aero-enabled", 1 ); } } return "ok"; }
/////////////////////////////////////////////////////////////// // // CCompressorJobQueueImpl::ThreadProc // // Job service loop // /////////////////////////////////////////////////////////////// void* CCompressorJobQueueImpl::ThreadProc() { shared.m_Mutex.Lock(); while (!shared.m_bTerminateThread) { // Temp debug code to cause crash with key combo static bool bEnableKeyCrash2 = false; static bool bEnableKeyCrash2Init = false; if (!bEnableKeyCrash2Init) { bEnableKeyCrash2Init = true; bEnableKeyCrash2 = FileExists(CalcMTASAPath("debug.txt")); } bool bEnableKeyCrash = (g_pCore && g_pCore->GetDiagnosticDebug() == EDiagnosticDebug::LUA_TRACE_0000); if (bEnableKeyCrash || bEnableKeyCrash2) { bool bHoldingCtrlL = (GetAsyncKeyState(VK_LCONTROL) & 0x8000) != 0; bool bHoldingCtrlR = (GetAsyncKeyState(VK_RCONTROL) & 0x8000) != 0; if (bHoldingCtrlL && bHoldingCtrlR) { // Cause crash dump generation int* ptr = NULL; *ptr = 0; } } // Is there a waiting command? if (shared.m_CommandQueue.empty()) { if (bEnableKeyCrash) shared.m_Mutex.Wait(10); else shared.m_Mutex.Wait(1000); } else { // Get next command CCompressJobData* pJobData = shared.m_CommandQueue.front(); pJobData->stage = EJobStage::PROCCESSING; shared.m_Mutex.Unlock(); // Process command ProcessCommand(pJobData); // Store result shared.m_Mutex.Lock(); // Check command has not been cancelled (this should not be possible) if (!shared.m_CommandQueue.empty() && pJobData == shared.m_CommandQueue.front()) { // Remove command shared.m_CommandQueue.pop_front(); // Add result pJobData->stage = EJobStage::RESULT; shared.m_ResultQueue.push_back(pJobData); } shared.m_Mutex.Signal(); } } shared.m_bThreadTerminated = true; shared.m_Mutex.Unlock(); return NULL; }
/////////////////////////////////////////////////////////////// // // CClientPerfStatLibMemoryImpl::GetLibMemoryStats // // // /////////////////////////////////////////////////////////////// void CClientPerfStatLibMemoryImpl::GetLibMemoryStats ( CClientPerfStatResult* pResult, const std::map < SString, int >& strOptionMap, const SString& strFilter ) { // // Set option flags // bool bHelp = MapContains ( strOptionMap, "h" ); bool bMoreInfo = MapContains ( strOptionMap, "i" ); bool bTopTags = MapContains ( strOptionMap, "t" ); // // Process help // if ( bHelp ) { pResult->AddColumn ( "Lib memory help" ); pResult->AddRow ()[0] ="Option h - This help"; pResult->AddRow ()[0] ="Option t - Top allocations"; pResult->AddRow ()[0] ="Option i - More information"; return; } // Fetch mem stats from dlls { if ( m_LibraryList.size () == 0 ) { struct { bool bModDir; const char* szName; } libs [] = { { false, "cgui", }, { false, "core", }, { true, "client", }, { false, "game_sa", }, { false, "multiplayer_sa", }, { false, "netc", }, { false, "xmll", }, }; for ( unsigned int i = 0 ; i < NUMELMS ( libs ) ; i++ ) { CLibraryInfo info; bool bModDir = libs[i].bModDir; info.strName = libs[i].szName; #if MTA_DEBUG info.strName += "_d"; #endif #ifdef WIN32 info.strName += ".dll"; #else info.strName += ".so"; #endif info.pLibrary = new CDynamicLibrary(); SString strPathFilename; if ( bModDir ) strPathFilename = CalcMTASAPath( PathJoin( "mods", "deathmatch", info.strName ) ); else strPathFilename = CalcMTASAPath( PathJoin( "mta", info.strName ) ); if ( info.pLibrary->Load ( strPathFilename ) ) { info.pfnGetAllocStats = reinterpret_cast< PFNGETALLOCSTATS > ( info.pLibrary->GetProcedureAddress ( "GetAllocStats" ) ); if ( info.pfnGetAllocStats ) { m_LibraryList.push_back ( info ); continue; } } delete info.pLibrary; } } for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ ) { CLibraryInfo& info = m_LibraryList[i]; unsigned long stats[9]; unsigned long numgot = info.pfnGetAllocStats ( 0, stats, NUMELMS ( stats ) ); if ( numgot >= 2 ) UpdateLibMemory ( info.strName, ( stats[0] + 1023 ) / 1024, ( stats[1] + 1023 ) / 1024 ); } } pResult->AddColumn ( "name" ); pResult->AddColumn ( "change" ); pResult->AddColumn ( "current" ); pResult->AddColumn ( "max" ); if ( bMoreInfo ) { pResult->AddColumn ( "ActiveAllocs" ); pResult->AddColumn ( "DupeAllocs" ); pResult->AddColumn ( "UniqueAllocs" ); pResult->AddColumn ( "ReAllocs" ); pResult->AddColumn ( "Frees" ); pResult->AddColumn ( "UnmatchedFrees" ); pResult->AddColumn ( "DupeMem" ); } else if ( bTopTags ) { pResult->AddColumn ( "1" ); pResult->AddColumn ( "2" ); pResult->AddColumn ( "3" ); pResult->AddColumn ( "4" ); pResult->AddColumn ( "5" ); } // Calc totals if ( strFilter == "" ) { int calcedCurrent = 0; int calcedDelta = 0; int calcedMax = 0; for ( CLibMemoryMap::iterator iter = AllLibMemory.LibMemoryMap.begin () ; iter != AllLibMemory.LibMemoryMap.end () ; ++iter ) { CLibMemory& LibMemory = iter->second; calcedCurrent += LibMemory.Current; calcedDelta += LibMemory.Delta; calcedMax += LibMemory.Max; } // Add row SString* row = pResult->AddRow (); int c = 0; row[c++] = "Lib totals"; if ( labs(calcedDelta) >= 1 ) { row[c] = SString ( "%d KB", calcedDelta ); calcedDelta = 0; } c++; row[c++] = SString ( "%d KB", calcedCurrent ); row[c++] = SString ( "%d KB", calcedMax ); } // For each lib for ( CLibMemoryMap::iterator iter = AllLibMemory.LibMemoryMap.begin () ; iter != AllLibMemory.LibMemoryMap.end () ; ++iter ) { CLibMemory& LibMemory = iter->second; const SString& strName = iter->first; // Apply filter if ( strFilter != "" && strName.find ( strFilter ) == SString::npos ) continue; SString* row = pResult->AddRow (); int c = 0; row[c++] = strName; if ( labs(LibMemory.Delta) >= 1 ) { row[c] = SString ( "%d KB", LibMemory.Delta ); LibMemory.Delta = 0; } c++; row[c++] = SString ( "%d KB", LibMemory.Current ); row[c++] = SString ( "%d KB", LibMemory.Max ); if ( bMoreInfo ) { for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ ) { CLibraryInfo& info = m_LibraryList[i]; if ( strName == info.strName ) { unsigned long stats[9]; unsigned long numgot = info.pfnGetAllocStats ( 0, stats, NUMELMS(stats) ); if ( numgot >= 9 ) { row[c++] = SString ( "%d", stats[2] ); row[c++] = SString ( "%d", stats[3] ); row[c++] = SString ( "%d", stats[4] ); row[c++] = SString ( "%d", stats[5] ); row[c++] = SString ( "%d", stats[6] ); row[c++] = SString ( "%d", stats[7] ); row[c++] = SString ( "%d KB", ( stats[8] + 1023 ) / 1024 ); } break; } } } else if ( bTopTags ) { for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ ) { CLibraryInfo& info = m_LibraryList[i]; if ( strName == info.strName ) { SAllocTrackingTagInfo stats[5]; unsigned long numgot = info.pfnGetAllocStats ( 1, stats, NUMELMS ( stats ) ); for ( uint i = 0 ; i < numgot && i < 5 ; i++ ) { const SAllocTrackingTagInfo& info = stats[i]; row[c++] = SString ( "[%d KB (%d) {%s}]", info.size/ 1024, info.countAllocs, info.tag ); } break; } } } } }