Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Client/mods/deathmatch/StdInc.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
#include <luadefs/CLuaWaterDefs.h>
#include <luadefs/CLuaWeaponDefs.h>
#include <luadefs/CLuaWorldDefs.h>
#include <luadefs/CLuaThreadDefs.h>
#include <CRemoteCalls.h>

// Shared includes
Expand Down
62 changes: 62 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,68 @@ bool CLuaArguments::CallGlobal(CLuaMain* pLuaMain, const char* szFunction, CLuaA
return true;
}

bool CLuaArguments::CallGlobal(lua_State* luaVM, const char* szFunction, CLuaArguments* returnValues) const
{
assert(szFunction);
TIMEUS startTime = GetTimeUs();

// Add the function name to the stack and get the event from the table
assert(luaVM);
LUA_CHECKSTACK(luaVM, 1);
int luaStackPointer = lua_gettop(luaVM);
lua_pushstring(luaVM, szFunction);
lua_gettable(luaVM, LUA_GLOBALSINDEX);

// If that function doesn't exist, return false
if (lua_isnil(luaVM, -1))
{
// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);

return false;
}

// Push our arguments onto the stack
PushArguments(luaVM);

// Reset function call timer (checks long-running functions)
// pLuaMain->ResetInstructionCount();

// Call the function with our arguments
int iret = lua_pcall(luaVM, m_Arguments.size(), LUA_MULTRET, 0);
if (iret == LUA_ERRRUN || iret == LUA_ERRMEM)
{
std::string strRes = ConformResourcePath(lua_tostring(luaVM, -1));
g_pClientGame->GetScriptDebugging()->LogPCallError(luaVM, strRes);

// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);

return false; // the function call failed
}
else
{
int iReturns = lua_gettop(luaVM) - luaStackPointer;

if (returnValues != NULL)
{
for (int i = -iReturns; i <= -1; i++)
{
returnValues->ReadArgument(luaVM, i);
}
}

// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);
}

// CPerfStatLuaTiming::GetSingleton()->UpdateLuaTiming(pLuaMain, szFunction, GetTimeUs() - startTime);
return true;
}

CLuaArgument* CLuaArguments::PushNil()
{
CLuaArgument* pArgument = new CLuaArgument;
Expand Down
1 change: 1 addition & 0 deletions Client/mods/deathmatch/logic/lua/CLuaArguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class CLuaArguments
void PushArguments(const CLuaArguments& Arguments);
bool Call(class CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, CLuaArguments* returnValues = NULL) const;
bool CallGlobal(class CLuaMain* pLuaMain, const char* szFunction, CLuaArguments* returnValues = NULL) const;
bool CallGlobal(lua_State* luaVM, const char* szFunction, CLuaArguments* returnValues) const;

void ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
void PushAsTable(lua_State* luaVM, CFastHashMap<CLuaArguments*, int>* pKnownTables = nullptr) const;
Expand Down
26 changes: 26 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaCFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <StdInc.h>

static std::vector<CLuaCFunction*> m_sFunctions;
static std::vector<CLuaCFunction*> m_ThreadSafeFunctions;
static std::vector<CLuaCFunction*> m_ThreadFunctions;
static std::map<lua_CFunction, CLuaCFunction*> ms_Functions;
static void* ms_pFunctionPtrLow = (void*)0xffffffff;
static void* ms_pFunctionPtrHigh = 0;
Expand Down Expand Up @@ -133,6 +135,30 @@ void CLuaCFunctions::RegisterFunctionsWithVM(lua_State* luaVM)
}
}

void CLuaCFunctions::RegisterThreadSafeFunctionsWithVM(lua_State* luaVM)
{
// Register all our functions to a lua VM
std::vector<CLuaCFunction*>::const_iterator iter = m_ThreadSafeFunctions.begin();
for (; iter != m_ThreadSafeFunctions.end(); iter++)
{
lua_pushstring(luaVM, (*iter)->GetFunctionName());
lua_pushcclosure(luaVM, (*iter)->GetFunctionAddress(), 1);
lua_setglobal(luaVM, (*iter)->GetFunctionName());
}
}

void CLuaCFunctions::RegisterThreadFunctionsWithVM(lua_State* luaVM)
{
// Register all our functions to a lua VM
std::vector<CLuaCFunction*>::const_iterator iter = m_ThreadFunctions.begin();
for (; iter != m_ThreadFunctions.end(); iter++)
{
lua_pushstring(luaVM, (*iter)->GetFunctionName());
lua_pushcclosure(luaVM, (*iter)->GetFunctionAddress(), 1);
lua_setglobal(luaVM, (*iter)->GetFunctionName());
}
}

void CLuaCFunctions::RemoveAllFunctions()
{
for (CLuaCFunction* luaCFunction : m_sFunctions)
Expand Down
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaCFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class CLuaCFunctions
static bool IsRestricted(const char* szName);

static void RegisterFunctionsWithVM(lua_State* luaVM);
static void RegisterThreadSafeFunctionsWithVM(lua_State* luaVM);
static void RegisterThreadFunctionsWithVM(lua_State* luaVM);

static void RemoveAllFunctions();
};
4 changes: 4 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,10 @@ inline SString GetClassByTypeName(eClientModelType)
{
return "client-model-type";
}
inline SString GetClassTypeName(CLuaThread*)
{
return "lua-thread";
}

//
// CResource from userdata
Expand Down
24 changes: 14 additions & 10 deletions Client/mods/deathmatch/logic/lua/CLuaMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ CLuaMain::CLuaMain(CLuaManager* pLuaManager, CResource* pResourceOwner, bool bEn
m_luaVM = NULL;
m_bBeingDeleted = false;
m_pLuaTimerManager = new CLuaTimerManager;
m_pLuaThreadManager = new CLuaThreadManager;
m_FunctionEnterTimer.SetMaxIncrement(500);

m_pResource = pResourceOwner;
Expand All @@ -58,6 +59,9 @@ CLuaMain::~CLuaMain()
// Delete the timer manager
delete m_pLuaTimerManager;

// Delete the thread manager
delete m_pLuaThreadManager;

CClientPerfStatLuaMemory::GetSingleton()->OnLuaMainDestroy(this);
CClientPerfStatLuaTiming::GetSingleton()->OnLuaMainDestroy(this);
}
Expand All @@ -72,7 +76,7 @@ void CLuaMain::ResetInstructionCount()
m_FunctionEnterTimer.Reset();
}

void CLuaMain::InitSecurity()
void CLuaMain::InitSecurity(lua_State* luaVM)
{
// Disable dangerous Lua Os library functions
static const luaL_reg osfuncs[] =
Expand All @@ -86,14 +90,14 @@ void CLuaMain::InitSecurity()
{ "setlocale", CLuaUtilDefs::DisabledFunction },
{ NULL, NULL }
};
luaL_register(m_luaVM, "os", osfuncs);

lua_register(m_luaVM, "dofile", CLuaUtilDefs::DisabledFunction);
lua_register(m_luaVM, "loadfile", CLuaUtilDefs::DisabledFunction);
lua_register(m_luaVM, "require", CLuaUtilDefs::DisabledFunction);
lua_register(m_luaVM, "loadlib", CLuaUtilDefs::DisabledFunction);
lua_register(m_luaVM, "getfenv", CLuaUtilDefs::DisabledFunction);
lua_register(m_luaVM, "newproxy", CLuaUtilDefs::DisabledFunction);
luaL_register(luaVM, "os", osfuncs);

lua_register(luaVM, "dofile", CLuaUtilDefs::DisabledFunction);
lua_register(luaVM, "loadfile", CLuaUtilDefs::DisabledFunction);
lua_register(luaVM, "require", CLuaUtilDefs::DisabledFunction);
lua_register(luaVM, "loadlib", CLuaUtilDefs::DisabledFunction);
lua_register(luaVM, "getfenv", CLuaUtilDefs::DisabledFunction);
lua_register(luaVM, "newproxy", CLuaUtilDefs::DisabledFunction);
}

void CLuaMain::InitClasses(lua_State* luaVM)
Expand Down Expand Up @@ -159,7 +163,7 @@ void CLuaMain::InitVM()
luaopen_os(m_luaVM);

// Initialize security restrictions. Very important to prevent lua trojans and viruses!
InitSecurity();
InitSecurity(m_luaVM);

// Register module functions
CLuaCFunctions::RegisterFunctionsWithVM(m_luaVM);
Expand Down
15 changes: 10 additions & 5 deletions Client/mods/deathmatch/logic/lua/CLuaMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ class CLuaMain;
#pragma once

#include "CLuaTimerManager.h"
#include "./../Shared/mods/deathmatch/logic/lua/CLuaThreadManager.h"
#include "lua/CLuaVector2.h"
#include "lua/CLuaVector3.h"
#include "lua/CLuaVector4.h"
#include "lua/CLuaMatrix.h"
#include "lua/CLuaThread.h"

#include "CLuaFunctionDefs.h"

Expand All @@ -26,6 +28,7 @@ class CLuaMain;
#define MAX_SCRIPTNAME_LENGTH 64

#include <list>
CLuaThreadManager* a = new CLuaThreadManager();

struct CRefInfo
{
Expand All @@ -51,8 +54,9 @@ class CLuaMain //: public CClient
const char* GetScriptName() const { return m_strScriptName; }
void SetScriptName(const char* szName) { m_strScriptName.AssignLeft(szName, MAX_SCRIPTNAME_LENGTH); }

lua_State* GetVM() { return m_luaVM; };
CLuaTimerManager* GetTimerManager() const { return m_pLuaTimerManager; };
lua_State* GetVM() { return m_luaVM; };
CLuaTimerManager* GetTimerManager() const { return m_pLuaTimerManager; };
CLuaThreadManager* GetThreadManager() const { return m_pLuaThreadManager; };

bool BeingDeleted();
lua_State* GetVirtualMachine() const { return m_luaVM; };
Expand All @@ -79,15 +83,16 @@ class CLuaMain //: public CClient

bool IsOOPEnabled() { return m_bEnableOOP; }

static void InitSecurity(lua_State* luaVM);
private:
void InitSecurity();

static void InstructionCountHook(lua_State* luaVM, lua_Debug* pDebug);

SString m_strScriptName;

lua_State* m_luaVM;
CLuaTimerManager* m_pLuaTimerManager;
lua_State* m_luaVM;
CLuaTimerManager* m_pLuaTimerManager;
CLuaThreadManager* m_pLuaThreadManager;

bool m_bBeingDeleted; // prevent it being deleted twice

Expand Down
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/lua/LuaCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class CClientPointLights;
class CLuaTimer;
class CResource;
class CXMLNode;
class CLuaThread;

// Lua push/pop macros for our datatypes

Expand All @@ -62,6 +63,7 @@ void lua_pushvector(lua_State* luaVM, const CVector4D& vector);
void lua_pushvector(lua_State* luaVM, const CVector& vector);
void lua_pushvector(lua_State* luaVM, const CVector2D& vector);
void lua_pushmatrix(lua_State* luaVM, const CMatrix& matrix);
void lua_pushluathread(lua_State* luaVM, CLuaThread* pThread);

// Internal use
void lua_initclasses(lua_State* luaVM);
Expand Down
3 changes: 3 additions & 0 deletions Server/mods/deathmatch/StdInc.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ struct SAclRequest;
#include "luadefs/CLuaTeamDefs.h"
#include "luadefs/CLuaTextDefs.h"
#include "luadefs/CLuaTimerDefs.h"
#include "luadefs/CLuaThreadDefs.h"
#include "luadefs/CLuaVehicleDefs.h"
#include "luadefs/CLuaVoiceDefs.h"
#include "luadefs/CLuaWaterDefs.h"
Expand All @@ -157,6 +158,8 @@ struct SAclRequest;
#include "lua/CLuaManager.h"
#include "lua/CLuaTimerManager.h"
#include "lua/CLuaTimer.h"
#include "lua/CLuaThreadManager.h"
#include "lua/CLuaThread.h"
#include "lua/CLuaFunctionDefs.h"
#include "lua/CLuaModuleManager.h"
#include "lua/CLuaArgument.h"
Expand Down
70 changes: 70 additions & 0 deletions Server/mods/deathmatch/logic/lua/CLuaArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,68 @@ bool CLuaArguments::CallGlobal(CLuaMain* pLuaMain, const char* szFunction, CLuaA
return true;
}

bool CLuaArguments::CallGlobal(lua_State* luaVM, const char* szFunction, CLuaArguments* returnValues) const
{
assert(szFunction);
TIMEUS startTime = GetTimeUs();

// Add the function name to the stack and get the event from the table
assert(luaVM);
LUA_CHECKSTACK(luaVM, 1);
int luaStackPointer = lua_gettop(luaVM);
lua_pushstring(luaVM, szFunction);
lua_gettable(luaVM, LUA_GLOBALSINDEX);

// If that function doesn't exist, return false
if (lua_isnil(luaVM, -1))
{
// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);

return false;
}

// Push our arguments onto the stack
PushArguments(luaVM);

// Reset function call timer (checks long-running functions)
//pLuaMain->ResetInstructionCount();

// Call the function with our arguments
int iret = lua_pcall(luaVM, m_Arguments.size(), LUA_MULTRET, 0);
if (iret == LUA_ERRRUN || iret == LUA_ERRMEM)
{
std::string strRes = ConformResourcePath(lua_tostring(luaVM, -1));
g_pGame->GetScriptDebugging()->LogPCallError(luaVM, strRes);

// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);

return false; // the function call failed
}
else
{
int iReturns = lua_gettop(luaVM) - luaStackPointer;

if (returnValues != NULL)
{
for (int i = -iReturns; i <= -1; i++)
{
returnValues->ReadArgument(luaVM, i);
}
}

// cleanup the stack
while (lua_gettop(luaVM) - luaStackPointer > 0)
lua_pop(luaVM, 1);
}

//CPerfStatLuaTiming::GetSingleton()->UpdateLuaTiming(pLuaMain, szFunction, GetTimeUs() - startTime);
return true;
}

CLuaArgument* CLuaArguments::PushNil()
{
CLuaArgument* pArgument = new CLuaArgument;
Expand Down Expand Up @@ -428,6 +490,14 @@ CLuaArgument* CLuaArguments::PushTimer(CLuaTimer* pLuaTimer)
return pArgument;
}

CLuaArgument* CLuaArguments::PushThread(CLuaThread* pLuaThread)
{
CLuaArgument* pArgument = new CLuaArgument;
pArgument->ReadScriptID(pLuaThread->GetScriptID());
m_Arguments.push_back(pArgument);
return pArgument;
}

CLuaArgument* CLuaArguments::PushDbQuery(CDbJobData* pJobData)
{
CLuaArgument* pArgument = new CLuaArgument;
Expand Down
3 changes: 3 additions & 0 deletions Server/mods/deathmatch/logic/lua/CLuaArguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CAccount;
class CBan;
class CElement;
class CLuaTimer;
class CLuaThread;
class CResource;
class CTextDisplay;
class CTextItem;
Expand All @@ -60,6 +61,7 @@ class CLuaArguments
void PushArguments(const CLuaArguments& Arguments);
bool Call(class CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, CLuaArguments* returnValues = NULL) const;
bool CallGlobal(class CLuaMain* pLuaMain, const char* szFunction, CLuaArguments* returnValues = NULL) const;
bool CallGlobal(lua_State* luaVM, const char* szFunction, CLuaArguments* returnValues) const;

void ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
void PushAsTable(lua_State* luaVM, CFastHashMap<CLuaArguments*, int>* pKnownTables = nullptr) const;
Expand All @@ -77,6 +79,7 @@ class CLuaArguments
CLuaArgument* PushTextDisplay(CTextDisplay* pTextDisplay);
CLuaArgument* PushTextItem(CTextItem* pTextItem);
CLuaArgument* PushTimer(CLuaTimer* pLuaTimer);
CLuaArgument* PushThread(CLuaThread* pLuaThread);
CLuaArgument* PushDbQuery(CDbJobData* pJobData);

CLuaArgument* PushArgument(const CLuaArgument& argument);
Expand Down
Loading