Skip to content

Commit

Permalink
Added getUserdataType lua function to determine what particular MTA t…
Browse files Browse the repository at this point in the history
…ype userdata is.

Some possible return values:

resource-data
xml-node
lua-timer
account
db-query
acl
acl-group
weapon
ban
text-item
text-display
vector2
vector3
vector4
matrix

or 'userdata' if unknown.  False if non-userdata arg provided.
  • Loading branch information
darkdreamingdan committed Jul 28, 2016
1 parent 94a420b commit df8576f
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 49 deletions.
28 changes: 28 additions & 0 deletions MTA10/mods/shared_logic/lua/CLuaFunctionDefs.Util.cpp
Expand Up @@ -896,6 +896,34 @@ int CLuaFunctionDefs::IsOOPEnabled ( lua_State* luaVM )
return 1;
}

int CLuaFunctionDefs::GetUserdataType ( lua_State* luaVM )
{
CScriptArgReader argStream(luaVM);
int iArgument = lua_type(luaVM, 1);

if (argStream.NextIsUserData())
{
SString strType;
if (iArgument == LUA_TLIGHTUSERDATA)
strType = GetUserDataClassName(lua_touserdata(luaVM, 1), luaVM, false);
else if (iArgument == LUA_TUSERDATA)
strType = GetUserDataClassName(*((void**)lua_touserdata(luaVM, 1)), luaVM, false);

strType = strType.empty() ? "userdata" : strType;

lua_pushstring(luaVM,strType.c_str());
return 1;
}
else
{
argStream.SetCustomError(SString("Bad Argument: Expected userdata, got " + EnumToString((eLuaType)iArgument)));
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());
}

lua_pushboolean(luaVM, false);
return 1;
}


int CLuaFunctionDefs::GetVersion ( lua_State* luaVM )
{
Expand Down
1 change: 1 addition & 0 deletions MTA10/mods/shared_logic/lua/CLuaFunctionDefs.h
Expand Up @@ -477,6 +477,7 @@ class CLuaFunctionDefs
LUA_DECLARE ( AddDebugHook );
LUA_DECLARE ( RemoveDebugHook );
LUA_DECLARE ( IsOOPEnabled );
LUA_DECLARE ( GetUserdataType );

LUA_DECLARE ( GetVersion );

Expand Down
44 changes: 21 additions & 23 deletions MTA10/mods/shared_logic/lua/CLuaFunctionParseHelpers.cpp
Expand Up @@ -474,36 +474,34 @@ IMPLEMENT_ENUM_END ( "json-pretty-type" )
//
// Get best guess at name of userdata type
//
SString GetUserDataClassName ( void* ptr, lua_State* luaVM )
SString GetUserDataClassName ( void* ptr, lua_State* luaVM, bool bFindElementType )
{
// Try element
if ( CClientEntity* pClientElement = UserDataCast < CClientEntity > ( (CClientEntity*)NULL, ptr, NULL ) )
{
// Try gui element
if ( CClientGUIElement* pGuiElement = DynamicCast < CClientGUIElement > ( pClientElement ) )
{
return EnumToString ( pGuiElement->GetCGUIElement ()->GetType () );
}
return pClientElement->GetTypeName ();
}

// Try xml node
if ( CXMLNode* pXMLNode = UserDataCast < CXMLNode > ( (CXMLNode*)NULL, ptr, NULL ) )
{
return GetClassTypeName ( pXMLNode );
if (bFindElementType)
// Try gui element first
if ( CClientGUIElement* pGuiElement = DynamicCast < CClientGUIElement > ( pClientElement ) )
return EnumToString ( pGuiElement->GetCGUIElement ()->GetType () );
else
return pClientElement->GetTypeName ();
else
return GetClassTypeName(pClientElement);
}

// Try timer
if ( CLuaTimer* pLuaTimer = UserDataCast < CLuaTimer > ( (CLuaTimer*)NULL, ptr, luaVM ) )
{
return GetClassTypeName ( pLuaTimer );
}
if (auto* pVar = UserDataCast < CResource >((CResource*)NULL, ptr, luaVM)) // Try resource
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CXMLNode >((CXMLNode*)NULL, ptr, luaVM)) // Try xml node
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaTimer >((CLuaTimer*)NULL, ptr, luaVM)) // Try timer
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector2D >((CLuaVector2D*)NULL, ptr, luaVM)) // Try 2D Vector
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector3D >((CLuaVector3D*)NULL, ptr, luaVM)) // Try 3D Vector
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector4D >((CLuaVector4D*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);

// Try resource
if ( CResource* pResource = UserDataCast < CResource > ( (CResource*)NULL, ptr, NULL ) )
{
return GetClassTypeName ( pResource );
}

return "";
}
Expand Down
2 changes: 1 addition & 1 deletion MTA10/mods/shared_logic/lua/CLuaFunctionParseHelpers.h
Expand Up @@ -260,7 +260,7 @@ bool CheckWrappedUserDataType ( CClientGUIElement*& pGuiElement, SString& strErr
}


SString GetUserDataClassName ( void* ptr, lua_State* luaVM );
SString GetUserDataClassName ( void* ptr, lua_State* luaVM, bool bFindElementType = true );


//
Expand Down
1 change: 1 addition & 0 deletions MTA10/mods/shared_logic/lua/CLuaManager.cpp
Expand Up @@ -667,6 +667,7 @@ void CLuaManager::LoadCFunctions ( void )
CLuaCFunctions::AddFunction ( "addDebugHook", CLuaFunctionDefs::AddDebugHook );
CLuaCFunctions::AddFunction ( "removeDebugHook", CLuaFunctionDefs::RemoveDebugHook );
CLuaCFunctions::AddFunction ( "isOOPEnabled", CLuaFunctionDefs::IsOOPEnabled );
CLuaCFunctions::AddFunction ( "getUserdataType", CLuaFunctionDefs::GetUserdataType );

// Version functions
CLuaCFunctions::AddFunction ( "getVersion", CLuaFunctionDefs::GetVersion );
Expand Down
Expand Up @@ -439,3 +439,31 @@ int CLuaFunctionDefs::fromJSON ( lua_State* luaVM )
lua_pushnil ( luaVM );
return 1;
}

int CLuaFunctionDefs::GetUserdataType(lua_State* luaVM)
{
CScriptArgReader argStream(luaVM);
int iArgument = lua_type(luaVM, 1);

if (argStream.NextIsUserData())
{
SString strType;
if (iArgument == LUA_TLIGHTUSERDATA)
strType = GetUserDataClassName(lua_touserdata(luaVM, 1), luaVM, false);
else if (iArgument == LUA_TUSERDATA)
strType = GetUserDataClassName(*((void**)lua_touserdata(luaVM, 1)), luaVM, false);

strType = strType.empty() ? "userdata" : strType;

lua_pushstring(luaVM, strType.c_str());
return 1;
}
else
{
argStream.SetCustomError(SString("Bad Argument: Expected userdata, got " + EnumToString((eLuaType)iArgument)));
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());
}

lua_pushboolean(luaVM, false);
return 1;
}
1 change: 1 addition & 0 deletions MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionDefs.h
Expand Up @@ -198,6 +198,7 @@ class CLuaFunctionDefs
LUA_DECLARE ( GetModules );
LUA_DECLARE ( GetModuleInfo );
LUA_DECLARE ( IsOOPEnabled );
LUA_DECLARE ( GetUserdataType );

private:
// Static references to objects
Expand Down
57 changes: 33 additions & 24 deletions MTA10_Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp
Expand Up @@ -276,31 +276,40 @@ IMPLEMENT_ENUM_END ( "account-password-type" )
//
// Get best guess at name of userdata type
//
SString GetUserDataClassName ( void* ptr, lua_State* luaVM )
SString GetUserDataClassName ( void* ptr, lua_State* luaVM, bool bFindElementType )
{
// Try element
if ( CElement* pElement = UserDataCast < CElement > ( (CElement*)NULL, ptr, NULL ) )
{
return pElement->GetTypeName ();
}

// Try xml node
if ( CXMLNode* pXMLNode = UserDataCast < CXMLNode > ( (CXMLNode*)NULL, ptr, NULL ) )
{
return GetClassTypeName ( pXMLNode );
}

// Try timer
if ( CLuaTimer* pLuaTimer = UserDataCast < CLuaTimer > ( (CLuaTimer*)NULL, ptr, luaVM ) )
{
return GetClassTypeName ( pLuaTimer );
}

// Try resource
if ( CResource* pResource = UserDataCast < CResource > ( (CResource*)NULL, ptr, NULL ) )
{
return GetClassTypeName ( pResource );
}
if (CElement* pVar = UserDataCast < CElement >((CElement*)NULL, ptr, luaVM)) // Try element
return bFindElementType ? pVar->GetTypeName() : GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CResource >((CResource*)NULL, ptr, luaVM)) // Try resource
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CXMLNode >((CXMLNode*)NULL, ptr, luaVM)) // Try xml node
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaTimer >((CLuaTimer*)NULL, ptr, luaVM)) // Try timer
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CAccount >((CAccount*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CDbJobData >((CDbJobData*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CAccessControlList >((CAccessControlList*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CAccessControlListGroup >((CAccessControlListGroup*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CCustomWeapon >((CCustomWeapon*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CBan >((CBan*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CTextItem >((CTextItem*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CTextDisplay >((CTextDisplay*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector2D >((CLuaVector2D*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector3D >((CLuaVector3D*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaVector4D >((CLuaVector4D*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);
if (auto* pVar = UserDataCast < CLuaMatrix >((CLuaMatrix*)NULL, ptr, luaVM))
return GetClassTypeName(pVar);

return "";
}
Expand Down
Expand Up @@ -325,7 +325,7 @@ T* GetElementFromId( ElementID elementId )


class CScriptArgReader;
SString GetUserDataClassName ( void* ptr, lua_State* luaVM );
SString GetUserDataClassName ( void* ptr, lua_State* luaVM, bool bFindElementType = true );
void MixedReadResourceString ( CScriptArgReader& argStream, SString& strOutResourceName );
void MixedReadResourceString ( CScriptArgReader& argStream, CResource*& pOutResource );
bool StringToBool ( const SString& strText );
Expand Down
1 change: 1 addition & 0 deletions MTA10_Server/mods/deathmatch/logic/lua/CLuaManager.cpp
Expand Up @@ -367,6 +367,7 @@ void CLuaManager::LoadCFunctions ( void )
CLuaCFunctions::AddFunction ( "getLoadedModules", CLuaFunctionDefs::GetModules );
CLuaCFunctions::AddFunction ( "getModuleInfo", CLuaFunctionDefs::GetModuleInfo );
CLuaCFunctions::AddFunction ( "isOOPEnabled", CLuaFunctionDefs::IsOOPEnabled );
CLuaCFunctions::AddFunction ( "getUserdataType", CLuaFunctionDefs::GetUserdataType );

// Backward compat functions at the end, so the new function name is used in ACL

Expand Down

0 comments on commit df8576f

Please sign in to comment.