Skip to content

Commit

Permalink
Initial FIles
Browse files Browse the repository at this point in the history
  • Loading branch information
RaphaelIT7 committed Nov 17, 2023
1 parent 7ca4c4e commit 74d89b9
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Build Project

jobs:
build:
uses: RaphaelIT7/gmod-common-module-base/.github/workflows/compile.yml@workflow
with:
PROJECT_NAME: "lua_threaded"
BUILD_64x: "false"
LINUX_FILEEXTENTION: "dll"
BUILD_WINDOWS: "false"
ARTIFACT_EXPIRE: "1"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

development/
46 changes: 46 additions & 0 deletions premake5.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
-- Defines which version of the project generator to use, by default
-- (can be overriden by the environment variable PROJECT_GENERATOR_VERSION)
PROJECT_GENERATOR_VERSION = 3

newoption({
trigger = "gmcommon",
description = "Sets the path to the garrysmod_common (https://github.com/danielga/garrysmod_common) directory",
default = "garrysmod_common"
})

local gmcommon = assert(_OPTIONS.gmcommon or os.getenv("GARRYSMOD_COMMON"),
"you didn't provide a path to your garrysmod_common (https://github.com/danielga/garrysmod_common) directory")
include(gmcommon)

CreateWorkspace({name = "lua_threaded", abi_compatible = false})
-- Serverside module (gmsv prefix)
-- Can define "source_path", where the source files are located
-- Can define "manual_files", which allows you to manually add files to the project,
-- instead of automatically including them from the "source_path"
-- Can also define "abi_compatible", for project specific compatibility
CreateProject({serverside = true, manual_files = false})
kind "SharedLib"
symbols "On"
-- Remove some or all of these includes if they're not needed
--IncludeHelpersExtended()
IncludeLuaShared()
--IncludeSDKEngine()
IncludeSDKCommon()
--IncludeBootil()
IncludeSDKTier0()
IncludeSDKTier1()
--IncludeSDKTier2()
--IncludeSDKTier3()
--IncludeSDKMathlib()
--IncludeSDKRaytrace()
--IncludeSDKBitmap()
--IncludeSDKVTF()
--IncludeSteamAPI()
IncludeDetouring()
IncludeScanning()

filter("system:windows")
files({"source/win32/*.cpp", "source/win32/*.hpp"})

filter("system:linux or macosx")
files({"source/posix/*.cpp", "source/posix/*.hpp"})
26 changes: 26 additions & 0 deletions source/detours.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "detours.h"
#include <GarrysMod/ModuleLoader.hpp>
#include <scanning/symbolfinder.hpp>

CreateLuaInterface func_CreateLuaInterface;
CloseLuaInterface func_CloseLuaInterface;

template<class T>
void CheckFunction(T func, const char* name)
{
if (func == nullptr) {
//Msg("Could not locate %s symbol!", name);
}
}

void Symbols_Init()
{
SymbolFinder symfinder;
SourceSDK::ModuleLoader lua_shared_loader("lua_shared");

func_CreateLuaInterface = (CreateLuaInterface)symfinder.Resolve(lua_shared_loader.GetModule(), CreateLuaInterfaceSym.name.c_str(), CreateLuaInterfaceSym.length);
CheckFunction(func_CreateLuaInterface, "CreateLuaInterface");

func_CloseLuaInterface = (CloseLuaInterface)symfinder.Resolve(lua_shared_loader.GetModule(), CloseLuaInterfaceSym.name.c_str(), CloseLuaInterfaceSym.length);
CheckFunction(func_CloseLuaInterface, "CloseLuaInterface");
}
17 changes: 17 additions & 0 deletions source/detours.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <GarrysMod/Symbol.hpp>
#include <GarrysMod/Lua/LuaInterface.h>

using namespace GarrysMod::Lua;

/*
lua_shared Symbols
*/
typedef ILuaInterface* (*CreateLuaInterface)(bool);
const Symbol CreateLuaInterfaceSym = Symbol::FromName("_Z18CreateLuaInterfaceb");
extern CreateLuaInterface func_CreateLuaInterface;

typedef void (*CloseLuaInterface)(ILuaInterface*);
const Symbol CloseLuaInterfaceSym = Symbol::FromName("_Z17CloseLuaInterfaceP13ILuaInterface");
extern CloseLuaInterface func_CloseLuaInterface;

extern void Symbols_Init();
245 changes: 245 additions & 0 deletions source/lua_threaded.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
#include "detours.h"
#include <GarrysMod/Lua/Interface.h>
#include <GarrysMod/Lua/LuaInterface.h>
#include <GarrysMod/Lua/LuaObject.h>
#include <unordered_map>
#include <lua.h>

int interfaces_count = 0;
std::unordered_map<double, ILuaInterface*> interfaces;

static int32_t metatype = GarrysMod::Lua::Type::NONE;
static const char metaname[] = "ILuaInterface";
static const char invalid_error[] = "invalid ILuaInterface";
static const char table_name[] = "ILuaInterface_object";

struct LUA_ILuaInterface
{
ILuaInterface* IFace;
int ID;
};

inline void CheckType(GarrysMod::Lua::ILuaBase* LUA, int32_t index)
{
if(!LUA->IsType(index, metatype))
luaL_typerror(LUA->GetState(), index, metaname);
}

inline LUA_ILuaInterface *GetUserdata(GarrysMod::Lua::ILuaBase *LUA, int index)
{
return LUA->GetUserType<LUA_ILuaInterface>(index, metatype);
}

static ILuaInterface* Get(GarrysMod::Lua::ILuaBase* LUA, int32_t index)
{
CheckType(LUA, index);
LUA_ILuaInterface *udata = GetUserdata(LUA, index);
if(udata == nullptr)
LUA->ArgError(index, invalid_error);

return udata->IFace;
}

void Push(GarrysMod::Lua::ILuaBase* LUA, ILuaInterface* Interface, int ID)
{
if(Interface == nullptr)
{
LUA->PushNil();
return;
}

LUA->GetField(GarrysMod::Lua::INDEX_REGISTRY, table_name);
LUA->PushUserdata(Interface);
LUA->GetTable(-2);
if(LUA->IsType(-1, metatype))
{
LUA->Remove(-2);
return;
}

LUA->Pop(1);

LUA_ILuaInterface *udata = LUA->NewUserType<LUA_ILuaInterface>(metatype);
udata->IFace = Interface;
udata->ID = ID;

LUA->PushMetaTable(metatype);
LUA->SetMetaTable(-2);

LUA->CreateTable();
lua_setfenv(LUA->GetState(), -2);

LUA->PushUserdata(Interface);
LUA->Push(-2);
LUA->SetTable(-4);
LUA->Remove(-2);
}

static void Destroy(GarrysMod::Lua::ILuaBase *LUA, int32_t index)
{
LUA_ILuaInterface *udata = GetUserdata(LUA, index);
if (udata == nullptr)
return;

ILuaInterface* IFace = udata->IFace;

LUA->GetField(GarrysMod::Lua::INDEX_REGISTRY, table_name);
LUA->PushUserdata(IFace);
LUA->PushNil();
LUA->SetTable(-3);
LUA->Pop(1);

LUA->SetUserType(index, nullptr);
}

LUA_FUNCTION_STATIC(gc)
{
if (!LUA->IsType(1, metatype))
return 0;

Destroy(LUA, 1);
return 0;
}

LUA_FUNCTION_STATIC(tostring)
{
LUA->PushFormattedString("%s: %p", metaname, Get(LUA, 1));
return 1;
}

LUA_FUNCTION_STATIC(eq)
{
LUA->PushBool(Get(LUA, 1) == Get(LUA, 2));
return 1;
}

LUA_FUNCTION_STATIC(index)
{
LUA->GetMetaTable(1);
LUA->Push(2);
LUA->RawGet(-2);
if(!LUA->IsType(-1, GarrysMod::Lua::Type::NIL))
return 1;

lua_getfenv(LUA->GetState(), 1);
LUA->Push(2);
LUA->RawGet(-2);
return 1;
}

LUA_FUNCTION_STATIC(newindex)
{
lua_getfenv(LUA->GetState(), 1);
LUA->Push(2);
LUA->Push(3);
LUA->RawSet(-3);
return 0;
}

/*
ILuaInterface functions
*/
LUA_FUNCTION(ILuaInterface_RunString)
{
ILuaInterface* IFace = Get(LUA, 1);

IFace->RunString("RunString", "RunString", LUA->CheckString(2), true, true); // ToDo: Change this. The Interface will be on another Thread so fix this!

return 0;
}

/*
Module Table
*/
LUA_FUNCTION(LuaThread_GetInterface)
{


return 0;
}

LUA_FUNCTION(LuaThread_CreateInterface)
{
ILuaInterface* IFace = func_CreateLuaInterface(true);

interfaces_count += 1;
interfaces[interfaces_count] = IFace;

Push(LUA, IFace, interfaces_count);

if (IFace->GetState() == nullptr) {
Msg("ILuaInterface got no State!\n");
}

return 1;
}

LUA_FUNCTION(LuaThread_CloseInterface)
{
ILuaInterface* ILUA = (ILuaInterface*)LUA;
ILuaObject* obj = ILUA->GetObject(0);

double id = obj->GetMemberDouble("ID", -1);
if (id == -1)
{
LUA->ThrowError("Failed to get a Valid ID!");
}

ILuaInterface* IFace = interfaces[id];
func_CloseLuaInterface(IFace);

interfaces[id] = nullptr;

return 0;
}

void Add_Func(GarrysMod::Lua::ILuaBase* LUA, CFunc Func, const char* Name) {
LUA->PushCFunction(Func);
LUA->SetField(-2, Name);
}

GMOD_MODULE_OPEN()
{
Symbols_Init();

LUA->PushSpecial(SPECIAL_GLOB);
LUA->CreateTable();
Add_Func(LUA, LuaThread_GetInterface, "GetInterface");
Add_Func(LUA, LuaThread_CreateInterface, "Createinterface");
Add_Func(LUA, LuaThread_CloseInterface, "CloseInterface");

LUA->SetField(-2, "LuaThreaded");
LUA->Pop(2);

LUA->CreateTable();
LUA->SetField( GarrysMod::Lua::INDEX_REGISTRY, table_name );

metatype = LUA->CreateMetaTable(metaname);

LUA->PushCFunction(gc);
LUA->SetField(-2, "__gc");

LUA->PushCFunction(tostring);
LUA->SetField(-2, "__tostring");

LUA->PushCFunction(eq);
LUA->SetField(-2, "__eq");

LUA->PushCFunction(index);
LUA->SetField(-2, "__index");

LUA->PushCFunction(newindex);
LUA->SetField(-2, "__newindex");

LUA->Pop(1);

return 0;
}

GMOD_MODULE_CLOSE()
{
LUA->PushNil();
LUA->SetField(GarrysMod::Lua::INDEX_REGISTRY, metaname);

return 0;
}

0 comments on commit 74d89b9

Please sign in to comment.