// // Process next BrowseToSolution // void SharedUtil::ProcessPendingBrowseToSolution ( void ) { SString strType, strMessageBoxMessage; int bAskQuestion; // Get args from the registry CArgMap argMap; argMap.SetFromString ( GetApplicationSetting ( "pending-browse-to-solution" ) ); argMap.Get ( "type", strType ); argMap.Get ( "message", strMessageBoxMessage ); argMap.Get ( "bAskQuestion", bAskQuestion ); // Check if anything to do if ( strType.empty () ) return; ClearPendingBrowseToSolution (); // Show message box if required if ( !strMessageBoxMessage.empty () ) MessageBox ( 0, strMessageBoxMessage, "Error", MB_OK|MB_ICONEXCLAMATION ); // Ask question if required, and then launch URL if ( !bAskQuestion || IDYES == MessageBox( 0, "Do you want to see some on-line help about this problem ?", "MTA: San Andreas", MB_ICONQUESTION|MB_YESNO ) ) { SString strQueryURL = GetApplicationSetting ( "trouble-url" ); if ( strQueryURL == "" ) strQueryURL = TROUBLE_URL1; strQueryURL = strQueryURL.Replace ( "%VERSION%", GetApplicationSetting ( "mta-version-ext" ) ); strQueryURL = strQueryURL.Replace ( "%ID%", GetApplicationSetting ( "serial" ) ); strQueryURL = strQueryURL.Replace ( "%TROUBLE%", strType ); ShellExecuteNonBlocking ( "open", strQueryURL.c_str () ); } }
bool CClientDFF::ReplaceModel(unsigned short usModel, bool bAlphaTransparency) { // Record attempt in case it all goes wrong CArgMap argMap; argMap.Set("id", usModel); argMap.Set("reason", "ReplaceModel"); SetApplicationSetting("diagnostics", "gta-model-fail", argMap.ToString()); bool bResult = DoReplaceModel(usModel, bAlphaTransparency); SetApplicationSetting("diagnostics", "gta-model-fail", ""); return bResult; }
//////////////////////////////////////////////////////////////////////////////////////////////// // Check for invalid RpHAnimHierarchy* void _cdecl OnGetAnimHierarchyFromSkinClump(RpClump* pRpClump, void* pRpHAnimHierarchyResult) { if (pRpHAnimHierarchyResult == nullptr) { // Crash will occur at offset 003C51A8 uint uiModelId = pGameInterface->GetPools()->GetModelIdFromClump(pRpClump); LogEvent(818, "Model bad anim hierarchy", "GetAnimHierarchyFromSkinClump", SString("Corrupt model:%d", uiModelId), 5418); CArgMap argMap; argMap.Set("id", uiModelId); argMap.Set("reason", "anim_hierarchy"); SetApplicationSetting("diagnostics", "gta-model-fail", argMap.ToString()); } }
////////////////////////////////////////////////////////// // // CInstallManager::_InstallNewsItems // // // ////////////////////////////////////////////////////////// SString CInstallManager::_InstallNewsItems ( void ) { // Get install news queue CArgMap queue; queue.SetFromString ( GetApplicationSetting ( "news-install" ) ); SetApplicationSetting ( "news-install", "" ); std::vector < SString > keyList; queue.GetKeys ( keyList ); for ( uint i = 0 ; i < keyList.size () ; i++ ) { // Install each file SString strDate = keyList[i]; SString strFileLocation = queue.Get ( strDate ); // Save cwd SString strSavedDir = GetSystemCurrentDirectory (); // Calc and make target dir SString strTargetDir = PathJoin ( GetMTADataPath (), "news", strDate ); MkDir ( strTargetDir ); // Extract into target dir SetCurrentDirectory ( strTargetDir ); // Try to extract the files if ( !ExtractFiles ( strFileLocation ) ) { // If extract failed and update file is an exe, try to run it if ( ExtractExtension ( strFileLocation ).CompareI ( "exe" ) ) ShellExecuteBlocking ( "open", strFileLocation, "-s" ); } // Restore cwd SetCurrentDirectory ( strSavedDir ); // Check result if ( FileExists ( PathJoin ( strTargetDir, "files.xml" ) ) ) { SetApplicationSettingInt ( "news-updated", 1 ); AddReportLog ( 2051, SString ( "InstallNewsItems ok for '%s'", *strDate ) ); } else { AddReportLog ( 4048, SString ( "InstallNewsItems failed with '%s' '%s' '%s'", *strDate, *strFileLocation, *strTargetDir ) ); } } return "ok"; }
// // Direct players to info about trouble // void SharedUtil::BrowseToSolution ( const SString& strType, bool bAskQuestion, bool bTerminateProcess, bool bDoOnExit, const SString& strMessageBoxMessage ) { AddReportLog ( 3200, SString ( "Trouble %s", *strType ) ); // Put args into a string and save in the registry CArgMap argMap; argMap.Set ( "type", strType.SplitLeft ( ";" ) ); argMap.Set ( "bAskQuestion", bAskQuestion ); argMap.Set ( "message", strMessageBoxMessage ); SetApplicationSetting ( "pending-browse-to-solution", argMap.ToString () ); // Do it now if required if ( !bDoOnExit ) ProcessPendingBrowseToSolution (); // Exit if required if ( bTerminateProcess ) TerminateProcess ( GetCurrentProcess (), 1 ); }
/////////////////////////////////////////////////////////////// // // CDatabaseConnectionMySql::CDatabaseConnectionMySql // // // /////////////////////////////////////////////////////////////// CDatabaseConnectionMySql::CDatabaseConnectionMySql ( CDatabaseType* pManager, const SString& strHost, const SString& strUsername, const SString& strPassword, const SString& strOptions ) : m_iRefCount ( 1 ) , m_pManager ( pManager ) { // Parse options string CArgMap optionsMap ( "=", ";" ); optionsMap.SetFromString ( strOptions ); optionsMap.Get ( "autoreconnect", m_bAutomaticReconnect, 1 ); optionsMap.Get ( "batch", m_bAutomaticTransactionsEnabled, 1 ); SString strHostname; SString strDatabaseName; int iPort = 0; SString strUnixSocket; ulong ulClientFlags = 0; // Parse host string CArgMap argMap ( "=", ";" ); argMap.SetFromString ( strHost ); argMap.Get ( "dbname", strDatabaseName, "" ); argMap.Get ( "host", strHostname, "localhost" ); argMap.Get ( "port", iPort, 0 ); argMap.Get ( "unix_socket", strUnixSocket, "" ); m_handle = mysql_init ( NULL ); if ( m_handle ) { my_bool reconnect = m_bAutomaticReconnect; mysql_options ( m_handle, MYSQL_OPT_RECONNECT, &reconnect ); if ( mysql_real_connect ( m_handle, strHostname, strUsername, strPassword, strDatabaseName, iPort, strUnixSocket, ulClientFlags ) ) m_bOpened = true; else { SetLastError ( mysql_errno( m_handle ), mysql_error ( m_handle ) ); } } }
bool CMainConfig::Load ( void ) { // Eventually destroy the previously loaded xml if ( m_pFile ) { delete m_pFile; m_pFile = NULL; } // Load the XML m_pFile = g_pServerInterface->GetXML ()->CreateXML ( GetFileName ().c_str () ); if ( !m_pFile ) { CLogger::ErrorPrintf ( "Error loading config file\n" ); return false; } // Parse it if ( !m_pFile->Parse () ) { CLogger::ErrorPrintf ( "Error parsing config file\n" ); return false; } // Grab the XML root node m_pRootNode = m_pFile->GetRootNode (); if ( !m_pRootNode ) { CLogger::ErrorPrintf ( "Missing root node ('config')\n" ); return false; } // Name int iResult = GetString ( m_pRootNode, "servername", m_strServerName, 1, 96 ); if ( iResult == DOESNT_EXIST ) { CLogger::ErrorPrintf ( "Server name not specified in config\n" ); return false; } else if ( iResult == INVALID_VALUE ) { CLogger::ErrorPrintf ( "Server name must be between 1 and 96 characters\n" ); return false; } // Grab the script debuglog GetString ( m_pRootNode, "serverip", m_strServerIP, 1 ); // Grab the port int iTemp; iResult = GetInteger ( m_pRootNode, "serverport", iTemp, 1, 65535 ); if ( iResult == IS_SUCCESS ) { m_usServerPort = static_cast < unsigned short > ( iTemp ); } else { if ( iResult == DOESNT_EXIST ) CLogger::ErrorPrintf ( "Server port not specified in config\n" ); else CLogger::ErrorPrintf ( "Server port must be between 1 and 65535\n" ); return false; } // Grab the max players iResult = GetInteger ( m_pRootNode, "maxplayers", iTemp, 1, MAX_PLAYER_COUNT ); if ( iResult == IS_SUCCESS ) { m_uiHardMaxPlayers = iTemp; m_uiSoftMaxPlayers = iTemp; } else { if ( iResult == DOESNT_EXIST ) CLogger::ErrorPrintf ( "Max players not specified in config\n" ); else CLogger::ErrorPrintf ( "Max players must be between 1 and %u\n", MAX_PLAYER_COUNT ); return false; } // httpserver iResult = GetBoolean ( m_pRootNode, "httpserver", m_bHTTPEnabled ); if ( iResult == INVALID_VALUE ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"httpserver\" tag; defaulting to 1\n" ); m_bHTTPEnabled = true; } else if ( iResult == DOESNT_EXIST ) { m_bHTTPEnabled = false; } // HTTPD port iResult = GetInteger ( m_pRootNode, "httpport", iTemp, 1, 65535 ); if ( iResult == IS_SUCCESS ) { m_usHTTPPort = static_cast < unsigned short > ( iTemp ); } else { if ( iResult == DOESNT_EXIST ) CLogger::ErrorPrintf ( "HTTP port is not specified in config\n" ); else CLogger::ErrorPrintf ( "HTTP server port must be between 1 and 65535\n" ); return false; } // HTTPD Download URL (if we want to host externally) if ( GetString ( m_pRootNode, "httpdownloadurl", m_strHTTPDownloadURL, 5 ) == IS_SUCCESS ) { m_ucHTTPDownloadType = HTTP_DOWNLOAD_ENABLED_URL; m_strHTTPDownloadURL = SString ( m_strHTTPDownloadURL ).TrimEnd ( "/" ); } else { m_ucHTTPDownloadType = HTTP_DOWNLOAD_ENABLED_PORT; m_strHTTPDownloadURL = ""; } // httpmaxconnectionsperclient GetInteger ( m_pRootNode, "httpmaxconnectionsperclient", m_iHTTPMaxConnectionsPerClient, 1, 8 ); m_iHTTPMaxConnectionsPerClient = Clamp ( 1, m_iHTTPMaxConnectionsPerClient, 8 ); // httpthreadcount GetInteger ( m_pRootNode, "httpthreadcount", m_iHTTPThreadCount, 1, 20 ); m_iHTTPThreadCount = Clamp ( 1, m_iHTTPThreadCount, 20 ); // httpdosthreshold GetInteger ( m_pRootNode, "httpdosthreshold", m_iHTTPDosThreshold, 1, 10000 ); m_iHTTPDosThreshold = Clamp ( 1, m_iHTTPDosThreshold, 10000 ); // verifyclientsettings GetInteger ( m_pRootNode, "verifyclientsettings", m_iEnableClientChecks ); // Handle the <client_file> nodes CXMLNode* pNode = NULL; unsigned int uiCurrentIndex = 0; do { // Grab the current script node pNode = m_pRootNode->FindSubNode ( "client_file", uiCurrentIndex++ ); if ( pNode ) { // Grab its "name" attribute CXMLAttribute* pAttribute = pNode->GetAttributes ().Find ( "name" ); SString strName = pAttribute ? pAttribute->GetValue () : ""; strName = strName.Replace ( "\\", "/" ).ToLower (); // Grab its "verify" attribute pAttribute = pNode->GetAttributes ().Find ( "verify" ); SString strVerify = pAttribute ? pAttribute->GetValue () : ""; bool bVerify = strVerify == "true" || strVerify == "yes" || strVerify == "1"; // Find bitnumber bool bFound = false; for ( uint i = 0 ; i < NUMELMS( gtaDataFiles ) ; i++ ) { if ( strName == gtaDataFiles[i].szRealFilename ) { if ( bVerify ) m_iEnableClientChecks |= 1 << gtaDataFiles[i].iBitNumber; else m_iEnableClientChecks &= ~( 1 << gtaDataFiles[i].iBitNumber ); bFound = true; break; } } if ( !bFound ) CLogger::ErrorPrintf ( "Unknown client_file '%s'\n", *strName ); } } while ( pNode ); // hideac int iHideAC = 0; GetInteger ( m_pRootNode, "hideac", iHideAC ); { std::set < SString > disableACMap; std::set < SString > enableSDMap; { SString strDisableAC; GetString ( m_pRootNode, "disableac", strDisableAC ); std::vector < SString > tagACList; strDisableAC.Split ( ",", tagACList ); for ( std::vector < SString >::iterator it = tagACList.begin () ; it != tagACList.end () ; ++it ) if ( isdigit((uchar)***it) ) { MapInsert ( disableACMap, *it ); MapInsert ( m_DisableComboACMap, *it ); } } // Add support for SD #12, #14, #15, #16, #20, #22 and #28 (defaults to disabled) MapInsert ( m_DisableComboACMap, "12" ); MapInsert ( m_DisableComboACMap, "14" ); MapInsert ( m_DisableComboACMap, "15" ); MapInsert ( m_DisableComboACMap, "16" ); MapInsert ( m_DisableComboACMap, "20" ); MapInsert ( m_DisableComboACMap, "22" ); MapInsert ( m_DisableComboACMap, "28" ); { SString strEnableSD; GetString ( m_pRootNode, "enablesd", strEnableSD ); std::vector < SString > tagSDList; strEnableSD.Split ( ",", tagSDList ); for ( std::vector < SString >::iterator it = tagSDList.begin () ; it != tagSDList.end () ; ++it ) if ( isdigit((uchar)***it) ) { MapInsert ( enableSDMap, *it ); MapRemove ( m_DisableComboACMap, *it ); } // Also save initial value in transient settings, so we can update the config without anyone knowing MapSet ( m_TransientSettings, "enablesd", strEnableSD ); } CArgMap argMap; for ( std::set < SString >::iterator it = m_DisableComboACMap.begin () ; it != m_DisableComboACMap.end () ; ++it ) argMap.Set ( *it, "" ); SString strDisableComboACMap = argMap.ToString (); argMap = CArgMap (); for ( std::set < SString >::iterator it = disableACMap.begin () ; it != disableACMap.end () ; ++it ) argMap.Set ( *it, "" ); SString strDisableACMap = argMap.ToString (); argMap = CArgMap (); for ( std::set < SString >::iterator it = enableSDMap.begin () ; it != enableSDMap.end () ; ++it ) argMap.Set ( *it, "" ); SString strEnableSDMap = argMap.ToString (); g_pNetServer->SetChecks ( strDisableComboACMap, strDisableACMap, strEnableSDMap, m_iEnableClientChecks, iHideAC != 0 ); } { SString strEnable; GetString ( m_pRootNode, "enablediagnostic", strEnable ); std::vector < SString > tagList; strEnable.Split ( ",", tagList ); for ( std::vector < SString >::iterator it = tagList.begin () ; it != tagList.end () ; ++it ) if ( (*it).length () ) MapInsert ( m_EnableDiagnosticMap, *it ); } // Grab the server password iResult = GetString ( m_pRootNode, "password", m_strPassword, 1, 32 ); // Grab the server fps limit int iFPSTemp = 0; iResult = GetInteger ( m_pRootNode, "fpslimit", iFPSTemp, 0, 100 ); if ( iResult == IS_SUCCESS ) { if ( iFPSTemp == 0 || iFPSTemp >= 25 ) { m_usFPSLimit = (unsigned short)iFPSTemp; SetInteger ( m_pRootNode, "fpslimit", (int)m_usFPSLimit ); } } // Grab whether or not voice is enabled iResult = GetInteger ( m_pRootNode, "voice", iTemp, 0, 1 ); if ( iResult == IS_SUCCESS ) { m_bVoiceEnabled = iTemp ? true : false; } // Grab the Sample Rate for Voice iTemp = m_uiVoiceSampleRate; iResult = GetInteger ( m_pRootNode, "voice_samplerate", iTemp, 0, 2 ); m_uiVoiceSampleRate = Clamp ( 0, iTemp, 2 ); // Grab the Quality for Voice iTemp = m_ucVoiceQuality; iResult = GetInteger ( m_pRootNode, "voice_quality", iTemp, 0, 10 ); m_ucVoiceQuality = Clamp ( 0, iTemp, 10 ); // Grab the bitrate for Voice [optional] iResult = GetInteger ( m_pRootNode, "voice_bitrate", iTemp ); if ( iResult == IS_SUCCESS ) { m_uiVoiceBitrate = iTemp; } // Grab the serial verification /** ACHTUNG: Unsupported for release 1.0 (#4090) iResult = GetBoolean ( m_pRootNode, "verifyserials", m_bVerifySerials ); if ( iResult == INVALID_VALUE ) { m_bVerifySerials = true; } else if ( iResult == DOESNT_EXIST ) */ { m_bVerifySerials = false; } // Grab the server-id filename SString strIdFile = "server-id.keys"; GetString ( m_pRootNode, "idfile", strIdFile, 1 ); m_strIdFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strIdFile ); // Grab the server logfiles std::string strBuffer; if ( GetString ( m_pRootNode, "logfile", strBuffer, 1 ) == IS_SUCCESS ) m_strLogFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); if ( GetString ( m_pRootNode, "authfile", strBuffer, 1 ) == IS_SUCCESS ) m_strAuthFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); if ( GetString ( m_pRootNode, "dbfile", strBuffer, 1 ) == IS_SUCCESS ) m_strDbLogFilename = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); else m_strDbLogFilename = g_pServerInterface->GetModManager ()->GetAbsolutePath ( "logs/db.log" ); if ( GetString ( m_pRootNode, "loadstringfile", strBuffer, 1 ) == IS_SUCCESS ) m_strLoadstringLogFilename = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); // Grab the server access control list if ( GetString ( m_pRootNode, "acl", strBuffer, 1, 255 ) == IS_SUCCESS ) { m_strAccessControlListFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); } else { m_strAccessControlListFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( "acl.xml" ); } // Grab the global databases path if ( GetString ( m_pRootNode, "global_databases_path", strBuffer, 1, 255 ) != IS_SUCCESS ) strBuffer = "databases/global"; if ( !IsValidFilePath ( strBuffer.c_str () ) || strBuffer.empty () ) { CLogger::ErrorPrintf ( "global_databases_path is not valid. Defaulting to 'databases/global'\n" ); strBuffer = "databases/global"; } m_strGlobalDatabasesPath = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); // Grab the system databases path if ( GetString ( m_pRootNode, "system_databases_path", strBuffer, 1, 255 ) != IS_SUCCESS ) strBuffer = "databases/system"; if ( !IsValidFilePath ( strBuffer.c_str () ) || strBuffer.empty () ) { CLogger::ErrorPrintf ( "system_databases_path is not valid. Defaulting to 'databases/system'\n" ); strBuffer = "databases/system"; } m_strSystemDatabasesPath = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); // Grab the backup path if ( GetString ( m_pRootNode, "backup_path", strBuffer, 1, 255 ) != IS_SUCCESS ) strBuffer = "backups"; if ( !IsValidFilePath ( strBuffer.c_str () ) || strBuffer.empty () ) { CLogger::ErrorPrintf ( "backup_path is not valid. Defaulting to 'backups'\n" ); strBuffer = "backups"; } m_strBackupPath = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); // Grab the backup interval GetInteger ( m_pRootNode, "backup_interval", m_iBackupInterval ); m_iBackupInterval = Clamp ( 0, m_iBackupInterval, 30 ); // Grab the backup count GetInteger ( m_pRootNode, "backup_copies", m_iBackupAmount ); m_iBackupAmount = Clamp ( 0, m_iBackupAmount, 100 ); GetBoolean ( m_pRootNode, "autologin", m_bAutoLogin ); // networkencryption - Encryption for Server <-> client communications GetBoolean ( m_pRootNode, "networkencryption", m_bNetworkEncryptionEnabled ); // bandwidth_reduction GetString ( m_pRootNode, "bandwidth_reduction", m_strBandwidthReductionMode ); ApplyBandwidthReductionMode (); // busy_sleep_time GetInteger ( m_pRootNode, "busy_sleep_time", m_iPendingWorkToDoSleepTime ); m_iPendingWorkToDoSleepTime = Clamp ( -1, m_iPendingWorkToDoSleepTime, 50 ); // idle_sleep_time GetInteger ( m_pRootNode, "idle_sleep_time", m_iNoWorkToDoSleepTime ); m_iNoWorkToDoSleepTime = Clamp ( -1, m_iNoWorkToDoSleepTime, 50 ); // threadnet - Default to on at startup m_bThreadNetEnabled = true; ApplyThreadNetEnabled (); // Check settings in this list here const std::vector < SIntSetting >& settingList = GetIntSettingList (); for ( uint i = 0 ; i < settingList.size () ; i++ ) { const SIntSetting& item = settingList[i]; int iValue = item.iDefault; GetInteger ( m_pRootNode, item.szName, iValue ); *item.pVariable = Clamp ( item.iMin, iValue, item.iMax ); } // Handle recently retired lightsync_rate if ( m_pRootNode->FindSubNode ( "lightweight_sync_interval" ) == NULL ) { GetInteger ( m_pRootNode, "lightsync_rate", g_TickRateSettings.iLightSync ); g_TickRateSettings.iLightSync = Clamp ( 200, g_TickRateSettings.iLightSync, 4000 ); } ApplyNetOptions (); return true; }
// // Extract and map data from a shoutcast meta string // void CBassAudio::ParseShoutcastMeta ( const SString& strMeta ) { // Get title int startPos = strMeta.find ( "=" ); SString strStreamTitle = strMeta.SubStr ( startPos + 2, strMeta.find ( ";" ) - startPos - 3 ); if ( !strStreamTitle.empty () ) m_strStreamTitle = strStreamTitle; // Get url startPos = strMeta.find ( "=" , startPos + 1 ); SString strStreamUrl = strMeta.SubStr ( startPos + 2, strMeta.find ( ";", startPos ) - startPos - 3 ); // Extract info from url CArgMap shoutcastInfo; shoutcastInfo.SetEscapeCharacter ( '%' ); shoutcastInfo.SetFromString ( strStreamUrl ); // Convert from shoutcast identifiers to map of tags static const char* convList[] = { // Mapable "%ARTI", "artist", "%TITL", "title", "%ALBM", "album", // Mapable, but possibly don't exist "%GNRE", "genre", "%YEAR", "year", "%CMNT", "comment", "%TRCK", "track", "%COMP", "composer", "%COPY", "copyright", "%SUBT", "subtitle", "%AART", "albumartist", // Not mapabale "%DURATION", "duration", "%SONGTYPE", "songtype", "%OVERLAY", "overlay", "%BUYCD", "buycd", "%WEBSITE", "website", "%PICTURE", "picture", }; std::vector < SString > shoutcastKeyList; shoutcastInfo.GetKeys ( shoutcastKeyList ); // For each shoutcast pair for ( std::vector < SString >::iterator iter = shoutcastKeyList.begin () ; iter != shoutcastKeyList.end () ; ++iter ) { const SString& strKey = *iter; SString strValue = shoutcastInfo.Get ( strKey ); // Find %TAG match for ( uint i = 0 ; i < NUMELMS( convList ) - 1 ; i += 2 ) { if ( strKey == convList[ i + 1 ] ) { MapSet ( m_ConvertedTagMap, convList[ i ], strValue ); break; } } } }
void CArgMap::Merge ( const CArgMap& other, bool bAllowMultiValues ) { MergeFromString ( other.ToString (), bAllowMultiValues ); }