int CLuaFunctionDefs::GetResourceName ( lua_State* luaVM ) { // Verify arguments CResource* pResource = NULL; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pResource ); if ( !argStream.HasErrors ( ) ) { if ( pResource ) { // Grab its name and return it const char* szName = pResource->GetName (); if ( szName ) { lua_pushstring ( luaVM, szName ); return 1; } } else m_pScriptDebugging->LogBadPointer ( luaVM, "resource", 1 ); } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
// // CFunctionUseLogger::OnFunctionUse // void CFunctionUseLogger::OnFunctionUse( lua_State* luaVM, const char* szFunctionName, const char* szArgs, uint uiArgsSize ) { if ( m_strLogFilename.empty() ) return; CResource* pResource = g_pGame->GetResourceManager()->GetResourceFromLuaState( luaVM ); SString strResourceName = pResource ? pResource->GetName() : "Unknown"; SString strKey( "%s-%s", szFunctionName, *strResourceName ); SFuncCallRecord* pItem = MapFind( m_FuncCallRecordMap, strKey ); if ( !pItem ) { // Create new entry for this resource/function combo MapSet( m_FuncCallRecordMap, strKey, SFuncCallRecord() ); pItem = MapFind( m_FuncCallRecordMap, strKey ); pItem->strFunctionName = szFunctionName; pItem->strResourceName = strResourceName; pItem->uiCallCount = 0; pItem->timeFirstUsed = CTickCount::Now(); } pItem->uiCallCount++; if ( pItem->strExampleArgs.empty() ) pItem->strExampleArgs = SStringX( szArgs ).Left( 40 ); }
bool CLuaDefs::CanUseFunction ( const char* szFunction, lua_State* luaVM, bool bRestricted ) { // Get the belonging resource of the lua state CResource* pResource = m_pResourceManager->GetResourceFromLuaState ( luaVM ); if ( pResource ) { // Can we use the function? Return true so LUA can execute it if ( m_pACLManager->CanObjectUseRight ( pResource->GetName().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, szFunction, CAccessControlListRight::RIGHT_TYPE_FUNCTION, !bRestricted ) ) { return true; } else { // Otherwise just return false m_pScriptDebugging->LogBadAccess ( luaVM, szFunction ); return false; } } // Heh this should never happen return true; }
int CLuaFunctionDefs::Set ( lua_State* luaVM ) { CResource* pResource = m_pLuaManager->GetVirtualMachine ( luaVM )->GetResource (); SString strSetting; CLuaArguments Args; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strSetting ); argStream.ReadLuaArguments ( Args ); if ( !argStream.HasErrors () ) { std::string strResourceName = pResource->GetName (); std::string strJSON; Args.WriteToJSONString ( strJSON ); if ( g_pGame->GetSettings ()->Set ( strResourceName.c_str (), strSetting.c_str (), strJSON.c_str () ) ) { lua_pushboolean ( luaVM, true ); return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::GetResourceName ( lua_State* luaVM ) { // Verify arguments if ( lua_istype ( luaVM, 1, LUA_TLIGHTUSERDATA ) ) { // Grab the resource argument CResource* pResource = lua_toresource ( luaVM, 1 ); if ( pResource ) { // Grab its name and return it char* szName = pResource->GetName (); if ( szName ) { lua_pushstring ( luaVM, szName ); return 1; } } else m_pScriptDebugging->LogBadPointer ( luaVM, "getResourceName", "resource", 1 ); } else m_pScriptDebugging->LogBadType ( luaVM, "getResourceName" ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
SString CResourceManager::GetResourceName ( lua_State* luaVM ) { CResource* pResource = GetResourceFromLuaState( luaVM ); if ( pResource ) return pResource->GetName(); return ""; }
int CLuaFileDefs::fileDelete ( lua_State* luaVM ) { // bool fileDelete ( string filePath ) SString strFile; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strFile ); if ( argStream.NextIsUserData () ) m_pScriptDebugging->LogCustom ( luaVM, "fileDelete may be using an outdated syntax. Please check and update." ); if ( !argStream.HasErrors () ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { std::string strPath; // We have a resource argument? CResource* pThisResource = pLuaMain->GetResource (); CResource* pResource = pThisResource; if ( CResourceManager::ParseResourcePathInput ( strFile, pResource, &strPath, NULL ) ) { // Do we have permissions? if ( pResource == pThisResource || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) { // Make sure the dir exists so we can remove the file MakeSureDirExists ( strPath.c_str () ); if ( remove ( strPath.c_str () ) == 0 ) { // If file removed return success lua_pushboolean ( luaVM, true ); return 1; } else { // Output error m_pScriptDebugging->LogWarning ( luaVM, "%s; unable to delete file", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ) ); } } else m_pScriptDebugging->LogError ( luaVM, "%s failed; ModifyOtherObjects in ACL denied resource %s to access %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), pThisResource->GetName ().c_str (), pResource->GetName ().c_str () ); } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFileDefs::fileGetPath ( lua_State* luaVM ) { // string fileGetPath ( file theFile ) CScriptFile* pFile; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pFile ); if ( !argStream.HasErrors () ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { CResource* pThisResource = pLuaMain->GetResource (); CResource* pFileResource = pFile->GetResource (); SString strFilePath = pFile->GetFilePath (); // If the calling resource is not the resource the file resides in // we need to prepend :resourceName to the path if ( pThisResource != pFileResource ) { #ifdef MTA_CLIENT strFilePath = SString ( ":%s/%s", pFileResource->GetName (), *strFilePath ); #else strFilePath = SString ( ":%s/%s", *pFileResource->GetName (), *strFilePath ); #endif } lua_pushlstring ( luaVM, strFilePath, strFilePath.length () ); return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
// // Read next as resource or resource name. Result output as string // void MixedReadResourceString ( CScriptArgReader& argStream, SString& strOutResourceName ) { if ( !argStream.NextIsString () ) { CResource* pResource; argStream.ReadUserData ( pResource ); if ( pResource ) strOutResourceName = pResource->GetName (); } else argStream.ReadString ( strOutResourceName ); }
bool CLuaModuleManager::GetResourceName ( lua_State * luaVM, std::string& strName ) { if ( luaVM ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { CResource* pResource = pLuaMain->GetResource (); if ( pResource ) { strName = pResource->GetName (); return true; } } } return false; }
// // Called after a Lua function if post call hook has been installed // void CLuaDefs::DidUseFunction ( lua_CFunction f, lua_State* luaVM ) { // Quick cull of unknown pointer range - Deals with calls from client dll (when the server has been loaded into the same process) if ( CLuaCFunctions::IsNotFunction( f ) ) return; if ( !ms_TimingFunctionStack.empty () ) { // Check if the function used was being timed const STimingFunction& info = ms_TimingFunctionStack.back (); if ( info.f == f ) { // Finish the timing TIMEUS elapsedTime = GetTimeUs() - info.startTime; uint uiDeltaBytes = g_uiNetSentByteCounter - info.uiStartByteCount; // Record timing over a threshold if ( elapsedTime >= CPerfStatFunctionTiming::ms_PeakUsThresh || uiDeltaBytes > 1000 ) { CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( info.f ); if ( pFunction ) { CResource* pResource = g_pGame->GetResourceManager ()->GetResourceFromLuaState ( info.luaVM ); SString strResourceName = pResource ? pResource->GetName() : "unknown"; CPerfStatFunctionTiming::GetSingleton ()->UpdateTiming ( strResourceName, pFunction->GetName ().c_str (), elapsedTime, uiDeltaBytes ); } } ms_TimingFunctionStack.pop_back (); } } // Check if we should remove the hook if ( !g_pStats->bFunctionTimingActive && !g_pGame->GetDebugHookManager()->HasPostFunctionHooks() ) { ms_TimingFunctionStack.clear (); OutputDebugLine ( "[Lua] Removing PostCallHook" ); assert ( ms_bRegisterdPostCallHook ); ms_bRegisterdPostCallHook = false; lua_registerPostCallHook ( NULL ); } g_pGame->GetDebugHookManager()->OnPostFunction( f, luaVM ); }
int CLuaFileDefs::fileGetPath( lua_State* luaVM ) { // string fileGetPath ( file theFile ) CScriptFile* pFile; CScriptArgReader argStream( luaVM ); argStream.ReadUserData( pFile ); if ( !argStream.HasErrors( ) ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine( luaVM ); if ( pLuaMain ) { // We have a resource argument? CResource* pThisResource = pLuaMain->GetResource( ); CResource* pFileResource = pFile->GetResource( ); const SString& strFilePath = pFile->GetFilePath( ); SString outPath = strFilePath; // If the calling resource is not the resource the file resides in // we need to prepend :resourceName to the path if ( pThisResource != pFileResource ) { outPath = ":" + pFileResource->GetName() + "/" + outPath; } lua_pushlstring( luaVM, outPath.c_str( ), outPath.length( ) ); return 1; } } else m_pScriptDebugging->LogCustom( luaVM, argStream.GetFullErrorMessage( ) ); // Failed lua_pushboolean( luaVM, false ); return 1; }
// // Material/string // void MixedReadMaterialString(CScriptArgReader& argStream, CClientMaterial*& pMaterialElement) { pMaterialElement = NULL; if (!argStream.NextIsString()) argStream.ReadUserData(pMaterialElement); else { SString strFilePath; argStream.ReadString(strFilePath); // If no element, auto find/create one CLuaMain* pLuaMain = g_pClientGame->GetLuaManager()->GetVirtualMachine(argStream.m_luaVM); CResource* pParentResource = pLuaMain ? pLuaMain->GetResource() : NULL; if (pParentResource) { CResource* pFileResource = pParentResource; SString strPath, strMetaPath; if (CResourceManager::ParseResourcePathInput(strFilePath, pFileResource, &strPath, &strMetaPath)) { SString strUniqueName = SString("%s*%s*%s", pParentResource->GetName(), pFileResource->GetName(), strMetaPath.c_str()).Replace("\\", "/"); pMaterialElement = g_pClientGame->GetManager()->GetRenderElementManager()->FindAutoTexture(strPath, strUniqueName); if (pMaterialElement) { // Check if brand new if (!pMaterialElement->GetParent()) // Make it a child of the resource's file root ** CHECK Should parent be pFileResource, and element added to pParentResource's // ElementGroup? ** pMaterialElement->SetParent(pParentResource->GetResourceDynamicEntity()); } else argStream.SetCustomError(strFilePath, "Error loading image"); } else argStream.SetCustomError(strFilePath, "Bad file path"); } } }
int CLuaFunctionDefs::Get ( lua_State* luaVM ) { CResource* pResource = m_pLuaManager->GetVirtualMachine ( luaVM )->GetResource (); SString strSetting; CLuaArguments Args; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strSetting ); if ( !argStream.HasErrors () ) { unsigned int uiIndex = 0; bool bDeleteNode; // Extract attribute name if setting to be gotten has three parts i.e. resname.settingname.attributename SString strAttribute = "value"; vector < SString > Result; strSetting.Split ( ".", Result ); if ( Result.size () == 3 && Result[2].length () ) { strAttribute = Result[2]; } // Get the setting CXMLNode *pSubNode, *pNode = g_pGame->GetSettings ()->Get ( pResource->GetName ().c_str (), strSetting.c_str (), bDeleteNode ); // Only proceed if we have a valid node if ( pNode ) { // Argument count unsigned int uiArgCount = 1; // See if we need to return a table with single or multiple entries if ( pNode->GetSubNodeCount () == 0 ) { // See if required attribute exists CXMLAttribute *pAttribute = pNode->GetAttributes ().Find ( strAttribute.c_str () ); if ( !pAttribute ) { if ( bDeleteNode ) delete pNode; lua_pushboolean ( luaVM, false ); return 1; } // We only have a single entry for a specific setting, so output a string const std::string& strDataValue = pAttribute->GetValue (); if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) ) { // No valid JSON? Parse as plain text Args.PushString ( strDataValue ); } Args.PushArguments ( luaVM ); uiArgCount = Args.Count (); /* Don't output a table because although it is more consistent with the multiple values output below, ** due to lua's implementation of associative arrays (assuming we use the "setting-name", "value" key-value pairs) ** it would require the scripter to walk through an array that only has a single entry which is a Bad Thing, performance wise. ** PUSH_SETTING ( pNode ); Args.PushAsTable ( luaVM ); **/ } else { // We need to return multiply entries, so push all subnodes while ( ( pSubNode = pNode->FindSubNode ( "setting", uiIndex++ ) ) ) { CXMLAttributes& attributes = pSubNode->GetAttributes (); Args.PushString ( attributes.Find ( "name" )->GetValue () ); const std::string& strDataValue = attributes.Find ( "value" )->GetValue (); if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) ) { Args.PushString ( strDataValue ); } } // Push a table and return Args.PushAsTable ( luaVM ); } // Check if we have to delete the node if ( bDeleteNode ) delete pNode; return uiArgCount; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
bool CMainConfig::LoadExtended ( void ) { std::string strBuffer; int iTemp = 0, iResult = 0; // Grab the script debuglog if ( GetString ( m_pRootNode, "scriptdebuglogfile", strBuffer, 255, 1 ) == IS_SUCCESS ) { m_strScriptDebugLogFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); m_bScriptDebugLogEnabled = true; } else { m_bScriptDebugLogEnabled = false; } // Grab the script debuglog level iResult = GetInteger ( m_pRootNode, "scriptdebugloglevel", iTemp, 0, 3 ); if ( iResult == IS_SUCCESS ) { m_uiScriptDebugLogLevel = iTemp; } else { if ( iResult == INVALID_VALUE ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"scriptdebugloglevel\" tag; defaulting to 0\n" ); } m_uiScriptDebugLogLevel = 0; } iResult = GetInteger ( m_pRootNode, "htmldebuglevel", iTemp, 0, 3 ); if ( iResult == IS_SUCCESS ) { g_pGame->GetScriptDebugging()->SetHTMLLogLevel ( iTemp ); } else { if ( iResult == INVALID_VALUE ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"htmldebuglevel\" tag; defaulting to 0\n" ); } g_pGame->GetScriptDebugging()->SetHTMLLogLevel ( 0 ); } // Handle the <module> nodes CXMLNode* pNode = NULL; unsigned int uiCurrentIndex = 0; do { pNode = m_pRootNode->FindSubNode ( "module", uiCurrentIndex++ ); if ( pNode ) { CXMLAttribute* pAttribute = pNode->GetAttributes ().Find ( "src" ); if ( pAttribute ) { std::string strBuffer = pAttribute->GetValue (); SString strFilename ( "%s/modules/%s", g_pServerInterface->GetModManager ()->GetModPath (), strBuffer.c_str () ); if ( IsValidFilePath ( strBuffer.c_str () ) ) { m_pLuaManager->GetLuaModuleManager ()->_LoadModule ( strBuffer.c_str (), strFilename, false ); } } } } while ( pNode ); // Handle the <resource> nodes pNode = NULL; uiCurrentIndex = 0; bool bFoundDefault = false; bool bFirst = true; bool bNoProgress = false; do { // Grab the current script node pNode = m_pRootNode->FindSubNode ( "resource", uiCurrentIndex++ ); if ( pNode ) { // Grab its "src" attribute CXMLAttribute* pAttribute = pNode->GetAttributes ().Find ( "src" ); if ( pAttribute ) { // Grab the text in it and convert iwt to a path inside "scripts" std::string strBuffer = pAttribute->GetValue (); CResource * loadedResource = g_pGame->GetResourceManager ()->GetResource ( strBuffer.c_str () ); if ( !loadedResource ) { CLogger::LogPrintNoStamp ( "\n" ); CLogger::ErrorPrintf ( "Couldn't find resource %s. Check it exists.\n", strBuffer.c_str () ); bNoProgress = true; } else { loadedResource->SetPersistent ( true ); pAttribute = pNode->GetAttributes ().Find ( "startup" ); if ( pAttribute ) { std::string strStartup = pAttribute->GetValue (); if ( strStartup.compare ( "true" ) == 0 || strStartup.compare ( "yes" ) == 0 || strStartup.compare ( "1" ) == 0 ) { CLogger::SetOutputEnabled ( false ); if ( loadedResource->Start( NULL, true ) ) { CLogger::SetOutputEnabled ( true ); if ( !bNoProgress ) { if ( bFirst ) CLogger::LogPrint ( "Starting resources..." ); else CLogger::LogPrintNoStamp ( "." ); bFirst = false; } } else { CLogger::SetOutputEnabled ( true ); CLogger::LogPrintNoStamp ( "\n" ); CLogger::ErrorPrintf ( "Unable to start resource %s; %s\n", strBuffer.c_str (), loadedResource->GetFailureReason ().c_str () ); bNoProgress = true; } } } pAttribute = pNode->GetAttributes ().Find ( "protected" ); if ( pAttribute ) { std::string strProtected = pAttribute->GetValue (); if ( strProtected.compare ( "true" ) == 0 || strProtected.compare ( "yes" ) == 0 || strProtected.compare ( "1" ) == 0 ) loadedResource->SetProtected ( true ); } // Default resource pAttribute = pNode->GetAttributes ().Find ( "default" ); if ( pAttribute ) { if ( !bFoundDefault ) { std::string strProtected = pAttribute->GetValue (); if ( strProtected.compare ( "true" ) == 0 || strProtected.compare ( "yes" ) == 0 || strProtected.compare ( "1" ) == 0 ) { std::string strName = loadedResource->GetName (); if ( !strName.empty () ) { g_pGame->GetHTTPD ()->SetDefaultResource ( strName.c_str () ); } bFoundDefault = true; } } else { CLogger::LogPrintNoStamp ( "\n" ); CLogger::ErrorPrintf ( "More than one default resource specified!\n" ); bNoProgress = true; } } } } } } while ( pNode ); if ( !bNoProgress ) CLogger::LogPrintNoStamp ( "\n" ); // Register the commands RegisterCommand ( "update", CConsoleCommands::Update, false ); RegisterCommand ( "start", CConsoleCommands::StartResource, false ); RegisterCommand ( "stop", CConsoleCommands::StopResource, false ); RegisterCommand ( "stopall", CConsoleCommands::StopAllResources, false ); RegisterCommand ( "restart", CConsoleCommands::RestartResource, false ); RegisterCommand ( "refresh", CConsoleCommands::RefreshResources, false ); RegisterCommand ( "refreshall", CConsoleCommands::RefreshAllResources, false ); RegisterCommand ( "list", CConsoleCommands::ListResources, false ); RegisterCommand ( "info", CConsoleCommands::ResourceInfo, false ); RegisterCommand ( "install", CConsoleCommands::InstallResource, false ); RegisterCommand ( "upgrade", CConsoleCommands::UpgradeResources, false ); RegisterCommand ( "say", CConsoleCommands::Say, false ); RegisterCommand ( "teamsay", CConsoleCommands::TeamSay, false ); RegisterCommand ( "asay", CConsoleCommands::ASay, false ); RegisterCommand ( "msg", CConsoleCommands::Msg, false ); RegisterCommand ( "amsg", CConsoleCommands::AMsg, false ); RegisterCommand ( "me", CConsoleCommands::Me, false ); RegisterCommand ( "nick", CConsoleCommands::Nick, false ); RegisterCommand ( "login", CConsoleCommands::LogIn, false ); RegisterCommand ( "logout", CConsoleCommands::LogOut, false ); RegisterCommand ( "chgmypass", CConsoleCommands::ChgMyPass, false ); RegisterCommand ( "addaccount", CConsoleCommands::AddAccount, false ); RegisterCommand ( "delaccount", CConsoleCommands::DelAccount, false ); RegisterCommand ( "chgpass", CConsoleCommands::ChgPass, false ); RegisterCommand ( "shutdown", CConsoleCommands::Shutdown, false ); RegisterCommand ( "aexec", CConsoleCommands::AExec, false ); RegisterCommand ( "whois", CConsoleCommands::WhoIs, false ); RegisterCommand ( "whowas", CConsoleCommands::WhoWas, false ); RegisterCommand ( "debugscript", CConsoleCommands::DebugScript, false ); RegisterCommand ( "sudo", CConsoleCommands::Sudo, false ); RegisterCommand ( "help", CConsoleCommands::Help, false ); RegisterCommand ( "loadmodule", CConsoleCommands::LoadModule, false ); //RegisterCommand ( "unloadmodule", CConsoleCommands::UnloadModule, false ); //RegisterCommand ( "reloadmodule", CConsoleCommands::ReloadModule, false ); RegisterCommand ( "ver", CConsoleCommands::Ver, false ); RegisterCommand ( "sver", CConsoleCommands::Ver, false ); return true; }
int CLuaXMLDefs::xmlCreateFile ( lua_State* luaVM ) { #ifndef MTA_CLIENT if ( lua_type ( luaVM, 3 ) == LUA_TLIGHTUSERDATA ) m_pScriptDebugging->LogCustom ( luaVM, "xmlCreateFile may be using an outdated syntax. Please check and update." ); #endif // !MTA_CLIENT // Grab our resource CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { SString strInputPath, strRootNodeName; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strInputPath ); argStream.ReadString ( strRootNodeName ); if ( !argStream.HasErrors () ) { SString strPath; CResource* pThisResource = pLuaMain->GetResource (); CResource* pOtherResource = pThisResource; // clientside, this variable will always be pThisResource // Resolve other resource from name if ( CResourceManager::ParseResourcePathInput ( strInputPath, pOtherResource, &strPath, nullptr ) ) { #ifndef MTA_CLIENT // We have access to modify other resource? if ( pOtherResource == pThisResource || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) #endif // !MTA_CLIENT { // Make sure the dir exists so we can successfully make the file MakeSureDirExists ( strPath ); // Create the XML file CXMLFile * xmlFile = pLuaMain->CreateXML ( strPath ); if ( xmlFile ) { // Create its root node CXMLNode* pRootNode = xmlFile->CreateRootNode ( strRootNodeName ); if ( pRootNode ) { lua_pushxmlnode ( luaVM, pRootNode ); return 1; } // Destroy it if we failed pLuaMain->DestroyXML ( xmlFile ); } } #ifndef MTA_CLIENT else argStream.SetCustomError ( SString ( "ModifyOtherObjects in ACL denied resource '%s' to access '%s'", pThisResource->GetName ().c_str (), pOtherResource->GetName ().c_str () ), "Access denied" ); #endif // !MTA_CLIENT } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); } lua_pushboolean ( luaVM, false ); return 1; }
int CLuaXMLDefs::xmlCopyFile ( lua_State* luaVM ) { #ifndef MTA_CLIENT if ( lua_type ( luaVM, 3 ) == LUA_TLIGHTUSERDATA ) m_pScriptDebugging->LogCustom ( luaVM, "xmlCopyFile may be using an outdated syntax. Please check and update." ); #endif // !MTA_CLIENT // Grab our resource CLuaMain* pLUA = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLUA ) { SString strFile; CXMLNode* pSourceNode; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pSourceNode ); argStream.ReadString ( strFile ); if ( !argStream.HasErrors () ) { SString strPath; CResource* pThisResource = pLUA->GetResource (); CResource* pOtherResource = pThisResource; // Resolve other resource from name if ( CResourceManager::ParseResourcePathInput ( strFile, pOtherResource, &strPath, NULL ) ) { #ifndef MTA_CLIENT // We have access to modify other resource? if ( pOtherResource == pThisResource || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) #endif // !MTA_CLIENT { if ( pSourceNode ) { // Make sure the dir exists so we can successfully make the file MakeSureDirExists ( strPath ); // Grab the roots tag name std::string strRootTagName; strRootTagName = pSourceNode->GetTagName (); // Create the new XML file and its root node CXMLFile* pNewXML = pLUA->CreateXML ( strPath.c_str () ); if ( pNewXML ) { // Grab the root of the new XML CXMLNode* pNewRoot = pNewXML->CreateRootNode ( strRootTagName ); if ( pNewRoot ) { // Copy over the attributes from the root int iAttributeCount = pSourceNode->GetAttributes ().Count (); int i = 0; CXMLAttribute* pAttribute; for ( ; i < iAttributeCount; i++ ) { pAttribute = pSourceNode->GetAttributes ().Get ( i ); if ( pAttribute ) pNewRoot->GetAttributes ().Create ( *pAttribute ); } // Copy the stuff from the given source node to the destination root if ( pSourceNode->CopyChildrenInto ( pNewRoot, true ) ) { lua_pushxmlnode ( luaVM, pNewRoot ); return 1; } } // Delete the XML again pLUA->DestroyXML ( pNewXML ); } } else argStream.SetCustomError ( SString ( "Unable to copy XML file %s", strFile.c_str () ), "Bad filepath" ); } #ifndef MTA_CLIENT else argStream.SetCustomError ( SString ( "ModifyOtherObjects in ACL denied resource '%s' to access '%s'", pThisResource->GetName ().c_str (), pOtherResource->GetName ().c_str () ), "Access denied" ); #endif } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); } // Error lua_pushboolean ( luaVM, false ); return 1; }
char* CLuaArgument::WriteToString(char* szBuffer, int length) { switch (GetType()) { case LUA_TNIL: { snprintf(szBuffer, length, "0"); return szBuffer; } case LUA_TBOOLEAN: { if (GetBoolean()) snprintf(szBuffer, length, "true"); else snprintf(szBuffer, length, "false"); return szBuffer; } case LUA_TTABLE: { g_pGame->GetScriptDebugging()->LogError( NULL, "Cannot convert table to string (do not use tables as keys in tables if you want to send them over http/JSON)."); return NULL; } case LUA_TNUMBER: { int iNumber; if (ShouldUseInt(GetNumber(), &iNumber)) { snprintf(szBuffer, length, "%d", iNumber); return szBuffer; } else { snprintf(szBuffer, length, "%f", GetNumber()); return szBuffer; } break; } case LUA_TSTRING: { const char* szTemp = GetString().c_str(); unsigned short usLength = static_cast<unsigned short>(strlen(szTemp)); if (strlen(szTemp) == usLength) { snprintf(szBuffer, length, "%s", szTemp); return szBuffer; } else { g_pGame->GetScriptDebugging()->LogError(NULL, "String is too long. Limit is 65535 characters."); } break; } case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: { CElement* pElement = GetElement(); CResource* pResource = g_pGame->GetResourceManager()->GetResourceFromScriptID(reinterpret_cast<unsigned long>(GetUserData())); if (pElement) { snprintf(szBuffer, length, "#E#%d", (int)pElement->GetID().Value()); return szBuffer; } else if (pResource) { snprintf(szBuffer, length, "#R#%s", pResource->GetName().c_str()); return szBuffer; } else { g_pGame->GetScriptDebugging()->LogError(NULL, "Couldn't convert element to string, only valid elements can be sent."); return NULL; } break; } default: { g_pGame->GetScriptDebugging()->LogError(NULL, "Couldn't convert argument to string, unsupported data type. Use String, Number, Boolean or Element."); return NULL; } } return NULL; }
json_object* CLuaArgument::WriteToJSONObject(bool bSerialize, CFastHashMap<CLuaArguments*, unsigned long>* pKnownTables) { switch (GetType()) { case LUA_TNIL: { return json_object_new_int(0); } case LUA_TBOOLEAN: { return json_object_new_boolean(GetBoolean()); } case LUA_TTABLE: { ulong* pTableId; if (pKnownTables && (pTableId = MapFind(*pKnownTables, m_pTableData))) { // Self-referencing table char szTableID[10]; snprintf(szTableID, sizeof(szTableID), "^T^%lu", *pTableId); return json_object_new_string(szTableID); } else { return m_pTableData->WriteTableToJSONObject(bSerialize, pKnownTables); } } case LUA_TNUMBER: { int iNumber; if (ShouldUseInt(GetNumber(), &iNumber)) { return json_object_new_int(iNumber); } else { return json_object_new_double(GetNumber()); } break; } case LUA_TSTRING: { SString strTemp = GetString(); if (strTemp.length() > 3 && strTemp[0] == '^' && strTemp[2] == '^' && strTemp[1] != '^') { // Prevent clash with how MTA stores elements, resources and table refs as strings strTemp[2] = '~'; } if (strTemp.length() <= USHRT_MAX) { return json_object_new_string_len((char*)strTemp.c_str(), strTemp.length()); } else { g_pGame->GetScriptDebugging()->LogError(NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters."); } break; } case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: { CElement* pElement = GetElement(); CResource* pResource = g_pGame->GetResourceManager()->GetResourceFromScriptID(reinterpret_cast<unsigned long>(GetUserData())); // Elements are dynamic, so storing them is potentially unsafe if (pElement && bSerialize) { char szElementID[10] = {0}; snprintf(szElementID, 9, "^E^%d", (int)pElement->GetID().Value()); return json_object_new_string(szElementID); } else if (pResource) { char szElementID[MAX_RESOURCE_NAME_LENGTH + 4] = {0}; snprintf(szElementID, MAX_RESOURCE_NAME_LENGTH + 3, "^R^%s", pResource->GetName().c_str()); return json_object_new_string(szElementID); } else { if (pElement) // eg toJSON() with valid element g_pGame->GetScriptDebugging()->LogError(NULL, "Couldn't convert userdata argument to JSON, elements not allowed for this function."); else if (!bSerialize) // eg toJSON() with invalid element g_pGame->GetScriptDebugging()->LogError( NULL, "Couldn't convert userdata argument to JSON, only valid resources can be included for this function."); else g_pGame->GetScriptDebugging()->LogError(NULL, "Couldn't convert userdata argument to JSON, only valid elements or resources can be included."); return NULL; } break; } default: { g_pGame->GetScriptDebugging()->LogError( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element."); return NULL; } } return NULL; }
json_object * CLuaArgument::WriteToJSONObject ( bool bSerialize, std::map < CLuaArguments*, unsigned long > * pKnownTables ) { switch ( GetType () ) { case LUA_TNIL: { return json_object_new_int(0); } case LUA_TBOOLEAN: { return json_object_new_boolean(GetBoolean ()); } case LUA_TTABLE: { if ( pKnownTables && pKnownTables->find ( m_pTableData ) != pKnownTables->end () ) { char szTableID[10]; _snprintf ( szTableID, sizeof(szTableID), "^T^%lu", pKnownTables->find ( m_pTableData )->second ); return json_object_new_string ( szTableID ); } else { return m_pTableData->WriteTableToJSONObject ( bSerialize, pKnownTables ); } } case LUA_TNUMBER: { float fNum = static_cast < float > ( GetNumber () ); int iNum = static_cast < int > ( GetNumber () ); if ( iNum == fNum ) { return json_object_new_int(iNum); } else { return json_object_new_double(fNum); } break; } case LUA_TSTRING: { const char* szTemp = GetString ().c_str (); unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) ); if ( strlen ( szTemp ) == usLength ) { return json_object_new_string_len ( (char *)szTemp, usLength ); } else { g_pGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters." ); } break; } case LUA_TLIGHTUSERDATA: { CElement* pElement = GetElement (); CResource* pResource = reinterpret_cast < CResource* > ( GetLightUserData() ); // Elements are dynamic, so storing them is potentially unsafe if ( pElement && bSerialize ) { char szElementID[10] = {0}; _snprintf ( szElementID, 9, "^E^%d", (int)pElement->GetID() ); return json_object_new_string ( szElementID ); } else if ( VERIFY_RESOURCE(pResource) ) { char szElementID[MAX_RESOURCE_NAME_LENGTH+4] = {0}; _snprintf ( szElementID, MAX_RESOURCE_NAME_LENGTH+3, "^R^%s", pResource->GetName().c_str () ); return json_object_new_string ( szElementID ); } else { g_pGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, only valid elements can be sent." ); return NULL; } break; } default: { g_pGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element." ); return NULL; } } return NULL; }
bool CMainConfig::LoadExtended ( void ) { std::string strBuffer; int iTemp = 0, iResult = 0; // minclientversion - Minimum client version or kick GetString ( m_pRootNode, "minclientversion", m_strMinClientVersion ); if ( m_strMinClientVersion != "" && !IsValidVersionString ( m_strMinClientVersion ) ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"minclientversion\"\n" ); m_strMinClientVersion = ""; } // recommendedclientversion - Minimum client version or spam GetString ( m_pRootNode, "recommendedclientversion", m_strRecommendedClientVersion ); if ( m_strRecommendedClientVersion != "" && !IsValidVersionString ( m_strRecommendedClientVersion ) ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"recommendedclientversion\"\n" ); m_strRecommendedClientVersion = ""; } // Grab the script debuglog if ( GetString ( m_pRootNode, "scriptdebuglogfile", strBuffer, 1, 255 ) == IS_SUCCESS ) { m_strScriptDebugLogFile = g_pServerInterface->GetModManager ()->GetAbsolutePath ( strBuffer.c_str () ); m_bScriptDebugLogEnabled = true; } else { m_bScriptDebugLogEnabled = false; } // Grab the script debuglog level iResult = GetInteger ( m_pRootNode, "scriptdebugloglevel", iTemp, 0, 3 ); if ( iResult == IS_SUCCESS ) { m_uiScriptDebugLogLevel = iTemp; } else { if ( iResult == INVALID_VALUE ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"scriptdebugloglevel\" tag; defaulting to 0\n" ); } m_uiScriptDebugLogLevel = 0; } iResult = GetInteger ( m_pRootNode, "htmldebuglevel", iTemp, 0, 3 ); if ( iResult == IS_SUCCESS ) { g_pGame->GetScriptDebugging()->SetHTMLLogLevel ( iTemp ); } else { if ( iResult == INVALID_VALUE ) { CLogger::LogPrint ( "WARNING: Invalid value specified in \"htmldebuglevel\" tag; defaulting to 0\n" ); } g_pGame->GetScriptDebugging()->SetHTMLLogLevel ( 0 ); } // Handle the <module> nodes CXMLNode* pNode = NULL; unsigned int uiCurrentIndex = 0; do { pNode = m_pRootNode->FindSubNode ( "module", uiCurrentIndex++ ); if ( pNode ) { CXMLAttribute* pAttribute = pNode->GetAttributes ().Find ( "src" ); if ( pAttribute ) { std::string strBuffer = pAttribute->GetValue (); SString strFilename ( "%s/modules/%s", g_pServerInterface->GetModManager ()->GetModPath (), strBuffer.c_str () ); if ( IsValidFilePath ( strBuffer.c_str () ) ) { m_pLuaManager->GetLuaModuleManager ()->_LoadModule ( strBuffer.c_str (), strFilename, false ); } } } } while ( pNode ); // Handle the <resource> nodes pNode = NULL; uiCurrentIndex = 0; bool bFoundDefault = false; CLogger::SetMinLogLevel ( LOGLEVEL_MEDIUM ); CLogger::LogPrint ( "Starting resources..." ); CLogger::ProgressDotsBegin (); do { if ( g_pServerInterface->IsRequestingExit () ) return false; // Grab the current script node pNode = m_pRootNode->FindSubNode ( "resource", uiCurrentIndex++ ); if ( pNode ) { // Grab its "src" attribute CXMLAttribute* pAttribute = pNode->GetAttributes ().Find ( "src" ); if ( pAttribute ) { // Grab the text in it and convert iwt to a path inside "scripts" std::string strBuffer = pAttribute->GetValue (); CResource * loadedResource = g_pGame->GetResourceManager ()->GetResource ( strBuffer.c_str () ); if ( !loadedResource ) { CLogger::ErrorPrintf ( "Couldn't find resource %s. Check it exists.\n", strBuffer.c_str () ); } else { loadedResource->SetPersistent ( true ); pAttribute = pNode->GetAttributes ().Find ( "startup" ); if ( pAttribute ) { std::string strStartup = pAttribute->GetValue (); if ( strStartup.compare ( "true" ) == 0 || strStartup.compare ( "yes" ) == 0 || strStartup.compare ( "1" ) == 0 ) { if ( loadedResource->Start( NULL, true ) ) { CLogger::ProgressDotsUpdate (); } else { CLogger::ErrorPrintf ( "Unable to start resource %s; %s\n", strBuffer.c_str (), loadedResource->GetFailureReason ().c_str () ); } } } pAttribute = pNode->GetAttributes ().Find ( "protected" ); if ( pAttribute ) { std::string strProtected = pAttribute->GetValue (); if ( strProtected.compare ( "true" ) == 0 || strProtected.compare ( "yes" ) == 0 || strProtected.compare ( "1" ) == 0 ) loadedResource->SetProtected ( true ); } // Default resource pAttribute = pNode->GetAttributes ().Find ( "default" ); if ( pAttribute ) { if ( !bFoundDefault ) { std::string strDefault = pAttribute->GetValue (); if ( strDefault.compare ( "true" ) == 0 || strDefault.compare ( "yes" ) == 0 || strDefault.compare ( "1" ) == 0 ) { std::string strName = loadedResource->GetName (); if ( !strName.empty () ) { g_pGame->GetHTTPD ()->SetDefaultResource ( strName.c_str () ); } bFoundDefault = true; } } else { CLogger::ErrorPrintf ( "More than one default resource specified!\n" ); } } } } } } while ( pNode ); CLogger::ProgressDotsEnd (); CLogger::SetMinLogLevel ( LOGLEVEL_LOW ); // Register the commands RegisterCommand ( "start", CConsoleCommands::StartResource, false ); RegisterCommand ( "stop", CConsoleCommands::StopResource, false ); RegisterCommand ( "stopall", CConsoleCommands::StopAllResources, false ); RegisterCommand ( "restart", CConsoleCommands::RestartResource, false ); RegisterCommand ( "refresh", CConsoleCommands::RefreshResources, false ); RegisterCommand ( "refreshall", CConsoleCommands::RefreshAllResources, false ); RegisterCommand ( "list", CConsoleCommands::ListResources, false ); RegisterCommand ( "info", CConsoleCommands::ResourceInfo, false ); RegisterCommand ( "upgrade", CConsoleCommands::UpgradeResources, false ); RegisterCommand ( "check", CConsoleCommands::CheckResources, false ); RegisterCommand ( "say", CConsoleCommands::Say, false ); RegisterCommand ( "teamsay", CConsoleCommands::TeamSay, false ); //RegisterCommand ( "asay", CConsoleCommands::ASay, false ); // Not working RegisterCommand ( "msg", CConsoleCommands::Msg, false ); //RegisterCommand ( "amsg", CConsoleCommands::AMsg, false ); // Not working RegisterCommand ( "me", CConsoleCommands::Me, false ); RegisterCommand ( "nick", CConsoleCommands::Nick, false ); RegisterCommand ( "login", CConsoleCommands::LogIn, false ); RegisterCommand ( "logout", CConsoleCommands::LogOut, false ); RegisterCommand ( "chgmypass", CConsoleCommands::ChgMyPass, false ); RegisterCommand ( "addaccount", CConsoleCommands::AddAccount, false ); RegisterCommand ( "delaccount", CConsoleCommands::DelAccount, false ); RegisterCommand ( "chgpass", CConsoleCommands::ChgPass, false ); RegisterCommand ( "shutdown", CConsoleCommands::Shutdown, false ); RegisterCommand ( "aexec", CConsoleCommands::AExec, false ); RegisterCommand ( "whois", CConsoleCommands::WhoIs, false ); RegisterCommand ( "whowas", CConsoleCommands::WhoWas, false ); RegisterCommand ( "debugscript", CConsoleCommands::DebugScript, false ); //RegisterCommand ( "sudo", CConsoleCommands::Sudo, false ); // Not working RegisterCommand ( "help", CConsoleCommands::Help, false ); RegisterCommand ( "loadmodule", CConsoleCommands::LoadModule, false ); //RegisterCommand ( "unloadmodule", CConsoleCommands::UnloadModule, false ); //RegisterCommand ( "reloadmodule", CConsoleCommands::ReloadModule, false ); RegisterCommand ( "ver", CConsoleCommands::Ver, false ); RegisterCommand ( "sver", CConsoleCommands::Ver, false ); RegisterCommand ( "ase", CConsoleCommands::Ase, false ); RegisterCommand ( "openports", CConsoleCommands::OpenPortsTest, false ); RegisterCommand ( "debugdb", CConsoleCommands::SetDbLogLevel, false ); RegisterCommand ( "reloadbans", CConsoleCommands::ReloadBans, false ); RegisterCommand ( "aclrequest", CConsoleCommands::AclRequest, false ); RegisterCommand ( "debugjoinflood", CConsoleCommands::DebugJoinFlood, false ); #if defined(MTA_DEBUG) || defined(MTA_BETA) RegisterCommand ( "sfakelag", CConsoleCommands::FakeLag, false ); #endif return true; }
int CLuaFileDefs::fileCreate ( lua_State* luaVM ) { // file fileCreate ( string filePath ) SString strFile; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strFile ); if ( argStream.NextIsUserData () ) m_pScriptDebugging->LogCustom ( luaVM, "fileCreate may be using an outdated syntax. Please check and update." ); if ( !argStream.HasErrors () ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Grab the filename std::string strAbsPath; std::string strSubPath; // We have a resource argument? CResource* pThisResource = pLuaMain->GetResource (); CResource* pResource = pThisResource; if ( CResourceManager::ParseResourcePathInput ( strFile, pResource, &strAbsPath, &strSubPath ) ) { // Do we have permissions? if ( pResource == pThisResource || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) { // Make sure the destination folder exist so we can create the file MakeSureDirExists ( strAbsPath.c_str () ); // Create the file to create CScriptFile* pFile = new CScriptFile ( pThisResource->GetScriptID(), strSubPath.c_str (), DEFAULT_MAX_FILESIZE ); assert ( pFile ); // Try to load it if ( pFile->Load ( pResource, CScriptFile::MODE_CREATE ) ) { // Add it to the scrpt resource element group CElementGroup* pGroup = pThisResource->GetElementGroup (); if ( pGroup ) { pGroup->Add ( pFile ); } // Success. Return the file. lua_pushelement ( luaVM, pFile ); return 1; } else { // Delete the file again delete pFile; // Output error m_pScriptDebugging->LogWarning ( luaVM, "%s; unable to load file", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ) ); } } else m_pScriptDebugging->LogError ( luaVM, "%s failed; ModifyOtherObjects in ACL denied resource %s to access %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), pThisResource->GetName ().c_str (), pResource->GetName ().c_str () ); } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::Call ( lua_State* luaVM ) { CResource * pResource = NULL; SString strFunctionName = ""; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pResource ); argStream.ReadString ( strFunctionName ); if ( !argStream.HasErrors ( ) ) { // Grab our VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Grab this resource CResource* pThisResource = pLuaMain->GetResource (); if ( pThisResource ) { if ( pResource ) { //Get the target Lua VM lua_State* targetLuaVM = pResource->GetVM()->GetVM(); // Read out the vargs CLuaArguments args; args.ReadArguments ( luaVM, 3 ); CLuaArguments returns; LUA_CHECKSTACK ( targetLuaVM, 1 ); // Ensure some room //Lets grab the original hidden variables so we can restore them later lua_getglobal ( targetLuaVM, "sourceResource" ); CLuaArgument OldResource ( luaVM, -1 ); lua_pop( targetLuaVM, 1 ); lua_getglobal ( targetLuaVM, "sourceResourceRoot" ); CLuaArgument OldResourceRoot ( luaVM, -1 ); lua_pop( targetLuaVM, 1 ); //Set the new values for the current sourceResource, and sourceResourceRoot lua_pushresource ( targetLuaVM, pThisResource ); lua_setglobal ( targetLuaVM, "sourceResource" ); lua_pushelement ( targetLuaVM, pThisResource->GetResourceEntity() ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); // Call the exported function with the given name and the args if ( pResource->CallExportedFunction ( strFunctionName, args, returns, *pThisResource ) ) { // Push return arguments returns.PushArguments ( luaVM ); //Restore the old variables OldResource.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResource" ); OldResourceRoot.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); return returns.Count (); } else { //Restore the old variables OldResource.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResource" ); OldResourceRoot.Push ( targetLuaVM ); lua_setglobal ( targetLuaVM, "sourceResourceRoot" ); m_pScriptDebugging->LogError ( luaVM, "call: failed to call '%s:%s'", pResource->GetName (), *strFunctionName ); } } else { m_pScriptDebugging->LogBadType ( luaVM ); } } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
// Get ( [resource requesting the query], [setting name], [return buffer], [return buffer length], [delete node] ) // // bDeleteNode contains a boolean to indicate whether the table contains one entry or multiple entries. If multiple // entries are used, the resource's storage node (which only gets deleted on resource stop) is used to store any // matching nodes that you have access to. The boolean is meant to let the caller know that the XML node that is // returned should be deleted after usage, for the sake of memory usage. // // Returns the XML node. // // If ( bDeleteNode == TRUE ), always remove the XML node after you're done with it! CXMLNode *CSettings::Get(const char *szLocalResource, const char *szSetting, bool &bDeleteNode) { CResource * pResource; CXMLNode * pNode = NULL; char szQueryResource[MAX_RESOURCE_LENGTH] = {0}; SettingStatus eStatus = NotFound; bDeleteNode = false; // Get the temporary storage node associated with this resource CResource *pLocalResource = m_pResourceManager->GetResource(szLocalResource); CXMLNode * pStorage = pLocalResource ? pLocalResource->GetStorageNode() : nullptr; // Get the actual resource name from the specified setting, and get the resource class if (!GetResourceName(szSetting, szQueryResource, MAX_RESOURCE_LENGTH - 1)) { // No name was specified, so use the local resource pResource = m_pResourceManager->GetResource(szLocalResource); } else pResource = m_pResourceManager->GetResource(szQueryResource); // If we have a valid resource if (pResource) { CXMLNode *pSource = pResource->GetSettingsNode(); // Try to get the value for the appropriate setting from the settings registry if (pStorage) { pNode = Get(m_pNodeGlobalSettings, pStorage, "", szLocalResource, szSetting, bDeleteNode, eStatus); // If we're getting all of the resource's settings, throw in those from the meta as well if (bDeleteNode) { SettingStatus eMetaStatus = NotFound; CXMLNode * pMetaNode = Get(pSource, pStorage, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eMetaStatus, pNode); if (eMetaStatus == Found) { eStatus = eMetaStatus; pNode = pMetaNode; } } } // See if we found a matching setting if (eStatus == Found) return pNode; // Found else if (eStatus == NotFound) { // Not found, continue searching // Try to get the value for the appropriate setting from the resource's meta XML file if (pSource) pNode = Get(pSource, pStorage, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus); if (eStatus == Found) return pNode; } } else { // Try to get the value for the appropriate setting from the settings registry pNode = Get(m_pNodeGlobalSettings, pStorage, "", szLocalResource, szSetting, bDeleteNode, eStatus); if (eStatus == Found) return pNode; } return NULL; // No access or no settings found }
int CLuaFunctionDefs::shutdown ( lua_State* luaVM ) { SString strReason; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strReason, "No reason specified" ); if ( !argStream.HasErrors () ) { // Get the VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { // Get the resource CResource* pResource = pLuaMain->GetResource (); if ( pResource ) { // Log it CLogger::LogPrintf ( "Server shutdown as requested by resource %s (%s)\n", pResource->GetName ().c_str (), *strReason ); // Shut it down g_pGame->SetIsFinished ( true ); // Success lua_pushboolean ( luaVM, true ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); // Fail lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFileDefs::fileRename ( lua_State* luaVM ) { // bool fileRename ( string filePath, string newFilePath ) SString strCurFile; SString strNewFile; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strCurFile ); argStream.ReadString ( strNewFile ); if ( !argStream.HasErrors () ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { std::string strCurPath; std::string strNewPath; std::string strCurSubPath; std::string strNewSubPath; // We have a resource arguments? CResource* pThisResource = pLuaMain->GetResource (); CResource* pCurResource = pThisResource; CResource* pNewResource = pThisResource; if ( CResourceManager::ParseResourcePathInput ( strCurFile, pCurResource, &strCurPath, &strCurSubPath ) && CResourceManager::ParseResourcePathInput ( strNewFile, pNewResource, &strNewPath, &strNewSubPath ) ) { // Do we have permissions? if ( ( pCurResource == pThisResource && pNewResource == pThisResource ) || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) { string strCurFilePath; string strNewFilePath; // Does `current` file path exist and `new` file path doesn't exist? if ( pCurResource->GetFilePath ( strCurSubPath.c_str(), strCurFilePath ) && !pNewResource->GetFilePath ( strNewSubPath.c_str(), strNewFilePath ) ) { // Make sure the destination folder exist so we can move the file MakeSureDirExists ( strNewPath.c_str () ); if ( FileRename ( strCurPath.c_str (), strNewPath.c_str () ) ) { // If file renamed/moved return success lua_pushboolean ( luaVM, true ); return 1; } else { // Output error m_pScriptDebugging->LogWarning ( luaVM, "%s; unable to rename/move file", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ) ); } } else { // Output error m_pScriptDebugging->LogWarning ( luaVM, "%s failed; source file doesn't exist or destination file already exists", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ) ); } } // Do we have not permissions to both - `current` and `new` resources? else if ( pThisResource != pCurResource && pThisResource != pNewResource ) m_pScriptDebugging->LogError ( luaVM, "%s failed; ModifyOtherObjects in ACL denied resource %s to access %s and %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), pThisResource->GetName ().c_str (), pCurResource->GetName ().c_str (), pNewResource->GetName ().c_str () ); // Do we have not permissions to `current` resource? else if ( pThisResource != pCurResource && pThisResource == pNewResource ) m_pScriptDebugging->LogError ( luaVM, "%s failed; ModifyOtherObjects in ACL denied resource %s to access %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), pThisResource->GetName ().c_str (), pCurResource->GetName ().c_str () ); // Do we have not permissions to `new` resource? else m_pScriptDebugging->LogError ( luaVM, "%s failed; ModifyOtherObjects in ACL denied resource %s to access %s", lua_tostring ( luaVM, lua_upvalueindex ( 1 ) ), pThisResource->GetName ().c_str (), pNewResource->GetName ().c_str () ); } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
// Set ( resource requesting the query, setting name, content ) bool CSettings::Set(const char *szLocalResource, const char *szSetting, const char *szContent) { CXMLNode * pNode; CResource * pResource; CXMLAttributes *pAttributes; char szBuffer[MAX_SETTINGS_LENGTH] = {0}; char szQueryResource[MAX_RESOURCE_LENGTH] = {0}; SettingStatus eStatus; bool bDeleteNode, bExists; SString strOldValue; // Check for empty strings if (strlen(szSetting) < 1) return false; // Get the actual resource name from the specified setting, and get the resource class if (!GetResourceName(szSetting, szQueryResource, MAX_RESOURCE_LENGTH - 1)) { // No name was specified, so use the local resource pResource = m_pResourceManager->GetResource(szLocalResource); } else pResource = m_pResourceManager->GetResource(szQueryResource); // If we have a valid resource if (pResource) { CXMLNode *pSource = pResource->GetSettingsNode(); // Check whether the setting exists in the settings registry pNode = Get(m_pNodeGlobalSettings, NULL, "", szLocalResource, szSetting, bDeleteNode, eStatus); bExists = true; // Default value // Try to get the value for the appropriate setting from the resource's meta XML file if (eStatus == NotFound && pSource) { pNode = Get(pSource, NULL, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus); bExists = false; // There's no node in the settings registry, so we create one } // See if we have access if (eStatus != NoAccess) { // See if we have a prefix bool bPrefix = HasPrefix(szSetting[0]); // If no resource name was specified, use the local resource name if (!HasResourceName(szSetting)) { // If we have a prefix, move it from szSetting and put it at the beginning if (bPrefix) snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s.%s", szSetting[0], szLocalResource, szSetting + 1); else snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%s.%s", szLocalResource, szSetting); } else { // If we have a prefix, move it from szSetting and put it at the beginning if (bPrefix) snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s", szSetting[0], szSetting + 1); else strncpy(szBuffer, szSetting, MAX_SETTINGS_LENGTH - 1); } if (!bExists || !pNode) { // No existing settings registry entry, so create a new setting CreateSetting(m_pNodeGlobalSettings, szBuffer, szContent); } else { // Existing settings registry entry // Get the attributes pAttributes = &(pNode->GetAttributes()); // Abort if this value isnt public (but protected or private), and if the local resource // (doing the query) doesn't equal the setting's resource name if (GetAccessType(pAttributes->Find("name")->GetValue()[0]) != CSettings::Public && stricmp(pResource->GetName().c_str(), szLocalResource) != 0) return false; // Get the node's current value strOldValue = pAttributes->Find("value")->GetValue(); // Set the node's value pAttributes->Find("value")->SetValue(szContent); // If a prefix was given, set the node's name (to override any access operators) if (bPrefix) pAttributes->Find("name")->SetValue(szBuffer); } // Trigger onSettingChange CLuaArguments Arguments; Arguments.PushString(szSetting); if (strOldValue.length() > 0) Arguments.PushString(strOldValue.c_str()); else Arguments.PushNil(); Arguments.PushString(szContent); g_pGame->GetMapManager()->GetRootElement()->CallEvent("onSettingChange", Arguments); // Save the XML file if (m_pFile->Write()) return true; CLogger::ErrorPrintf("Error saving '%s'\n", FILENAME_SETTINGS); } } return false; }
int CLuaFileDefs::fileCopy ( lua_State* luaVM ) { // bool fileCopy ( string filePath, string newFilePath, bool overwrite = false ) SString filePath; SString newFilePath; bool bOverwrite; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( filePath ); argStream.ReadString ( newFilePath ); argStream.ReadBool ( bOverwrite, false ); if ( !argStream.HasErrors () ) { // Grab our lua VM CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( pLuaMain ) { std::string strCurAbsPath; std::string strNewAbsPath; std::string strCurMetaPath; std::string strNewMetaPath; // We have a resource arguments? CResource* pThisResource = pLuaMain->GetResource (); CResource* pCurResource = pThisResource; CResource* pNewResource = pThisResource; if ( CResourceManager::ParseResourcePathInput ( filePath, pCurResource, &strCurAbsPath, &strCurMetaPath ) && CResourceManager::ParseResourcePathInput ( newFilePath, pNewResource, &strNewAbsPath, &strNewMetaPath ) ) { // Do we have permissions? if ( ( pCurResource == pThisResource && pNewResource == pThisResource ) || m_pACLManager->CanObjectUseRight ( pThisResource->GetName ().c_str (), CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE, "ModifyOtherObjects", CAccessControlListRight::RIGHT_TYPE_GENERAL, false ) ) { std::string strCurFilePath; // Same as strCurAbsPath std::string strNewFilePath; // Same as strNewAbsPath // Does source file exist? if ( pCurResource->GetFilePath ( strCurMetaPath.c_str(), strCurFilePath ) ) { // Does destination file exist? if ( !bOverwrite && pNewResource->GetFilePath ( strNewMetaPath.c_str(), strNewFilePath ) ) { argStream.SetCustomError ( SString ( "Destination file already exists (%s)", *newFilePath ), "File error" ); } else { // Make sure the destination folder exists so we can copy the file MakeSureDirExists ( strNewAbsPath ); if ( FileCopy ( strCurAbsPath, strNewAbsPath ) ) { // If file copied return success lua_pushboolean ( luaVM, true ); return 1; } else { argStream.SetCustomError ( SString ( "Unable to copy %s to %s", *filePath, *newFilePath ), "File error" ); } } } else { argStream.SetCustomError ( SString ( "Source file doesn't exist (%s)", *filePath ), "File error" ); } } else { // Make permissions error message SString strWho; if ( pThisResource != pCurResource ) strWho += pCurResource->GetName (); if ( pThisResource != pNewResource ) { if ( !strWho.empty () ) strWho += " and "; strWho += pNewResource->GetName (); } argStream.SetCustomError ( SString ( "ModifyOtherObjects in ACL denied resource %s to access %s", pThisResource->GetName ().c_str (), *strWho ), "ACL issue" ); } } } } if ( argStream.HasErrors () ) m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); // Failed lua_pushboolean ( luaVM, false ); return 1; }
int CLuaFunctionDefs::GetResourceDynamicElementRoot ( lua_State* luaVM ) { CResource* pResource = NULL; CScriptArgReader argStream ( luaVM ); argStream.ReadUserData ( pResource ); if ( !argStream.HasErrors () ) { if ( pResource ) { CClientEntity* pEntity = pResource->GetResourceDynamicEntity(); if ( pEntity ) { lua_pushelement ( luaVM, pEntity ); return 1; } else m_pScriptDebugging->LogError ( luaVM, "getResourceDynamicElementRoot: Resource %s Is Not Currently Running", pResource->GetName() ); } else m_pScriptDebugging->LogBadPointer ( luaVM, "resource", 1 ); } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean ( luaVM, false ); return 1; }
int CLuaACLDefs::hasObjectPermissionTo ( lua_State* luaVM ) { // bool hasObjectPermissionTo ( string / element theObject, string theAction [, bool defaultPermission = true ] ) CResource* pResource = NULL; CElement* pElement = NULL; SString strObject; SString strRightName; bool bDefault; CAccessControlListGroupObject::EObjectType eObjectType; CScriptArgReader argStream ( luaVM ); if ( argStream.NextIsUserDataOfType < CResource > () ) argStream.ReadUserData ( pResource ); else if ( argStream.NextIsUserDataOfType < CElement > () ) argStream.ReadUserData ( pElement ); else argStream.ReadString ( strObject ); argStream.ReadString ( strRightName ); argStream.ReadBool ( bDefault, true ); if ( !argStream.HasErrors () ) { if ( pResource ) { // Grab the resource's name strObject = pResource->GetName (); eObjectType = CAccessControlListGroupObject::OBJECT_TYPE_RESOURCE; } else if ( pElement ) { // Grab the client this player/console/whatever is CClient* pClient = pElement->GetClient (); if ( pClient ) { // Get his account CAccount* pAccount = pClient->GetAccount (); if ( pAccount ) { // Grab the username strObject = pAccount->GetName (); eObjectType = CAccessControlListGroupObject::OBJECT_TYPE_USER; } } } else { // Extract the object name itself including the type const char * szName = CAccessControlListManager::ExtractObjectName ( strObject.c_str (), eObjectType ); strObject = szName ? szName : ""; } // Got a string? if ( !strObject.empty () ) { // Extract the right name itself including the type CAccessControlListRight::ERightType eRightType; strRightName = CAccessControlListManager::ExtractRightName ( strRightName, eRightType ); // Did we get a right name without the prefix? if ( strRightName ) { bool bHasPermission = m_pACLManager->CanObjectUseRight ( strObject, eObjectType, strRightName, eRightType, bDefault ); // Return whether we had access or not lua_pushboolean ( luaVM, bHasPermission ); return 1; } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); // Failed lua_pushnil ( luaVM ); return 1; }