bool CLuaMain::LoadScript ( const char* szLUAScript ) { if ( m_luaVM && !IsLuaCompiledScript( szLUAScript, strlen( szLUAScript ) ) ) { // Run the script if ( !CLuaMain::LuaLoadBuffer ( m_luaVM, szLUAScript, strlen(szLUAScript), NULL ) ) { ResetInstructionCount (); int luaSavedTop = lua_gettop ( m_luaVM ); int iret = this->PCall ( m_luaVM, 0, LUA_MULTRET, 0 ) ; if ( iret == LUA_ERRRUN || iret == LUA_ERRMEM ) { std::string strRes = ConformResourcePath ( lua_tostring( m_luaVM, -1 ) ); g_pGame->GetScriptDebugging()->LogPCallError( m_luaVM, strRes ); } // Cleanup any return values if ( lua_gettop ( m_luaVM ) > luaSavedTop ) lua_settop( m_luaVM, luaSavedTop ); } else { std::string strRes = ConformResourcePath ( lua_tostring( m_luaVM, -1 ) ); g_pGame->GetScriptDebugging()->LogError ( m_luaVM, "Loading in-line script failed: %s", strRes.c_str () ); } } else return false; return true; }
bool CResourceClientScriptsPacket::Write ( NetBitStreamInterface& BitStream ) const { if ( m_vecItems.size() == 0 ) return false; BitStream.Write ( m_pResource->GetNetID() ); auto usItemCount = static_cast<unsigned short>(m_vecItems.size()); BitStream.Write ( usItemCount ); for ( std::vector<CResourceClientScriptItem*>::const_iterator iter = m_vecItems.begin (); iter != m_vecItems.end(); ++iter ) { if ( BitStream.Version() >= 0x50 ) BitStream.WriteString( ConformResourcePath( (*iter)->GetFullName() ) ); const SString& data = (*iter)->GetSourceCode (); unsigned int len = data.length (); BitStream.Write ( len ); BitStream.Write ( data.c_str(), len ); } return true; }
bool CLuaArguments::CallGlobal ( CLuaMain* pLuaMain, const char* szFunction, CLuaArguments * returnValues ) const { assert ( pLuaMain ); assert ( szFunction ); TIMEUS startTime = GetTimeUs (); // Add the function name to the stack and get the event from the table lua_State* luaVM = pLuaMain->GetVirtualMachine (); assert ( luaVM ); LUA_CHECKSTACK ( luaVM, 1 ); int luaStackPointer = lua_gettop ( luaVM ); lua_pushstring ( luaVM, szFunction ); lua_gettable ( luaVM, LUA_GLOBALSINDEX ); // Push our arguments onto the stack PushArguments ( luaVM ); // Call the function with our arguments pLuaMain->ResetInstructionCount (); int iret = 0; try { iret = lua_pcall ( luaVM, m_Arguments.size (), LUA_MULTRET, 0 ); } catch ( ... ) { return false; } if ( iret == LUA_ERRRUN || iret == LUA_ERRMEM ) { std::string strRes = ConformResourcePath ( lua_tostring( luaVM, -1 ) ); g_pGame->GetScriptDebugging()->LogError ( luaVM, "%s", strRes.c_str () ); // cleanup the stack while ( lua_gettop ( luaVM ) - luaStackPointer > 0 ) lua_pop ( luaVM, 1 ); return false; // the function call failed } else { int iReturns = lua_gettop ( luaVM ) - luaStackPointer; if ( returnValues != NULL ) { for ( int i = - iReturns; i <= -1; i++ ) { returnValues->ReadArgument ( luaVM, i ); } } // cleanup the stack while ( lua_gettop ( luaVM ) - luaStackPointer > 0 ) lua_pop ( luaVM, 1 ); } CPerfStatLuaTiming::GetSingleton ()->UpdateLuaTiming ( pLuaMain, szFunction, GetTimeUs() - startTime ); return true; }
void CScriptDebugging::LogString ( const char* szPrePend, lua_State* luaVM, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue ) { // Add file/line number if required SString strText; lua_Debug debugInfo; if ( luaVM && lua_getstack ( luaVM, 1, &debugInfo ) ) { lua_getinfo ( luaVM, "nlS", &debugInfo ); // Make sure this function isn't defined in a string (eg: from runcode) if ( debugInfo.linedefined != 0 ) { std::string strFilename = ConformResourcePath ( debugInfo.source ); // Populate a message to print/send strText = SString ( "%s%s:%d: %s", szPrePend, strFilename.c_str (), debugInfo.currentline, szMessage ); } else { strText = SString ( "%s%s (string-defined function)", szPrePend, szMessage ); } } else { strText = SString ( "%s%s", szPrePend, szMessage ); } // Log it to the file if enough level if ( m_uiLogFileLevel >= uiMinimumDebugLevel ) { PrintLog ( strText ); } switch ( uiMinimumDebugLevel ) { case 1: ucRed = 255, ucGreen = 0, ucBlue = 0; break; case 2: ucRed = 255, ucGreen = 128, ucBlue = 0; break; case 3: ucRed = 0, ucGreen = 255, ucBlue = 0; break; } #ifdef MTA_DEBUG if ( !g_pCore->IsDebugVisible () ) return; #endif g_pCore->DebugEchoColor ( strText, ucRed, ucGreen, ucBlue ); }
/////////////////////////////////////////////////////////////// // // CResourceFileDownloadManager::DownloadFinished // // Callback when file download has finished // /////////////////////////////////////////////////////////////// void CResourceFileDownloadManager::DownloadFinished(const SHttpDownloadResult& result) { CDownloadableResource* pResourceFile = ResolveDownloadContextString((SString*)result.pObj); if (!pResourceFile) return; assert(ListContains(m_ActiveFileDownloadList, pResourceFile)); if (result.bSuccess) { CChecksum checksum = CChecksum::GenerateChecksumFromFile(pResourceFile->GetName()); if (checksum != pResourceFile->GetServerChecksum()) { // Checksum failed - Try download on next server if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) { // Was re-added - Add size again to total. AddDownloadSize(pResourceFile->GetDownloadSize()); SString strMessage("External HTTP file mismatch (Retrying this file with internal HTTP) [%s]", *ConformResourcePath(pResourceFile->GetName())); g_pClientGame->TellServerSomethingImportant(1011, strMessage, 3); return; } } } else { // Download failed due to connection type problem CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(m_HttpServerList[pResourceFile->GetHttpServerIndex()].downloadChannel); SString strHTTPError = pHTTP->GetError(); // Disable server from being used (if possible) if (DisableHttpServer(pResourceFile->GetHttpServerIndex())) { // Try download on next server if (BeginResourceFileDownload(pResourceFile, pResourceFile->GetHttpServerIndex() + 1)) { // Was re-added - Add size again to total. AddDownloadSize(pResourceFile->GetDownloadSize()); SString strMessage("External HTTP file download error:[%d] %s (Disabling External HTTP) [%s]", result.iErrorCode, *strHTTPError, *ConformResourcePath(pResourceFile->GetName())); g_pClientGame->TellServerSomethingImportant(1012, strMessage, 3); return; } } m_strLastHTTPError = strHTTPError; } // File now done (or failed) ListRemove(m_ActiveFileDownloadList, pResourceFile); pResourceFile->SetIsWaitingForDownload(false); }
SString GetDebugMessage ( lua_State* luaVM ) { SString strDebugMessage = ""; lua_Debug debugInfo; if ( luaVM && lua_getstack ( luaVM, 1, &debugInfo ) ) { lua_getinfo ( luaVM, "nlS", &debugInfo ); if ( debugInfo.source[0] == '@' ) { SString strFile = ConformResourcePath ( debugInfo.source ); strDebugMessage = SString( "%s:%i", strFile.c_str (), debugInfo.currentline ); } else { SString strFile = debugInfo.short_src; strDebugMessage = SString( "%s:%i", strFile.c_str (), debugInfo.currentline ); } } return strDebugMessage; }
bool CLuaMain::LoadScriptFromBuffer ( const char* cpInBuffer, unsigned int uiInSize, const char* szFileName ) { SString strNiceFilename = ConformResourcePath( szFileName ); // Decrypt if required const char* cpBuffer; uint uiSize; if ( !g_pRealNetServer->DecryptScript( cpInBuffer, uiInSize, &cpBuffer, &uiSize, strNiceFilename ) ) { SString strMessage( "%s is invalid. Please re-compile at http://luac.mtasa.com/", *strNiceFilename ); g_pGame->GetScriptDebugging()->LogError ( m_luaVM, "Loading script failed: %s", *strMessage ); return false; } bool bUTF8; // UTF-8 BOM? Compare by checking the standard UTF-8 BOM if ( IsUTF8BOM( cpBuffer, uiSize ) == false ) { // Maybe not UTF-8, if we have a >80% heuristic detection confidence, assume it is bUTF8 = ( GetUTF8Confidence ( (const unsigned char*)cpBuffer, uiSize ) >= 80 ); } else { // If there's a BOM, load ignoring the first 3 bytes bUTF8 = true; cpBuffer += 3; uiSize -= 3; } // If compiled script, make sure correct chunkname is embedded EmbedChunkName( strNiceFilename, &cpBuffer, &uiSize ); if ( m_luaVM ) { // Are we not marked as UTF-8 already, and not precompiled? std::string strUTFScript; if ( !bUTF8 && !IsLuaCompiledScript( cpBuffer, uiSize ) ) { std::string strBuffer = std::string(cpBuffer, uiSize); #ifdef WIN32 std::setlocale(LC_CTYPE,""); // Temporarilly use locales to read the script strUTFScript = UTF16ToMbUTF8(ANSIToUTF16( strBuffer )); std::setlocale(LC_CTYPE,"C"); #else strUTFScript = UTF16ToMbUTF8(ANSIToUTF16( strBuffer )); #endif if ( uiSize != strUTFScript.size() ) { uiSize = strUTFScript.size(); g_pGame->GetScriptDebugging()->LogWarning ( m_luaVM, "Script '%s' is not encoded in UTF-8. Loading as ANSI...", strNiceFilename.c_str() ); } } else strUTFScript = std::string(cpBuffer, uiSize); // Run the script if ( CLuaMain::LuaLoadBuffer ( m_luaVM, bUTF8 ? cpBuffer : strUTFScript.c_str(), uiSize, SString ( "@%s", *strNiceFilename ) ) ) { // Print the error std::string strRes = lua_tostring( m_luaVM, -1 ); if ( strRes.length () ) { CLogger::LogPrintf ( "SCRIPT ERROR: %s\n", strRes.c_str () ); g_pGame->GetScriptDebugging()->LogError ( m_luaVM, "Loading script failed: %s", strRes.c_str () ); } else { CLogger::LogPrint ( "SCRIPT ERROR: Unknown\n" ); g_pGame->GetScriptDebugging()->LogError ( m_luaVM, "Loading script failed for unknown reason" ); } } else { ResetInstructionCount (); int luaSavedTop = lua_gettop ( m_luaVM ); int iret = this->PCall ( m_luaVM, 0, LUA_MULTRET, 0 ) ; if ( iret == LUA_ERRRUN || iret == LUA_ERRMEM ) { SString strRes = lua_tostring( m_luaVM, -1 ); g_pGame->GetScriptDebugging()->LogPCallError( m_luaVM, strRes, true ); } // Cleanup any return values if ( lua_gettop ( m_luaVM ) > luaSavedTop ) lua_settop( m_luaVM, luaSavedTop ); return true; } } return false; }
bool CLuaArguments::Call ( CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, CLuaArguments * returnValues ) const { assert ( pLuaMain ); TIMEUS startTime = GetTimeUs (); // Add the function name to the stack and get the event from the table lua_State* luaVM = pLuaMain->GetVirtualMachine (); assert ( luaVM ); LUA_CHECKSTACK ( luaVM, 1 ); int luaStackPointer = lua_gettop ( luaVM ); lua_getref ( luaVM, iLuaFunction.ToInt () ); // Push our arguments onto the stack PushArguments ( luaVM ); // Call the function with our arguments pLuaMain->ResetInstructionCount (); int iret = lua_pcall ( luaVM, m_Arguments.size (), LUA_MULTRET, 0 ); if ( iret == LUA_ERRRUN || iret == LUA_ERRMEM ) { SString strRes = ConformResourcePath ( lua_tostring( luaVM, -1 ) ); vector <SString> vecSplit; strRes.Split ( ":", vecSplit ); if ( vecSplit.size ( ) >= 3 ) { SString strFile = vecSplit[0]; int iLine = atoi ( vecSplit[1].c_str ( ) ); SString strMsg = vecSplit[2].substr ( 1 ); g_pGame->GetScriptDebugging()->LogError ( strFile, iLine, strMsg ); } else g_pGame->GetScriptDebugging()->LogError ( luaVM, "%s", strRes.c_str () ); // cleanup the stack while ( lua_gettop ( luaVM ) - luaStackPointer > 0 ) lua_pop ( luaVM, 1 ); return false; // the function call failed } else { int iReturns = lua_gettop ( luaVM ) - luaStackPointer; if ( returnValues != NULL ) { for ( int i = - iReturns; i <= -1; i++ ) { returnValues->ReadArgument ( luaVM, i ); } } // cleanup the stack while ( lua_gettop ( luaVM ) - luaStackPointer > 0 ) lua_pop ( luaVM, 1 ); } CPerfStatLuaTiming::GetSingleton ()->UpdateLuaTiming ( pLuaMain, pLuaMain->GetFunctionTag ( iLuaFunction.m_iFunction ), GetTimeUs() - startTime ); return true; }