mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 03:43:15 +08:00
feat(lua): lua sprint
This commit is contained in:
@@ -8,10 +8,6 @@ namespace YimMenu
|
||||
class LuaManager
|
||||
{
|
||||
public:
|
||||
enum class ScriptPermission
|
||||
{
|
||||
};
|
||||
|
||||
struct UnloadedScript
|
||||
{
|
||||
std::string m_Name;
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "lua.hpp"
|
||||
#undef GetObject // another dumb Windows.h definition
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
template<typename T>
|
||||
class Metatable
|
||||
{
|
||||
static int m_Index;
|
||||
|
||||
public:
|
||||
static inline void Register(lua_State* state)
|
||||
{
|
||||
m_Index = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
static inline int Get()
|
||||
{
|
||||
return m_Index;
|
||||
}
|
||||
};
|
||||
|
||||
// Tries to get the userdata or errors out
|
||||
template <typename T>
|
||||
inline T& GetObject(lua_State* state, int idx)
|
||||
{
|
||||
auto data = lua_touserdata(state, idx);
|
||||
if (!data)
|
||||
luaL_argerror(state, idx, "cannot get userdata at this index");
|
||||
|
||||
if (!lua_getmetatable(state, idx))
|
||||
luaL_argerror(state, idx, "cannot get metatable for the userdata at this index");
|
||||
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, Metatable<T>::Get());
|
||||
auto equals = lua_rawequal(state, -1, -2);
|
||||
lua_pop(state, 2);
|
||||
|
||||
if (!equals)
|
||||
luaL_argerror(state, idx, "the metatable for this userdata at this index is incorrect");
|
||||
|
||||
return *reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
inline void SetFunction(lua_State* state, lua_CFunction func, const char* name)
|
||||
{
|
||||
lua_pushcfunction(state, func);
|
||||
lua_setfield(state, -2, name);
|
||||
}
|
||||
|
||||
// This is a terrible hack
|
||||
template<lua_CFunction actual_func>
|
||||
inline int DropSelf(lua_State* state)
|
||||
{
|
||||
lua_remove(state, 1);
|
||||
return actual_func(state);
|
||||
}
|
||||
|
||||
// Requires your table to be at the top of stack
|
||||
// Creates a metatable for the table, which might not desirable
|
||||
template<lua_CFunction ctor>
|
||||
inline void SetConstructor(lua_State* state)
|
||||
{
|
||||
SetFunction(state, ctor, "new");
|
||||
|
||||
lua_newtable(state);
|
||||
SetFunction(state, DropSelf<ctor>, "__call");
|
||||
lua_setmetatable(state, -2);
|
||||
}
|
||||
|
||||
// Creates an object and pushes it on the stack
|
||||
template<typename T, class... Args>
|
||||
inline T* CreateObject(lua_State* state, Args&& ...args)
|
||||
{
|
||||
void* data = lua_newuserdata(state, sizeof(T));
|
||||
new (data) T(std::forward<Args>(args)...); // construct in-place
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, Metatable<T>::Get());
|
||||
lua_setmetatable(state, -2);
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
// Copies an existing object and pushes it on the stack
|
||||
// A copy ctor must be defined or something like that
|
||||
template<typename T, class... Args>
|
||||
inline T* CopyObject(lua_State* state, const T& existing)
|
||||
{
|
||||
void* data = lua_newuserdata(state, sizeof(T));
|
||||
*reinterpret_cast<T*>(data) = existing;
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, Metatable<T>::Get());
|
||||
lua_setmetatable(state, -2);
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
// Moves an existing object and pushes it on the stack
|
||||
// A move ctor must be defined or something like that
|
||||
template<typename T, class... Args>
|
||||
inline T* MoveObject(lua_State* state, T&& existing)
|
||||
{
|
||||
void* data = lua_newuserdata(state, sizeof(T));
|
||||
*reinterpret_cast<T*>(data) = std::move(existing);
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, Metatable<T>::Get());
|
||||
lua_setmetatable(state, -2);
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
@@ -47,22 +48,11 @@ namespace YimMenu::Lua
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
lua_newtable(state);
|
||||
|
||||
lua_pushcfunction(state, Verbose);
|
||||
lua_setfield(state, -2, "verbose");
|
||||
|
||||
lua_pushcfunction(state, Info);
|
||||
lua_setfield(state, -2, "info");
|
||||
|
||||
lua_pushcfunction(state, Warn);
|
||||
lua_setfield(state, -2, "warn");
|
||||
|
||||
lua_pushcfunction(state, Error);
|
||||
lua_setfield(state, -2, "error");
|
||||
|
||||
lua_pushcfunction(state, Trace);
|
||||
lua_setfield(state, -2, "trace");
|
||||
|
||||
SetFunction(state, Verbose, "verbose");
|
||||
SetFunction(state, Info, "info");
|
||||
SetFunction(state, Warn, "warn");
|
||||
SetFunction(state, Error, "error");
|
||||
SetFunction(state, Trace, "trace");
|
||||
lua_setglobal(state, "log");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
@@ -65,19 +66,10 @@ namespace YimMenu::Lua
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
lua_newtable(state);
|
||||
|
||||
lua_pushcfunction(state, RunInCallback);
|
||||
lua_setfield(state, -2, "run_in_callback");
|
||||
|
||||
lua_pushcfunction(state, Yield);
|
||||
lua_setfield(state, -2, "yield");
|
||||
|
||||
lua_pushcfunction(state, IsInsideCallback);
|
||||
lua_setfield(state, -2, "is_inside_callback");
|
||||
|
||||
lua_pushcfunction(state, RegisterEventHandler);
|
||||
lua_setfield(state, -2, "register_event_handler");
|
||||
|
||||
SetFunction(state, RunInCallback, "run_in_callback");
|
||||
SetFunction(state, Yield, "yield");
|
||||
SetFunction(state, IsInsideCallback, "is_inside_callback");
|
||||
SetFunction(state, RegisterEventHandler, "register_event_handler");
|
||||
lua_setglobal(state, "script");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
class Util : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int Joaat(lua_State* state)
|
||||
{
|
||||
const char* string = luaL_checkstring(state, 1);
|
||||
lua_pushinteger(state, (int)YimMenu::Joaat(string));
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
lua_newtable(state);
|
||||
SetFunction(state, Joaat, "joaat");
|
||||
lua_setglobal(state, "util");
|
||||
}
|
||||
};
|
||||
|
||||
Util _Util;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "types/rage/vector.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
class Vector3 : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int New(lua_State* state)
|
||||
{
|
||||
auto args = lua_gettop(state);
|
||||
if (args == 0)
|
||||
CreateObject<rage::fvector3>(state);
|
||||
else if (args == 3)
|
||||
CreateObject<rage::fvector3>(state, luaL_checknumber(state, 1), luaL_checknumber(state, 2), luaL_checknumber(state, 3));
|
||||
else
|
||||
luaL_error(state, "Invalid amount of arguments passed to Vector3::New");
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
luaL_newmetatable(state, "Vector3");
|
||||
{
|
||||
lua_newtable(state);
|
||||
{
|
||||
// TODO?
|
||||
}
|
||||
lua_setfield(state, -2, "__index"); // prototype
|
||||
}
|
||||
Metatable<rage::fvector3>::Register(state);
|
||||
|
||||
lua_newtable(state);
|
||||
SetConstructor<New>(state);
|
||||
lua_setglobal(state, "Vector3");
|
||||
}
|
||||
};
|
||||
|
||||
Vector3 _Vector3;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "game/gta/Entity.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
// TODO: we need to automate this
|
||||
class Entity : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int New(lua_State* state)
|
||||
{
|
||||
CreateObject<YimMenu::Entity>(state, luaL_checkinteger(state, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetHandle(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, GetObject<YimMenu::Entity>(state, 1).GetHandle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsValid(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsValid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsPed(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsPed());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsVehicle(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsVehicle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsObject(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsObject());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsPlayer(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsPlayer());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsMissionEntity(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsMissionEntity());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetModel(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, (int)GetObject<YimMenu::Entity>(state, 1).GetModel());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetPosition(lua_State* state)
|
||||
{
|
||||
CopyObject<rage::fvector3>(state, GetObject<YimMenu::Entity>(state, 1).GetPosition());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetRotation(lua_State* state)
|
||||
{
|
||||
CopyObject<rage::fvector3>(state, GetObject<YimMenu::Entity>(state, 1).GetRotation(lua_gettop(state) >= 2 ? luaL_checkinteger(state, 2) : 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetVelocity(lua_State* state)
|
||||
{
|
||||
CopyObject<rage::fvector3>(state, GetObject<YimMenu::Entity>(state, 1).GetVelocity());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetPosition(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetPosition(GetObject<rage::fvector3>(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetRotation(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetRotation(GetObject<rage::fvector3>(state, 2), lua_gettop(state) >= 3 ? luaL_checkinteger(state, 3) : 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetVelocity(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetVelocity(GetObject<rage::fvector3>(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
luaL_newmetatable(state, "Entity");
|
||||
{
|
||||
lua_newtable(state);
|
||||
{
|
||||
SetFunction(state, GetHandle, "get_handle");
|
||||
SetFunction(state, IsValid, "is_valid");
|
||||
SetFunction(state, IsPed, "is_ped");
|
||||
SetFunction(state, IsVehicle, "is_vehicle");
|
||||
SetFunction(state, IsObject, "is_object");
|
||||
SetFunction(state, IsPlayer, "is_player");
|
||||
SetFunction(state, IsMissionEntity, "is_mission_entity");
|
||||
SetFunction(state, GetModel, "get_model");
|
||||
SetFunction(state, GetPosition, "get_position");
|
||||
SetFunction(state, GetRotation, "get_rotation");
|
||||
SetFunction(state, GetVelocity, "get_velocity");
|
||||
SetFunction(state, SetPosition, "set_position");
|
||||
SetFunction(state, SetRotation, "set_rotation");
|
||||
SetFunction(state, SetVelocity, "set_velocity");
|
||||
}
|
||||
lua_setfield(state, -2, "__index"); // prototype
|
||||
}
|
||||
Metatable<YimMenu::Entity>::Register(state);
|
||||
|
||||
lua_newtable(state);
|
||||
SetConstructor<New>(state);
|
||||
lua_setglobal(state, "Entity");
|
||||
}
|
||||
};
|
||||
|
||||
Entity _Entity;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "game/gta/ScriptGlobal.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
// TODO: we need to automate this
|
||||
class ScriptGlobal : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int New(lua_State* state)
|
||||
{
|
||||
CreateObject<YimMenu::ScriptGlobal>(state, luaL_checkinteger(state, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int At(lua_State* state)
|
||||
{
|
||||
auto num_args = lua_gettop(state) - 1; // first argument is self
|
||||
auto& global = GetObject<YimMenu::ScriptGlobal>(state, 1);
|
||||
|
||||
auto size = num_args > 1 ? luaL_checkinteger(state, 3) : 0;
|
||||
if (size != 0)
|
||||
CopyObject<YimMenu::ScriptGlobal>(state, global.At(luaL_checkinteger(state, 2), size));
|
||||
else
|
||||
CopyObject<YimMenu::ScriptGlobal>(state, global.At(luaL_checkinteger(state, 2)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int CanAccess(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::ScriptGlobal>(state, 1).CanAccess());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetInt(lua_State* state)
|
||||
{
|
||||
auto& global = GetObject<YimMenu::ScriptGlobal>(state, 1);
|
||||
int value = 0;
|
||||
if (global.CanAccess())
|
||||
value = *global.As<int*>();
|
||||
lua_pushinteger(state, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetFloat(lua_State* state)
|
||||
{
|
||||
auto& global = GetObject<YimMenu::ScriptGlobal>(state, 1);
|
||||
float value = 0;
|
||||
if (global.CanAccess())
|
||||
value = *global.As<float*>();
|
||||
lua_pushnumber(state, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetInt(lua_State* state)
|
||||
{
|
||||
auto& global = GetObject<YimMenu::ScriptGlobal>(state, 1);
|
||||
if (global.CanAccess())
|
||||
*global.As<int*>() = luaL_checkinteger(state, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetFloat(lua_State* state)
|
||||
{
|
||||
auto& global = GetObject<YimMenu::ScriptGlobal>(state, 1);
|
||||
if (global.CanAccess())
|
||||
*global.As<float*>() = static_cast<float>(luaL_checknumber(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
luaL_newmetatable(state, "ScriptGlobal");
|
||||
{
|
||||
lua_newtable(state);
|
||||
{
|
||||
SetFunction(state, At, "at");
|
||||
SetFunction(state, CanAccess, "can_access");
|
||||
SetFunction(state, GetInt, "get_int");
|
||||
SetFunction(state, GetFloat, "get_float");
|
||||
SetFunction(state, SetInt, "set_int");
|
||||
SetFunction(state, SetFloat, "set_float");
|
||||
}
|
||||
lua_setfield(state, -2, "__index"); // prototype
|
||||
}
|
||||
Metatable<YimMenu::ScriptGlobal>::Register(state);
|
||||
|
||||
lua_newtable(state);
|
||||
SetConstructor<New>(state);
|
||||
lua_setglobal(state, "ScriptGlobal");
|
||||
}
|
||||
};
|
||||
|
||||
ScriptGlobal _ScriptGlobal;
|
||||
}
|
||||
Reference in New Issue
Block a user