int CLuaFunctionDefs::AddCommandHandler ( lua_State* luaVM ) { // bool addCommandHandler ( string commandName, function handlerFunction, [bool restricted = false, bool caseSensitive = true] ) SString strKey; CLuaFunctionRef iLuaFunction; bool bRestricted; bool bCaseSensitive; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strKey ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadBool ( bRestricted, false ); argStream.ReadBool ( bCaseSensitive, true ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Grab our VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Add them to our list over command handlers if ( m_pRegisteredCommands->AddCommand ( pLuaMain, strKey, iLuaFunction, bRestricted, bCaseSensitive ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::RemoveCommandHandler ( lua_State* luaVM ) { // bool removeCommandHandler ( string commandName [, function handler] ) SString strKey; CLuaFunctionRef iLuaFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strKey ); argStream.ReadFunction ( iLuaFunction, LUA_REFNIL ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Grab our VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Remove it from our list if ( m_pRegisteredCommands->RemoveCommand ( pLuaMain, strKey, iLuaFunction ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::RemoveEventHandler ( lua_State* luaVM ) { // bool removeEventHandler ( string eventName, element attachedTo, function functionVar ) SString strName; CClientEntity* pEntity; CLuaFunctionRef iLuaFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strName ); argStream.ReadUserData ( pEntity ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Grab our virtual machine CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Do it if ( CStaticFunctionDefinitions::RemoveEventHandler ( *pLuaMain, strName, *pEntity, iLuaFunction ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, SString ( "Bad argument @ '%s' [%s]", "removeEventHandler", *argStream.GetErrorMessage () ) ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::RequestBrowserDomains ( lua_State* luaVM ) { // bool requestBrowserDomains ( table domains, bool isURL [, function callback ] ) std::vector<SString> pages; bool bIsURL; CLuaFunctionRef callbackFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadStringTable ( pages ); argStream.ReadBool ( bIsURL, false ); argStream.ReadFunction ( callbackFunction, LUA_REFNIL ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Convert to domains if we got a list of URLs if ( bIsURL ) { for ( auto& strURL : pages ) { strURL = g_pCore->GetWebCore ()->GetDomainFromURL ( strURL ); } } WebRequestCallback callback = [=]( bool bAllow, const std::vector<SString>& domains ) { // Test if luaVM is still available if ( m_pLuaManager->IsLuaVMValid ( luaVM ) && VERIFY_FUNCTION ( callbackFunction ) ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( !pLuaMain ) return; CLuaArguments arguments; arguments.PushBoolean ( bAllow ); CLuaArguments LuaTable; int i = 0; for ( const auto& domain : domains ) { LuaTable.PushNumber ( ++i ); LuaTable.PushString ( domain ); } arguments.PushTable ( &LuaTable ); arguments.Call ( pLuaMain, callbackFunction ); } }; g_pCore->GetWebCore ()->RequestPages ( pages, VERIFY_FUNCTION ( callbackFunction ) ? &callback : nullptr ); lua_pushboolean ( luaVM, true ); return 1; } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaDatabaseDefs::OOP_DbQuery ( lua_State* luaVM ) { // handle dbQuery ( [ function callbackFunction, [ table callbackArguments, ] ] element connection, string query, ... ) CLuaFunctionRef iLuaFunction; CLuaArguments callbackArgs; CDatabaseConnectionElement* pElement; SString strQuery; CLuaArguments Args; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pElement ); if ( argStream.NextIsFunction () ) { argStream.ReadFunction ( iLuaFunction ); if ( argStream.NextIsTable () ) { argStream.ReadLuaArgumentsTable( callbackArgs ); } } argStream.ReadString ( strQuery ); argStream.ReadLuaArguments ( Args ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Start async query CDbJobData* pJobData = g_pGame->GetDatabaseManager ()->QueryStart ( pElement->GetConnectionHandle (), strQuery, &Args ); if ( !pJobData ) { if ( !g_pGame->GetDatabaseManager ()->IsLastErrorSuppressed () ) m_pScriptDebugging->LogWarning ( luaVM, "%s failed; %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), *g_pGame->GetDatabaseManager ()->GetLastErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; } // Make callback function if required if ( VERIFY_FUNCTION ( iLuaFunction ) ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { CLuaArguments Arguments; Arguments.PushDbQuery ( pJobData ); Arguments.PushArguments ( callbackArgs ); pJobData->SetCallback ( CLuaDatabaseDefs::DbQueryCallback, g_pGame->GetLuaCallbackManager ()->CreateCallback ( pLuaMain, iLuaFunction, Arguments ) ); } } // Add debug info incase query result does not get collected pJobData->SetLuaDebugInfo ( g_pGame->GetScriptDebugging ()->GetLuaDebugInfo ( luaVM ) ); lua_pushquery ( luaVM, pJobData ); return 1; } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::UnbindKey ( lua_State* luaVM ) { SString strKey = "", strHitState = ""; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strKey ); if ( !argStream.HasErrors ( ) ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { if ( argStream.NextIsString ( 1 ) ) // Check if has command { // bool unbindKey ( string key, string keyState, string command ) SString strResource = pLuaMain->GetResource()->GetName(); SString strCommand = ""; argStream.ReadString ( strHitState ); argStream.ReadString ( strCommand ); if ( !argStream.HasErrors ( ) ) { if ( CStaticFunctionDefinitions::UnbindKey ( strKey, strHitState, strCommand, strResource ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else { // bool unbindKey ( string key, [ string keyState, function handler ] ) CLuaFunctionRef iLuaFunction; argStream.ReadString ( strHitState, "" ); argStream.ReadFunction ( iLuaFunction, LUA_REFNIL ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors ( ) ) { const char* szHitState = strHitState == "" ? NULL : strHitState.c_str(); if ( CStaticFunctionDefinitions::UnbindKey ( strKey, pLuaMain, szHitState, iLuaFunction ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } } } if ( argStream.HasErrors ( ) ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::BindKey ( lua_State* luaVM ) { SString strKey = "", strHitState = "", strCommand = "", strArguments = ""; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strKey ); argStream.ReadString ( strHitState ); if ( !argStream.HasErrors ( ) ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { if ( argStream.NextIsString ( ) ) { // bindKey ( string key, string keyState, string commandName, [ string arguments ] ) SString strResource = pLuaMain->GetResource()->GetName(); argStream.ReadString ( strCommand ); argStream.ReadString ( strArguments, "" ); if ( !argStream.HasErrors ( ) ) { if ( CStaticFunctionDefinitions::BindKey ( strKey, strHitState, strCommand, strArguments, strResource ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else { // bindKey ( string key, string keyState, function handlerFunction, [ var arguments, ... ] ) CLuaFunctionRef iLuaFunction; CLuaArguments Arguments; argStream.ReadFunction ( iLuaFunction ); argStream.ReadLuaArguments ( Arguments ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors ( ) ) { if ( CStaticFunctionDefinitions::BindKey ( strKey, strHitState, pLuaMain, iLuaFunction, Arguments ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } } } if ( argStream.HasErrors ( ) ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaTimerDefs::SetTimer ( lua_State* luaVM ) { // timer setTimer ( function theFunction, int timeInterval, int timesToExecute, [ var arguments... ] ) CLuaFunctionRef iLuaFunction; double dTimeInterval; uint uiTimesToExecute; CLuaArguments Arguments; CScriptArgReader argStream ( luaVM ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadNumber ( dTimeInterval ); argStream.ReadNumber ( uiTimesToExecute ); argStream.ReadLuaArguments ( Arguments ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain * luaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( luaMain ) { // Check for the minimum interval if ( dTimeInterval < LUA_TIMER_MIN_INTERVAL ) { argStream.SetCustomError ( "Interval is below 50" ); } else { CLuaTimer* pLuaTimer = luaMain->GetTimerManager ()->AddTimer ( iLuaFunction, CTickCount ( dTimeInterval ), uiTimesToExecute, Arguments ); if ( pLuaTimer ) { // Set our timer debug info (in case we don't have any debug info which is usually when you do setTimer(destroyElement, 50, 1) or such) pLuaTimer->SetLuaDebugInfo ( g_pClientGame->GetScriptDebugging ()->GetLuaDebugInfo ( luaVM ) ); lua_pushtimer ( luaVM, pLuaTimer ); return 1; } } } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::AddEventHandler ( lua_State* luaVM ) { // bool addEventHandler ( string eventName, element attachedTo, function handlerFunction, [bool getPropagated = true] ) SString strName; CClientEntity* pEntity; CLuaFunctionRef iLuaFunction; bool bPropagated; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strName ); argStream.ReadUserData ( pEntity ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadBool ( bPropagated, true ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Grab our virtual machine CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Check if the handle is in use if ( pEntity->GetEventManager()->HandleExists ( pLuaMain, strName, iLuaFunction ) ) { m_pScriptDebugging->LogCustom ( luaVM, 255, 0, 0, "addEventHandler: '%s' with this function is already handled", *strName ); lua_pushboolean ( luaVM, false ); return 1; } // Do it if ( CStaticFunctionDefinitions::AddEventHandler ( *pLuaMain, strName, *pEntity, iLuaFunction, bPropagated ) ) { lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, SString ( "Bad argument @ '%s' [%s]", "addEventHandler", *argStream.GetErrorMessage () ) ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::GetBrowserSource ( lua_State* luaVM ) { // bool getBrowserSource ( function callback ) CClientWebBrowser* pWebBrowser; CLuaFunctionRef callbackFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pWebBrowser ); argStream.ReadFunction ( callbackFunction ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain && VERIFY_FUNCTION ( callbackFunction ) ) { pWebBrowser->GetSourceCode ( [callbackFunction, pLuaMain]( const std::string& code ) { /* This function should not be called when the resource is about to stop as stopping the resource destroys the browser element and thus cancels the CefStringVisitor callback class (see CWebView::GetSourceCode::MyStringVisitor) */ if ( VERIFY_FUNCTION ( callbackFunction ) ) { CLuaArguments arguments; // TODO: Use SCharStringRef/direct string access instead of copying strings around arguments.PushString ( code ); arguments.Call ( pLuaMain, callbackFunction ); } }); lua_pushboolean ( luaVM, true ); return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
// Call a function on a remote server int CLuaFunctionDefs::FetchRemote ( lua_State* luaVM ) { // bool fetchRemote ( string URL [, string queueName ][, int connectionAttempts = 10, int connectTimeout = 10000 ], callback callbackFunction, [ string postData, bool bPostBinary, arguments... ] ) CScriptArgReader argStream ( luaVM ); SString strURL; SString strQueueName; CLuaFunctionRef iLuaFunction; SString strPostData; bool bPostBinary; CLuaArguments args; uint uiConnectionAttempts; uint uiConnectTimeoutMs; argStream.ReadString ( strURL ); if ( argStream.NextIsString () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_QUEUE_NAME, "'queue name' is being used" ); argStream.ReadIfNextIsString ( strQueueName, CALL_REMOTE_DEFAULT_QUEUE_NAME ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS, "'connection attempts' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectionAttempts, 10 ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECT_TIMEOUT, "'connect timeout' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectTimeoutMs, 10000 ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadString ( strPostData, "" ); argStream.ReadBool ( bPostBinary, false ); argStream.ReadLuaArguments ( args ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain * luaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( luaMain ) { g_pGame->GetRemoteCalls ()->Call ( strURL, &args, strPostData, bPostBinary, luaMain, iLuaFunction, strQueueName, uiConnectionAttempts, uiConnectTimeoutMs ); lua_pushboolean ( luaVM, true ); return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
// Call a function on a remote server int CLuaFunctionDefs::CallRemote ( lua_State* luaVM ) { CScriptArgReader argStream ( luaVM ); if ( !argStream.NextIsFunction ( 1 ) && !argStream.NextIsFunction ( 2 ) ) { // Call type 1 // bool callRemote ( string host [, int connectionAttempts = 10, int connectTimeout = 10000 ], string resourceName, string functionName, callback callbackFunction, [ arguments... ] ) SString strHost; uint uiConnectionAttempts; uint uiConnectTimeoutMs; SString strResourceName; SString strFunctionName; CLuaFunctionRef iLuaFunction; CLuaArguments args; argStream.ReadString ( strHost ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS, "'connection attempts' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectionAttempts, 10 ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECT_TIMEOUT, "'connect timeout' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectTimeoutMs, 10000 ); argStream.ReadString ( strResourceName ); argStream.ReadString ( strFunctionName ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadLuaArguments ( args ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain * luaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( luaMain ) { g_pGame->GetRemoteCalls ()->Call ( strHost, strResourceName, strFunctionName, &args, luaMain, iLuaFunction, uiConnectionAttempts, uiConnectTimeoutMs ); lua_pushboolean ( luaVM, true ); return 1; } } } else { // Call type 2 // bool callRemote ( string URL [, int connectionAttempts = 10, int connectTimeout = 10000 ], callback callbackFunction, [ arguments... ] ) SString strURL; uint uiConnectionAttempts; uint uiConnectTimeoutMs; CLuaFunctionRef iLuaFunction; CLuaArguments args; argStream.ReadString ( strURL ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECTION_ATTEMPTS, "'connection attempts' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectionAttempts, 10 ); if ( argStream.NextIsNumber () ) MinServerReqCheck ( argStream, MIN_SERVER_REQ_CALLREMOTE_CONNECT_TIMEOUT, "'connect timeout' is being used" ); argStream.ReadIfNextIsNumber ( uiConnectTimeoutMs, 10000 ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadLuaArguments ( args ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain * luaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( luaMain ) { g_pGame->GetRemoteCalls ()->Call ( strURL, &args, luaMain, iLuaFunction, uiConnectionAttempts, uiConnectTimeoutMs ); lua_pushboolean ( luaVM, true ); return 1; } } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaResourceDefs::Load ( lua_State* luaVM ) { // func,err load( callback callbackFunction[, string name] ) CLuaFunctionRef iLuaFunction; SString strName; CScriptArgReader argStream ( luaVM ); argStream.ReadFunction ( iLuaFunction ); argStream.ReadString ( strName, "=(load)" ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Call supplied function to get all the bits // Should apply some limit here? SString strInput; CLuaArguments callbackArguments; CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); while ( pLuaMain ) { CLuaArguments returnValues; callbackArguments.Call ( pLuaMain, iLuaFunction, &returnValues ); if ( returnValues.Count () ) { CLuaArgument* returnedValue = *returnValues.IterBegin (); if ( returnedValue->GetType () == LUA_TSTRING ) { strInput += returnedValue->GetString (); continue; } } break; } const char* szChunkname = *strName; const char* cpInBuffer = strInput; uint uiInSize = strInput.length (); // Deobfuscate if required const char* cpBuffer; uint uiSize; if ( !g_pNet->DeobfuscateScript ( cpInBuffer, uiInSize, &cpBuffer, &uiSize, m_pResourceManager->GetResourceName ( luaVM ) + "/load" ) ) { SString strMessage ( "argument 2 is invalid. Please re-compile at http://luac.mtasa.com/", 0 ); argStream.SetCustomError ( strMessage ); cpBuffer = NULL; g_pCore->GetConsole ()->Print ( argStream.GetFullErrorMessage () ); g_pClientGame->TellServerSomethingImportant ( 1005, argStream.GetFullErrorMessage (), 3 ); } if ( !argStream.HasErrors () ) { CLuaShared::CheckUTF8BOMAndUpdate ( &cpBuffer, &uiSize ); if ( !CLuaMain::LuaLoadBuffer ( luaVM, cpBuffer, uiSize, szChunkname ) ) { // Ok return 1; } else { lua_pushnil ( luaVM ); lua_insert ( luaVM, -2 ); /* put before error message */ return 2; /* return nil plus error message */ } } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::SetBrowserAjaxHandler ( lua_State* luaVM ) { // bool setBrowserAjaxHandler ( browser browser, string URL[, function callback] ) CClientWebBrowser* pWebBrowser; SString strURL; CLuaFunctionRef callbackFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pWebBrowser ); argStream.ReadString ( strURL ); if ( argStream.NextIsNil () || argStream.NextIsNone () ) { if ( !argStream.HasErrors () ) { lua_pushboolean ( luaVM, pWebBrowser->RemoveAjaxHandler ( strURL ) ); return 1; } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); } else { argStream.ReadFunction ( callbackFunction ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain && VERIFY_FUNCTION ( callbackFunction ) ) { CResource* pResource = pLuaMain->GetResource (); CResourceManager * pResourceManager = m_pResourceManager; auto netId = pResource->GetNetID (); bool bResult = pWebBrowser->AddAjaxHandler ( strURL, [=] ( std::vector<SString>& vecGet, std::vector<SString>& vecPost ) -> const SString { // Make sure the resource is still running if ( !pResourceManager->Exists ( pResource ) || pResource->GetNetID() != netId ) { return ""; } // Make sure the function is valid if ( VERIFY_FUNCTION ( callbackFunction ) ) { CLuaArguments arguments; CLuaArguments getArguments; CLuaArguments postArguments; for ( auto&& param : vecGet ) getArguments.PushString ( param ); for ( auto&& param : vecPost ) postArguments.PushString ( param ); arguments.PushTable ( &getArguments ); arguments.PushTable ( &postArguments ); CLuaArguments result; arguments.Call ( pLuaMain, callbackFunction, &result ); if ( result.Count () == 0 ) return ""; CLuaArgument* returnedValue = *result.IterBegin (); if ( returnedValue->GetType () == LUA_TSTRING ) return returnedValue->GetString (); else return ""; } else return ""; } ); lua_pushboolean ( luaVM, bResult ); return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); } lua_pushboolean ( luaVM, false ); return 1; }