Jump to content

get() can't distinguish between false and not-set


Mdbelen

Recommended Posts

Hi, i recently got into trouble with the get() function.

I want to check if a setting (ghostmode) is set true or false or not at all in the meta.xml of a map. But get(..) returns false if it is set false and if it isn't set. Actually i wanted to set it true manually for all maps where it isn't set yet, but i can't distinguish the cases (so all maps-ghostmode would be set true^^).

(If the setting is set to "false" then it returns false as string i think, but you can set it "[false]", too, then get() will return false as boolean.)

So maybe it would be better to return nil if no setting is found and false only if the setting is rly set false.

Am I wrong or should I bug-report this behavior?

Link to comment
  • 2 weeks later...

eeh.. easyish? Well i don't have a big clue about C and i don't even know in which file i have to search.. but i found something in "svn/trunk/MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefinitions.cpp", Line 11580

int CLuaFunctionDefinitions::Get ( lua_State* luaVM ) 
{ 
    CResource* pResource = m_pResourceManager->GetResourceFromLuaState ( luaVM ); 
  
    if ( lua_type ( luaVM, 1 ) == LUA_TSTRING ) { 
        CLuaArguments Args; 
        CXMLAttributes *pAttributes; 
        unsigned int uiIndex = 0; 
        bool bDeleteNode; 
  
        // Extract attribute name if setting to be gotten has three parts i.e. resname.settingname.attributename 
        SString strSetting = lua_tostring ( luaVM, 1 ); 
        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 
                char *szDataValue = const_cast < char* > ( pAttribute->GetValue ().c_str () ); 
                if ( !Args.ReadFromJSONString ( szDataValue ) ) { 
                    // No valid JSON? Parse as plain text 
                    Args.PushString ( szDataValue ); 
                } 
                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 
                char *szDataValue; 
                while ( ( pSubNode = pNode->FindSubNode ( "setting", uiIndex++ ) ) ) { 
                    PUSH_SETTING ( pSubNode, szDataValue ); 
                } 
                // 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->LogBadType ( luaVM, "get" ); 
  
    lua_pushboolean ( luaVM, false ); 
    return 1; 
} 

I guess 11616 and 11654 (37 and 75 here) have to be changed to lua_pushnil( luaVM );

(Don't want to report this without confirmation, because i'm pretty unsure.)

Link to comment

Line 37 is where false is returned if get can't find the setting you specify, so you could use that as the basis for an 'isset' function (i.e. copy that function and rip out all the code that actually checks or returns a value).

Link to comment
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...