mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 03:43:15 +08:00
feat(lua): sprint 2
This commit is contained in:
@@ -43,6 +43,7 @@ namespace YimMenu
|
||||
bool m_RunningScriptCallbacks = false;
|
||||
ScriptCallback* m_CurrentlyExecutingCallback = nullptr;
|
||||
std::unordered_map<std::uint32_t, std::vector<int>> m_EventHandlers;
|
||||
bool m_NativesLoaded = false; // TODO: move this to a LuaResource
|
||||
|
||||
// Calls the function at the top of stack. If this returns false the stack would have nothing on it
|
||||
bool CallFunction(int n_args, int n_results, lua_State* override_state = nullptr);
|
||||
@@ -133,5 +134,19 @@ namespace YimMenu
|
||||
|
||||
void AddEventHandler(std::uint32_t event, int handler);
|
||||
bool DispatchEvent(std::uint32_t event, const DispatchEventCallback& add_arguments_cb, bool handle_result = false);
|
||||
|
||||
// ------- TODO: move these into a resource
|
||||
|
||||
bool AreNativesLoaded() const
|
||||
{
|
||||
return m_NativesLoaded;
|
||||
}
|
||||
|
||||
void SetNativesLoaded()
|
||||
{
|
||||
m_NativesLoaded = true;
|
||||
}
|
||||
|
||||
// --------------
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "lua.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
#undef GetObject // another dumb Windows.h definition
|
||||
|
||||
namespace YimMenu::Lua
|
||||
@@ -6,7 +7,7 @@ namespace YimMenu::Lua
|
||||
template<typename T>
|
||||
class Metatable
|
||||
{
|
||||
static int m_Index;
|
||||
inline static int m_Index;
|
||||
|
||||
public:
|
||||
static inline void Register(lua_State* state)
|
||||
@@ -101,4 +102,26 @@ namespace YimMenu::Lua
|
||||
lua_setmetatable(state, -2);
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
inline std::uint32_t GetHashArgument(lua_State* state, int index)
|
||||
{
|
||||
if (lua_type(state, index) == LUA_TSTRING)
|
||||
return Joaat(lua_tostring(state, index));
|
||||
else
|
||||
return luaL_checkinteger(state, index);
|
||||
}
|
||||
|
||||
// luaL_checkstring automatically converts ints into strings, which we don't want
|
||||
inline const char* CheckStringSafe(lua_State* state, int index)
|
||||
{
|
||||
luaL_checktype(state, index, LUA_TSTRING);
|
||||
return lua_tostring(state, index);
|
||||
}
|
||||
|
||||
// lua doesn't even offer a check function for bools
|
||||
inline bool CheckBooleanSafe(lua_State* state, int index)
|
||||
{
|
||||
luaL_checktype(state, index, LUA_TBOOLEAN);
|
||||
return lua_toboolean(state, index);
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,12 @@ namespace YimMenu::Lua
|
||||
|
||||
static int RegisterEventHandler(lua_State* state)
|
||||
{
|
||||
auto event_name = luaL_checkstring(state, 1);
|
||||
auto event_name = GetHashArgument(state, 1);
|
||||
luaL_checktype(state, 2, LUA_TFUNCTION);
|
||||
lua_pushvalue(state, 2);
|
||||
int handler = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||
|
||||
LuaScript::GetScript(state).AddEventHandler(Joaat(event_name), handler);
|
||||
LuaScript::GetScript(state).AddEventHandler(event_name, handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace YimMenu::Lua
|
||||
|
||||
static int Joaat(lua_State* state)
|
||||
{
|
||||
const char* string = luaL_checkstring(state, 1);
|
||||
const char* string = CheckStringSafe(state, 1);
|
||||
lua_pushinteger(state, (int)YimMenu::Joaat(string));
|
||||
return 1;
|
||||
}
|
||||
|
||||
+12764
-12730
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -118,9 +118,106 @@ enum class NativeIndex
|
||||
{natives_buf}
|
||||
// clang-format on
|
||||
""")
|
||||
|
||||
|
||||
# make sure we block obvious footguns
|
||||
lua_blacklist = {
|
||||
"WAIT": "Use script.yield instead",
|
||||
"REGISTER_SCRIPT_VARIABLE": "Not allowed",
|
||||
"UNREGISTER_SCRIPT_VARIABLE": "Not allowed",
|
||||
"FORCE_CHECK_SCRIPT_VARIABLES": "Not allowed",
|
||||
"NETWORK_DELETE_CHARACTER": "Not allowed",
|
||||
"NETWORK_MANUAL_DELETE_CHARACTER": "Not allowed",
|
||||
"NET_GAMESERVER_DELETE_CHARACTER": "Not allowed",
|
||||
"NETWORK_REPORT_CODE_TAMPER": "Not allowed",
|
||||
"ADD_OWNED_EXPLOSION": "ADD_OWNED_EXPLOSION is no longer safe to use",
|
||||
# more telemetry
|
||||
"START_BEING_BOSS": "Not allowed",
|
||||
"START_BEING_GOON": "Not allowed",
|
||||
"END_BEING_BOSS": "Not allowed",
|
||||
"END_BEING_GOON": "Not allowed",
|
||||
"HIRED_LIMO": "Not allowed",
|
||||
"ORDER_BOSS_VEHICLE": "Not allowed",
|
||||
"CHANGE_UNIFORM": "Not allowed",
|
||||
"CHANGE_GOON_LOOKING_FOR_WORK": "Not allowed",
|
||||
"SEND_METRIC_GHOSTING_TO_PLAYER": "Not allowed",
|
||||
"SEND_METRIC_VIP_POACH": "Not allowed",
|
||||
"SEND_METRIC_PUNISH_BODYGUARD": "Not allowed",
|
||||
}
|
||||
|
||||
def get_blacklist_reason(native: str):
|
||||
if native in lua_blacklist:
|
||||
return lua_blacklist[native]
|
||||
if "PLAYSTATS" in native:
|
||||
return "Not allowed" # there's no good reason for scripts to call telemetry natives
|
||||
return None
|
||||
|
||||
def native_type_to_lua_type(type: str):
|
||||
if type == "void":
|
||||
return "n" # nothing
|
||||
elif type == "const char*" or type == "char*":
|
||||
return "s" # string
|
||||
elif type == "int" or type == "Any":
|
||||
return "i" # int
|
||||
elif type == "Hash":
|
||||
return "h" # hash
|
||||
elif type == "float":
|
||||
return "f" # float
|
||||
elif type == "BOOL":
|
||||
return "b" # boolean
|
||||
elif type == "Vector3" or type == "Vector3*":
|
||||
return "v" # vector
|
||||
elif "*" in type:
|
||||
return "p" # pointer
|
||||
else:
|
||||
return "i" # Ped, Entity, etc.
|
||||
|
||||
|
||||
def generate_lua_func_signature(native: NativeFunc):
|
||||
sig = ""
|
||||
n = 0
|
||||
for arg in native.args:
|
||||
sig += chr(97 + n) + ","
|
||||
n += 1
|
||||
if n >= 26:
|
||||
n = -32 # switch to uppercase letters (97 - 30 = A)
|
||||
sig = sig[:-1]
|
||||
return sig
|
||||
|
||||
def generate_lua_param_string(native: NativeFunc):
|
||||
string = ""
|
||||
for arg in native.args:
|
||||
string += native_type_to_lua_type(arg.type)
|
||||
string += "=" + native_type_to_lua_type(native.return_type)
|
||||
return string
|
||||
|
||||
def create_lua_func(native: NativeFunc):
|
||||
blacklist_reason = get_blacklist_reason(native.name)
|
||||
sign = generate_lua_func_signature(native)
|
||||
if sign != "":
|
||||
sign = ","+sign
|
||||
using_varargs = len(native.args) > 2
|
||||
if blacklist_reason:
|
||||
return f"{native.name}=function()error('{blacklist_reason}')end,"
|
||||
return f"{native.name}=function({"..." if using_varargs else generate_lua_func_signature(native)}){"" if native.return_type == "void" else "return "}_I({native.native_index},'{generate_lua_param_string(native)}'{",..." if using_varargs else sign})end,"
|
||||
|
||||
def create_lua_namespace(name: str, natives: list[NativeFunc]):
|
||||
string = f"\t\"{name}={{"
|
||||
for native in natives:
|
||||
string += create_lua_func(native)
|
||||
string = string[:-1] + "}\",\n"
|
||||
return string
|
||||
|
||||
def create_lua_defs():
|
||||
with open("../../scripting/libraries/NativeDefs.cpp", "w+") as file:
|
||||
string = "#pragma once\n#include \"NativeDefs.hpp\"\n\nconst char* g_LuaNativeDefs[] = \n{\n"
|
||||
for ns, natives_list in natives.items():
|
||||
string += create_lua_namespace(ns, natives_list)
|
||||
string += f"}};\n\nint g_NumLuaNativeDefs = {len(natives.items())};"
|
||||
file.write(string)
|
||||
|
||||
if __name__ == "__main__":
|
||||
load_natives_data()
|
||||
load_crossmap_data()
|
||||
write_crossmap_header()
|
||||
write_natives_header()
|
||||
write_natives_header()
|
||||
create_lua_defs()
|
||||
@@ -42,6 +42,13 @@ namespace YimMenu
|
||||
m_CallContext.FixVectors();
|
||||
}
|
||||
|
||||
constexpr void EndCall(int index, bool fix_vectors)
|
||||
{
|
||||
m_Handlers[index](&m_CallContext);
|
||||
if (fix_vectors)
|
||||
m_CallContext.FixVectors();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void PushArg(T&& value)
|
||||
{
|
||||
|
||||
@@ -3313,7 +3313,7 @@
|
||||
"0x3CDC1E622CCE0356": {
|
||||
"name": "OVERRIDE_VEH_HORN",
|
||||
"jhash": "0x2ACAB783",
|
||||
"comment": "Overrides the vehicle's horn hash.\nWhen changing this hash on a vehicle, it will not return the 'overwritten' hash. It will still always return the default horn hash (same as GET_VEHICLE_DEFAULT_HORN)\n\nvehicle - the vehicle whose horn should be overwritten\nmute - p1 seems to be an option for muting the horn\np2 - maybe a horn id, since the function AUDIO::GET_VEHICLE_DEFAULT_HORN(veh) exists?",
|
||||
"comment": "Overrides the vehicle's horn hash.\nWhen changing this hash on a vehicle, it will not return the 'overwritten' hash. It will still always return the default horn hash (same as GET_VEHICLE_DEFAULT_HORN)\n\nvehicle - the vehicle whose horn should be overwritten",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vehicle",
|
||||
@@ -3373,7 +3373,7 @@
|
||||
"0x58BB377BEC7CD5F4": {
|
||||
"name": "SET_VEHICLE_CONVERSATIONS_PERSIST",
|
||||
"jhash": "0x8CE63FA1",
|
||||
"comment": "SET_VEHICLE_CONVERSATIONS_PERSIST?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "BOOL",
|
||||
@@ -4193,7 +4193,7 @@
|
||||
"0xBAC7FC81A75EC1A1": {
|
||||
"name": "STOP_AUDIO_SCENES",
|
||||
"jhash": "0xF6C7342A",
|
||||
"comment": "??",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
@@ -4882,6 +4882,31 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0xC9D623C5A3D8FD5D": {
|
||||
"name": "SET_INDIVIDUAL_PORTAL_SETTINGS_OVERRIDE",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Hash",
|
||||
"name": "interiorNameHash"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "roomIndex"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "doorIndex"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "newPortalSettingsName"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0xB4BBFD9CD8B3922B": {
|
||||
"name": "REMOVE_PORTAL_SETTINGS_OVERRIDE",
|
||||
"jhash": "0xD24B4D0C",
|
||||
@@ -4895,10 +4920,31 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x8EF105736194F80C": {
|
||||
"name": "REMOVE_INDIVIDUAL_PORTAL_SETTINGS_OVERRIDE",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Hash",
|
||||
"name": "interiorNameHash"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "roomIndex"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "doorIndex"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0xE4E6DD5566D28C82": {
|
||||
"name": "STOP_SMOKE_GRENADE_EXPLOSION_SOUNDS",
|
||||
"jhash": "0x7262B5BA",
|
||||
"comment": "STOP_S[MOKE_GRENADE_EXPLOSION_SOUNDS]?",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
@@ -9821,6 +9867,23 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x1FA904B60E492336": {
|
||||
"name": "GET_CUT_FILE_OFFSET",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "cutsceneName"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "index"
|
||||
}
|
||||
],
|
||||
"return_type": "Vector3",
|
||||
"build": "889"
|
||||
},
|
||||
"0x0ABC54DE641DC0FC": {
|
||||
"name": "GET_CUT_FILE_CONCAT_COUNT",
|
||||
"jhash": "0xFD8B1AC2",
|
||||
@@ -10319,11 +10382,11 @@
|
||||
"0x2F137B508DE238F2": {
|
||||
"name": "NETWORK_SET_MOCAP_CUTSCENE_CAN_BE_SKIPPED",
|
||||
"jhash": "0x8338DA1D",
|
||||
"comment": "Stops current cutscene with a fade transition\np0: always true in R* Scripts\nYou will need to manually fade the screen back in\nSET_CUTSCENE_INPUTS_PARTIALLY_FADE?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "p0"
|
||||
"name": "toggle"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
@@ -13335,7 +13398,7 @@
|
||||
"0x1218E6886D3D8327": {
|
||||
"name": "IS_ENTITY_STATIC",
|
||||
"jhash": "0x928E12E9",
|
||||
"comment": "a static ped will not react to natives like \"APPLY_FORCE_TO_ENTITY\" or \"SET_ENTITY_VELOCITY\" and oftentimes will not react to task-natives like \"TASK::TASK_COMBAT_PED\". The only way I know of to make one of these peds react is to ragdoll them (or sometimes to use CLEAR_PED_TASKS_IMMEDIATELY(). Static peds include almost all far-away peds, beach-combers, peds in certain scenarios, peds crossing a crosswalk, peds walking to get back into their cars, and others. If anyone knows how to make a ped non-static without ragdolling them, please edit this with the solution.\n\nhow can I make an entity static???",
|
||||
"comment": "a static ped will not react to natives like \"APPLY_FORCE_TO_ENTITY\" or \"SET_ENTITY_VELOCITY\" and oftentimes will not react to task-natives like \"TASK::TASK_COMBAT_PED\". The only way I know of to make one of these peds react is to ragdoll them (or sometimes to use CLEAR_PED_TASKS_IMMEDIATELY(). Static peds include almost all far-away peds, beach-combers, peds in certain scenarios, peds crossing a crosswalk, peds walking to get back into their cars, and others. If anyone knows how to make a ped non-static without ragdolling them, please edit this with the solution.",
|
||||
"params": [
|
||||
{
|
||||
"type": "Entity",
|
||||
@@ -14243,7 +14306,7 @@
|
||||
"0x43D3807C077261E3": {
|
||||
"name": "STOP_SYNCHRONIZED_ENTITY_ANIM",
|
||||
"jhash": "0xE27D2FC1",
|
||||
"comment": "p1 sync task id?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Entity",
|
||||
@@ -17619,6 +17682,23 @@
|
||||
"_GET_PED_INSIDE_EXPLOSION_AREA",
|
||||
"_GET_ENTITY_INSIDE_EXPLOSION_AREA"
|
||||
]
|
||||
},
|
||||
"0x5241DB47A8B8AD54": {
|
||||
"name": "_NETWORK_EXPECT_EXPLOSION_EVENTS_FOR_PLAYER",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "expect"
|
||||
},
|
||||
{
|
||||
"type": "Player",
|
||||
"name": "player"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
}
|
||||
},
|
||||
"GRAPHICS": {
|
||||
@@ -20345,7 +20425,7 @@
|
||||
"0x845BAD77CC770633": {
|
||||
"name": "ATTACH_TV_AUDIO_TO_ENTITY",
|
||||
"jhash": "0x784944DB",
|
||||
"comment": "Might be more appropriate in AUDIO?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Entity",
|
||||
@@ -21040,7 +21120,7 @@
|
||||
"0x6D955F6A9E0295B1": {
|
||||
"name": "GRASSBATCH_ENABLE_FLATTENING_IN_SPHERE",
|
||||
"jhash": "",
|
||||
"comment": "Wraps 0xAAE9BE70EC7C69AB with FLT_MAX as p7, Jenkins: 0x73E96210?",
|
||||
"comment": "Wraps 0xAAE9BE70EC7C69AB with FLT_MAX as p7",
|
||||
"params": [
|
||||
{
|
||||
"type": "float",
|
||||
@@ -25578,7 +25658,7 @@
|
||||
"0xAE4E8157D9ECF087": {
|
||||
"name": "END_TEXT_COMMAND_UNPARSED_SCALEFORM_STRING",
|
||||
"jhash": "0x2E80DB52",
|
||||
"comment": "Same as END_TEXT_COMMAND_SCALEFORM_STRING but does not perform HTML conversion for text tokens.\n\nEND_TEXT_COMMAND_VIA_SPECIAL_MODIFIABLE_STRING?",
|
||||
"comment": "Same as END_TEXT_COMMAND_SCALEFORM_STRING but does not perform HTML conversion for text tokens.",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "811",
|
||||
@@ -31056,7 +31136,7 @@
|
||||
"0xA17784FCA9548D15": {
|
||||
"name": "SET_FAKE_GPS_PLAYER_POSITION_THIS_FRAME",
|
||||
"jhash": "",
|
||||
"comment": "p2 maybe z float?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "float",
|
||||
@@ -31067,8 +31147,8 @@
|
||||
"name": "y"
|
||||
},
|
||||
{
|
||||
"type": "Any",
|
||||
"name": "p2"
|
||||
"type": "float",
|
||||
"name": "z"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
@@ -39374,6 +39454,14 @@
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0xE2BCD0EFAE90D1F4": {
|
||||
"name": "_IS_XBOXPC_VERSION",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "BOOL",
|
||||
"build": "813"
|
||||
},
|
||||
"0x9F1935CA1F724008": {
|
||||
"name": "IS_AUSSIE_VERSION",
|
||||
"jhash": "0x944BA1DC",
|
||||
@@ -51020,6 +51108,19 @@
|
||||
"_NETWORK_SHOP_CHECKOUT_START"
|
||||
]
|
||||
},
|
||||
"0x4B64CD6D18474126": {
|
||||
"name": "NET_GAMESERVER_CHECKOUT_PENDING",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "transactionId"
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "889"
|
||||
},
|
||||
"0x3C5FD37B5499582E": {
|
||||
"name": "NET_GAMESERVER_BEGIN_SERVICE",
|
||||
"jhash": "",
|
||||
@@ -51360,6 +51461,14 @@
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0xA6BC0D9BCF9662FA": {
|
||||
"name": "_NETWORK_MULTIPLAYER_CROSSPLAY_NOT_ALLOWED",
|
||||
"jhash": "",
|
||||
"comment": "For the XboxPC version this returns true if XPRIVILEGE_MULTIPLAYER_SESSIONS is granted but XPRIVILEGE_CROSS_PLAY is NOT granted.\nFor more information, see https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/features/identity/privileges/concepts/live-user-privileges-client#privilege-ids-to-check\n\nAlways returns false for non-XboxPC versions.",
|
||||
"params": [],
|
||||
"return_type": "BOOL",
|
||||
"build": "889"
|
||||
},
|
||||
"0x1353F87E89946207": {
|
||||
"name": "NETWORK_HAS_AGE_RESTRICTIONS",
|
||||
"jhash": "",
|
||||
@@ -51737,6 +51846,40 @@
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0x6FA9825D0B5A721B": {
|
||||
"name": "NETWORK_CHECK_CAN_ACCESS_AND_ALERT",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "BOOL",
|
||||
"build": "889"
|
||||
},
|
||||
"0x967E6FB554E1B6DE": {
|
||||
"name": "_NETWORK_GET_ACCESS_CODE_LABEL_HEADING",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "accessCode"
|
||||
}
|
||||
],
|
||||
"return_type": "const char*",
|
||||
"build": "889"
|
||||
},
|
||||
"0x214CA1730793EBA8": {
|
||||
"name": "_NETWORK_GET_ACCESS_CODE_LABEL_BODY",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "accessCode"
|
||||
}
|
||||
],
|
||||
"return_type": "const char*",
|
||||
"build": "889"
|
||||
},
|
||||
"0x9747292807126EDA": {
|
||||
"name": "NETWORK_IS_MULTIPLAYER_DISABLED",
|
||||
"jhash": "0x05518C0F",
|
||||
@@ -51962,23 +52105,6 @@
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0xA02E59562D711006": {
|
||||
"name": "NETWORK_SESSION_END",
|
||||
"jhash": "0xBCACBEA2",
|
||||
"comment": "p0 is always false and p1 varies.\nNETWORK_SESSION_END(0, 1)\nNETWORK_SESSION_END(0, 0)\nResults in: \"Connection to session lost due to an unknown network error. Please return to Grand Theft Auto V and try again later.\"",
|
||||
"params": [
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "p0"
|
||||
},
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "p1"
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0xB9351A07A0D458B1": {
|
||||
"name": "NETWORK_SESSION_LEAVE",
|
||||
"jhash": "",
|
||||
@@ -56501,9 +56627,9 @@
|
||||
"build": "811"
|
||||
},
|
||||
"0xDBDF80673BBA3D65": {
|
||||
"name": "_NETWORK_DOES_COMMUNICATION_GROUP_EXIST",
|
||||
"name": "_NETWORK_DOES_COMMUNICATION_GROUP_HAVE_PERMISSION",
|
||||
"jhash": "",
|
||||
"comment": "communicationType: 0 = VOICE; 1 = TEXT_CHAT; 2 = TEXT_MESSAGE; 3 = EMAIL; 4 = USER_CONTENT; 5 = USER_TEXT",
|
||||
"comment": "communicationType: 0 = VOICE; 1 = TEXT_CHAT; 2 = TEXT_MESSAGE; 3 = EMAIL; 4 = USER_CONTENT; 5 = USER_TEXT",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
@@ -56511,7 +56637,23 @@
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
"build": "811",
|
||||
"old_names": [
|
||||
"_NETWORK_DOES_COMMUNICATION_GROUP_EXIST"
|
||||
]
|
||||
},
|
||||
"0x20C12650830A64EC": {
|
||||
"name": "_NETWORK_DOES_COMMUNICATION_GROUP_HAVE_SETTINGS_ENABLED",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "communicationType"
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "889"
|
||||
},
|
||||
"0x40DF02F371F40883": {
|
||||
"name": "_NETWORK_GET_COMMUNICATION_GROUP_FLAGS",
|
||||
@@ -56526,6 +56668,32 @@
|
||||
"return_type": "int",
|
||||
"build": "811"
|
||||
},
|
||||
"0x97F35B898D2D067F": {
|
||||
"name": "_NETWORK_GET_COMMUNICATION_GROUP_DEFAULT_FLAGS",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "communicationType"
|
||||
}
|
||||
],
|
||||
"return_type": "int",
|
||||
"build": "889"
|
||||
},
|
||||
"0xBF66ACD9AE81A99F": {
|
||||
"name": "_NETWORK_GET_COMMUNICATION_GROUP_VALUE",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "communicationType"
|
||||
}
|
||||
],
|
||||
"return_type": "int",
|
||||
"build": "889"
|
||||
},
|
||||
"0xE549F846DE7D32D5": {
|
||||
"name": "_NETWORK_SET_COMMUNICATION_GROUP_FLAGS",
|
||||
"jhash": "",
|
||||
@@ -58928,11 +59096,11 @@
|
||||
"0xC6FCEE21C6FCEE21": {
|
||||
"name": "NETWORK_SET_TASK_CUTSCENE_INSCOPE_MULTIPLER",
|
||||
"jhash": "",
|
||||
"comment": "A value between 1.0 and 5.0\n\n_NETWORK_SET_TASK_CUTSCENE_PROXIMITY_SCALE?",
|
||||
"comment": "A value between 1.0 and 5.0",
|
||||
"params": [
|
||||
{
|
||||
"type": "Any",
|
||||
"name": "p0"
|
||||
"type": "float",
|
||||
"name": "multiplier"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
@@ -60280,6 +60448,14 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0xCBD02360C5E16871": {
|
||||
"name": "NETWORK_SYNC_CLOCK_TIME_OVERRIDE",
|
||||
"jhash": "",
|
||||
"comment": "Does nothing in final builds.",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0xD7C95D322FF57522": {
|
||||
"name": "NETWORK_IS_CLOCK_TIME_OVERRIDDEN",
|
||||
"jhash": "0x2465296D",
|
||||
@@ -61195,27 +61371,6 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x1775961C2FBBCB5C": {
|
||||
"name": "NETWORK_SET_PROPERTY_ID",
|
||||
"jhash": "0x5A74E873",
|
||||
"comment": "value must be < 255",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0xC2B82527CA77053E": {
|
||||
"name": "NETWORK_CLEAR_PROPERTY_ID",
|
||||
"jhash": "0x38BC35C8",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x367EF5E2F439B4C6": {
|
||||
"name": "NETWORK_SET_PLAYER_MENTAL_STATE",
|
||||
"jhash": "0x53C9563C",
|
||||
@@ -67153,7 +67308,7 @@
|
||||
"0xADBE4809F19F927A": {
|
||||
"name": "ONLY_CLEAN_UP_OBJECT_WHEN_OUT_OF_RANGE",
|
||||
"jhash": "0x2048A7DD",
|
||||
"comment": "is this like setting is as no longer needed?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Object",
|
||||
@@ -78654,35 +78809,6 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x082D79E15302F0C2": {
|
||||
"name": "IS_PED_IN_SPHERE_AREA_OF_ANY_ENEMY_PEDS",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Ped",
|
||||
"name": "ped"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "x"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "y"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "z"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "range"
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "811"
|
||||
},
|
||||
"0xC158D28142A34608": {
|
||||
"name": "STOP_PED_WEAPON_FIRING_WHEN_DROPPED",
|
||||
"jhash": "0x4AC3421E",
|
||||
@@ -81975,7 +82101,7 @@
|
||||
"0x15F944730C832252": {
|
||||
"name": "SET_USE_KINEMATIC_PHYSICS",
|
||||
"jhash": "",
|
||||
"comment": "PED_RAGDOLL_BUMP Proof?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Entity",
|
||||
@@ -82867,7 +82993,7 @@
|
||||
"0x0032A6DBA562C518": {
|
||||
"name": "RESET_LAW_RESPONSE_DELAY_OVERRIDE",
|
||||
"jhash": "0x47CAB814",
|
||||
"comment": "2 matches in 1 script - am_hold_up\n\nUsed in multiplayer scripts?",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
@@ -83754,6 +83880,14 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x875BDD898B99C8CE": {
|
||||
"name": "GET_PLAYER_TARGETING_MODE",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [],
|
||||
"return_type": "int",
|
||||
"build": "889"
|
||||
},
|
||||
"0x5702B917B99DB1CD": {
|
||||
"name": "SET_PLAYER_TARGET_LEVEL",
|
||||
"jhash": "0x772DA539",
|
||||
@@ -85094,7 +85228,7 @@
|
||||
"0x11D5F725F0E780E0": {
|
||||
"name": "SET_PLAYER_PHONE_PALETTE_IDX",
|
||||
"jhash": "",
|
||||
"comment": "example:\n\nflags: 0-6\n\nPLAYER::SET_PLAYER_RESET_FLAG_PREFER_REAR_SEATS(PLAYER::PLAYER_ID(), 6);\n\nwouldnt the flag be the seatIndex?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Player",
|
||||
@@ -85102,7 +85236,7 @@
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "flags"
|
||||
"name": "idx"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
@@ -94179,6 +94313,39 @@
|
||||
"_PLAYSTATS_NJVS_VOTE"
|
||||
]
|
||||
},
|
||||
"0x01D8B04D02F1217F": {
|
||||
"name": "_PLAYSTATS_DEATH_INFO",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Ped",
|
||||
"name": "victimPed"
|
||||
},
|
||||
{
|
||||
"type": "Ped",
|
||||
"name": "killerPed"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "mentalState"
|
||||
},
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "revengeKill"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "victimKvK"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "killerKvK"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0x46A70777BE6CEAB9": {
|
||||
"name": "PLAYSTATS_FM_MISSION_END",
|
||||
"jhash": "",
|
||||
@@ -94918,6 +95085,19 @@
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x574A7808450E141C": {
|
||||
"name": "_PLAYSTATS_SCRIPT_EVENT_FPOM",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Any*",
|
||||
"name": "data"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
}
|
||||
},
|
||||
"STREAMING": {
|
||||
@@ -96795,10 +96975,6 @@
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "overrideEntryClipsetName"
|
||||
},
|
||||
{
|
||||
"type": "Any",
|
||||
"name": "p7"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
@@ -98734,6 +98910,19 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0xF5D1F489147CB683": {
|
||||
"name": "SET_SEQUENCE_PREVENT_MIGRATION",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "taskSequenceId"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0x00A9010CFE1E3533": {
|
||||
"name": "GET_SEQUENCE_PROGRESS",
|
||||
"jhash": "0xA3419909",
|
||||
@@ -103047,6 +103236,23 @@
|
||||
"return_type": "int",
|
||||
"build": "811"
|
||||
},
|
||||
"0x686ECCD99D4E61BB": {
|
||||
"name": "SET_PED_WAYPOINT_PROGRESS",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Ped",
|
||||
"name": "ped"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "progress"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0xE6A877C64CAF1BC5": {
|
||||
"name": "GET_PED_WAYPOINT_DISTANCE",
|
||||
"jhash": "0x084B35B0",
|
||||
@@ -103511,6 +103717,19 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0xE435D3539EFDCD1B": {
|
||||
"name": "VEHICLE_WAYPOINT_PLAYBACK_GET_IS_PAUSED",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vehicle",
|
||||
"name": "vehicle"
|
||||
}
|
||||
],
|
||||
"return_type": "BOOL",
|
||||
"build": "889"
|
||||
},
|
||||
"0xDC04FCAA7839D492": {
|
||||
"name": "VEHICLE_WAYPOINT_PLAYBACK_RESUME",
|
||||
"jhash": "0xBEB14C82",
|
||||
@@ -104073,6 +104292,23 @@
|
||||
"return_type": "void",
|
||||
"build": "811"
|
||||
},
|
||||
"0x0EFE4834A2F40563": {
|
||||
"name": "_SET_AMBIENT_PED_ENABLE_COLLISION_ON_NETWORK_CLONE_WHEN_FIXED",
|
||||
"jhash": "",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Ped",
|
||||
"name": "ped"
|
||||
},
|
||||
{
|
||||
"type": "BOOL",
|
||||
"name": "enable"
|
||||
}
|
||||
],
|
||||
"return_type": "void",
|
||||
"build": "889"
|
||||
},
|
||||
"0x349CE7B56DAFD95C": {
|
||||
"name": "IS_MOVE_BLEND_RATIO_STILL",
|
||||
"jhash": "0xE9DAF877",
|
||||
@@ -104180,7 +104416,7 @@
|
||||
"0xE45B7F222DE47E09": {
|
||||
"name": "IS_PED_STRAFING",
|
||||
"jhash": "0xEFEED13C",
|
||||
"comment": "What's strafing?",
|
||||
"comment": "",
|
||||
"params": [
|
||||
{
|
||||
"type": "Ped",
|
||||
@@ -108625,7 +108861,7 @@
|
||||
"0xA178472EBB8AE60D": {
|
||||
"name": "SET_HELI_BLADES_FULL_SPEED",
|
||||
"jhash": "0x033A9408",
|
||||
"comment": "Equivalent of SET_HELI_BLADES_SPEED(vehicleHandle, 1.0f);\n\nthis native works on planes to?",
|
||||
"comment": "Equivalent of SET_HELI_BLADES_SPEED(vehicleHandle, 1.0f);",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vehicle",
|
||||
@@ -108844,7 +109080,7 @@
|
||||
"0x2497C4717C8B881E": {
|
||||
"name": "SET_VEHICLE_ENGINE_ON",
|
||||
"jhash": "0x7FBC86F1",
|
||||
"comment": "Starts or stops the engine on the specified vehicle.\n\nvehicle: The vehicle to start or stop the engine on.\nvalue: true to turn the vehicle on; false to turn it off.\ninstantly: if true, the vehicle will be set to the state immediately; otherwise, the current driver will physically turn on or off the engine.\ndisableAutoStart: If true, the system will prevent the engine from starting when the player got into it.\n\nfrom what I've tested when I do this to a helicopter the propellers turn off after the engine has started. so is there any way to keep the heli propellers on?",
|
||||
"comment": "Starts or stops the engine on the specified vehicle.\n\nvehicle: The vehicle to start or stop the engine on.\nvalue: true to turn the vehicle on; false to turn it off.\ninstantly: if true, the vehicle will be set to the state immediately; otherwise, the current driver will physically turn on or off the engine.\ndisableAutoStart: If true, the system will prevent the engine from starting when the player got into it.",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vehicle",
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "core/scripting/LatentFunction.hpp"
|
||||
#include "game/gta/Entity.hpp"
|
||||
#include "Entity.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
// TODO: we need to automate this
|
||||
class Entity : LuaLibrary
|
||||
{
|
||||
public:
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int New(lua_State* state)
|
||||
@@ -100,26 +103,178 @@ namespace YimMenu::Lua
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetHeading(lua_State* state)
|
||||
{
|
||||
lua_pushnumber(state, GetObject<YimMenu::Entity>(state, 1).GetHeading());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetHeading(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetHeading(luaL_checknumber(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetSpeed(lua_State* state)
|
||||
{
|
||||
lua_pushnumber(state, GetObject<YimMenu::Entity>(state, 1).GetSpeed());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetCollision(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetCollision(lua_toboolean(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetFrozen(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetFrozen(lua_toboolean(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Delete(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).Delete();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DeleteNetwork
|
||||
|
||||
static int IsNetworked(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsNetworked());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsRemote(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsRemote());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int HasControl(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).HasControl());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GetNetworkObject
|
||||
// GetOwner
|
||||
|
||||
static int GetNetworkObjectId(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, GetObject<YimMenu::Entity>(state, 1).GetNetworkObjectId());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int PreventMigration(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).PreventMigration();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ForceControl(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).ForceControl();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int RequestControl(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).RequestControl(lua_gettop(state) >= 2 ? luaL_checkinteger(state, 2) : 100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ForceSync
|
||||
|
||||
static int IsInvincible(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsInvincible());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetInvincible(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetInvincible(lua_toboolean(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int IsDead(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsDead());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Kill(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).Kill();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetHealth(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, GetObject<YimMenu::Entity>(state, 1).GetHealth());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetHealth(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetHealth(luaL_checkinteger(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetMaxHealth(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, GetObject<YimMenu::Entity>(state, 1).GetMaxHealth());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int IsVisible(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).IsVisible());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetVisible(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetVisible(CheckBooleanSafe(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetAlpha(lua_State* state)
|
||||
{
|
||||
lua_pushinteger(state, GetObject<YimMenu::Entity>(state, 1).GetAlpha());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SetAlpha(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).SetAlpha(luaL_checkinteger(state, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ResetAlpha(lua_State* state)
|
||||
{
|
||||
GetObject<YimMenu::Entity>(state, 1).ResetAlpha();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HasInterior(lua_State* state)
|
||||
{
|
||||
lua_pushboolean(state, GetObject<YimMenu::Entity>(state, 1).HasInterior());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Explode
|
||||
|
||||
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");
|
||||
RegisterEntityMethods(state);
|
||||
}
|
||||
lua_setfield(state, -2, "__index"); // prototype
|
||||
}
|
||||
@@ -131,5 +286,49 @@ namespace YimMenu::Lua
|
||||
}
|
||||
};
|
||||
|
||||
void RegisterEntityMethods(lua_State* state)
|
||||
{
|
||||
SetFunction(state, Entity::GetHandle, "get_handle");
|
||||
SetFunction(state, Entity::IsValid, "is_valid");
|
||||
SetFunction(state, Entity::IsPed, "is_ped");
|
||||
SetFunction(state, Entity::IsVehicle, "is_vehicle");
|
||||
SetFunction(state, Entity::IsObject, "is_object");
|
||||
SetFunction(state, Entity::IsPlayer, "is_player");
|
||||
SetFunction(state, Entity::IsMissionEntity, "is_mission_entity");
|
||||
SetFunction(state, Entity::GetModel, "get_model");
|
||||
SetFunction(state, Entity::GetPosition, "get_position");
|
||||
SetFunction(state, Entity::GetRotation, "get_rotation");
|
||||
SetFunction(state, Entity::GetVelocity, "get_velocity");
|
||||
SetFunction(state, Entity::SetPosition, "set_position");
|
||||
SetFunction(state, Entity::SetRotation, "set_rotation");
|
||||
SetFunction(state, Entity::SetVelocity, "set_velocity");
|
||||
SetFunction(state, Entity::GetHeading, "get_heading");
|
||||
SetFunction(state, Entity::SetHeading, "set_heading");
|
||||
SetFunction(state, Entity::GetSpeed, "get_speed");
|
||||
SetFunction(state, Entity::SetCollision, "set_collision");
|
||||
SetFunction(state, Entity::SetFrozen, "set_frozen");
|
||||
SetFunction(state, Entity::Delete, "delete");
|
||||
SetFunction(state, Entity::IsNetworked, "is_networked");
|
||||
SetFunction(state, Entity::IsRemote, "is_remote");
|
||||
SetFunction(state, Entity::HasControl, "has_control");
|
||||
SetFunction(state, Entity::GetNetworkObjectId, "get_network_object_id");
|
||||
SetFunction(state, Entity::PreventMigration, "prevent_migration");
|
||||
SetFunction(state, Entity::ForceControl, "force_control");
|
||||
SetFunction(state, LatentFunction<Entity::RequestControl>, "request_control");
|
||||
SetFunction(state, Entity::IsInvincible, "is_invincible");
|
||||
SetFunction(state, Entity::SetInvincible, "set_invincible");
|
||||
SetFunction(state, Entity::IsDead, "is_dead");
|
||||
SetFunction(state, Entity::Kill, "kill");
|
||||
SetFunction(state, Entity::GetHealth, "get_health");
|
||||
SetFunction(state, Entity::SetHealth, "set_health");
|
||||
SetFunction(state, Entity::GetMaxHealth, "get_max_health");
|
||||
SetFunction(state, Entity::IsVisible, "is_visible");
|
||||
SetFunction(state, Entity::SetVisible, "set_visible");
|
||||
SetFunction(state, Entity::GetAlpha, "get_alpha");
|
||||
SetFunction(state, Entity::SetAlpha, "set_alpha");
|
||||
SetFunction(state, Entity::ResetAlpha, "reset_alpha");
|
||||
SetFunction(state, Entity::HasInterior, "has_interior");
|
||||
}
|
||||
|
||||
Entity _Entity;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "lua.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
void RegisterEntityMethods(lua_State* state);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "game/gta/invoker/Invoker.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
class Invoker : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int GetInteger(lua_State* state, int idx)
|
||||
{
|
||||
if (lua_type(state, idx) == LUA_TBOOLEAN)
|
||||
return static_cast<int>(lua_toboolean(state, idx)); // stand only coerces bools when an option is enabled, but I feel we should do it regardless
|
||||
else
|
||||
return luaL_checkinteger(state, idx);
|
||||
}
|
||||
|
||||
static BOOL GetBoolean(lua_State* state, int idx)
|
||||
{
|
||||
if (lua_type(state, idx) == LUA_TNUMBER)
|
||||
return static_cast<BOOL>(lua_tointeger(state, idx)); // coerce ints
|
||||
else if (lua_type(state, idx) == LUA_TBOOLEAN)
|
||||
return static_cast<BOOL>(lua_toboolean(state, idx));
|
||||
else
|
||||
return luaL_argerror(state, idx, "Expected boolean, got something else"); // lua can technically convert anything into a boolean, but it's a good idea to not do that
|
||||
}
|
||||
|
||||
static const char* GetString(lua_State* state, int idx)
|
||||
{
|
||||
if (lua_type(state, idx) == LUA_TNIL || lua_type(state, idx) == LUA_TNONE)
|
||||
return nullptr;
|
||||
else
|
||||
return CheckStringSafe(state, idx);
|
||||
}
|
||||
|
||||
// thanks to Stand for the parameter string idea
|
||||
// we're assuming that only trusted functions can call this directly (this assumption is incorrect, but would do for now)
|
||||
static int InvokeNative(lua_State* state)
|
||||
{
|
||||
size_t params_len;
|
||||
auto index = lua_tointeger(state, 1);
|
||||
const char* parameters = lua_tolstring(state, 2, ¶ms_len);
|
||||
bool fix_vectors = false;
|
||||
NativeInvoker invoker;
|
||||
int vector_params = 0;
|
||||
rage::fvector3* vectors_to_fix[4];
|
||||
char return_type;
|
||||
|
||||
invoker.BeginCall();
|
||||
|
||||
for (int i = 0; i < params_len; i++)
|
||||
{
|
||||
auto type = parameters[i];
|
||||
switch (type)
|
||||
{
|
||||
case 'i': // integer
|
||||
invoker.PushArg<int>(GetInteger(state, 3 + i));
|
||||
break;
|
||||
case 'f': // float
|
||||
invoker.PushArg<float>(luaL_checknumber(state, 3 + i));
|
||||
break;
|
||||
case 'h': // hash
|
||||
invoker.PushArg<std::uint32_t>(GetHashArgument(state, 3 + i));
|
||||
break;
|
||||
case 'b': // boolean
|
||||
invoker.PushArg<std::uint32_t>(GetBoolean(state, 3 + i));
|
||||
break;
|
||||
case 's': // string
|
||||
invoker.PushArg<const char*>(GetString(state, 3 + i));
|
||||
break;
|
||||
case 'v': // Vector3* (not Vector3)
|
||||
{
|
||||
fix_vectors = true;
|
||||
auto& vec = GetObject<rage::fvector3>(state, 3 + i);
|
||||
auto script_vec = rage::scrVector(vec);
|
||||
invoker.PushArg<void*>(&script_vec);
|
||||
vectors_to_fix[vector_params++] = &vec;
|
||||
break;
|
||||
}
|
||||
case 'p': // Any*
|
||||
{
|
||||
// idk what to do with this
|
||||
luaL_argerror(state, 3 + i, "Pointers are not supported yet");
|
||||
break;
|
||||
}
|
||||
case '=': // done + return
|
||||
{
|
||||
return_type = parameters[i + 1];
|
||||
goto done; // can't break; out of the loop from here
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
invoker.EndCall(index, false);
|
||||
|
||||
if (fix_vectors)
|
||||
{
|
||||
for (int i = 0; i < vector_params; i++)
|
||||
{
|
||||
*vectors_to_fix[i] = invoker.m_CallContext.GetSourceVector(i);
|
||||
}
|
||||
}
|
||||
|
||||
switch (return_type)
|
||||
{
|
||||
case 'n': // nothing ([v]oid is taken)
|
||||
return 0;
|
||||
case 'i': // integer
|
||||
case 'h': // hash
|
||||
lua_pushinteger(state, invoker.GetReturnValue<int>());
|
||||
return 1;
|
||||
case 'f': // float
|
||||
lua_pushnumber(state, invoker.GetReturnValue<float>());
|
||||
return 1;
|
||||
case 'b': // boolean
|
||||
lua_pushboolean(state, invoker.GetReturnValue<bool>());
|
||||
return 1;
|
||||
case 's': // string
|
||||
lua_pushstring(state, invoker.GetReturnValue<const char*>());
|
||||
return 1;
|
||||
case 'v': // Vector3 (not Vector3*)
|
||||
CreateObject<rage::fvector3>(state, invoker.GetReturnValue<rage::scrVector>());
|
||||
return 1;
|
||||
case 'p': // pointer
|
||||
luaL_error(state, "Pointer returns are not supported"); // and probably never will be
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
lua_pushcfunction(state, InvokeNative);
|
||||
lua_setglobal(state, "_I"); // we're trying to keep the invoker code as short as possible
|
||||
}
|
||||
};
|
||||
|
||||
Invoker _Invoker;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
extern const char* g_LuaNativeDefs[];
|
||||
extern int g_NumLuaNativeDefs;
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "core/scripting/LuaLibrary.hpp"
|
||||
#include "core/scripting/LuaScript.hpp"
|
||||
#include "core/scripting/LuaUtils.hpp"
|
||||
#include "NativeDefs.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
|
||||
namespace YimMenu::Lua
|
||||
{
|
||||
class Natives : LuaLibrary
|
||||
{
|
||||
using LuaLibrary::LuaLibrary;
|
||||
|
||||
static int LoadNatives(lua_State* state)
|
||||
{
|
||||
auto& script = LuaScript::GetScript(state);
|
||||
|
||||
if (script.AreNativesLoaded())
|
||||
luaL_error(state, "Natives have already been loaded");
|
||||
|
||||
for (int i = 0; i < g_NumLuaNativeDefs; i++)
|
||||
{
|
||||
auto chunk = g_LuaNativeDefs[i];
|
||||
if (luaL_dostring(state, chunk) != LUA_OK)
|
||||
{
|
||||
std::string err_copy = lua_tostring(state, -1);
|
||||
lua_pop(state, 1);
|
||||
luaL_error(state, "%s", err_copy.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
script.SetNativesLoaded();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AreNativesLoaded(lua_State* state)
|
||||
{
|
||||
auto& script = LuaScript::GetScript(state);
|
||||
lua_pushboolean(state, script.AreNativesLoaded());
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void Register(lua_State* state) override
|
||||
{
|
||||
lua_newtable(state);
|
||||
SetFunction(state, LoadNatives, "load_natives");
|
||||
SetFunction(state, AreNativesLoaded, "are_natives_loaded");
|
||||
lua_setglobal(state, "natives");
|
||||
}
|
||||
};
|
||||
|
||||
Natives _Natives;
|
||||
}
|
||||
@@ -57,6 +57,11 @@ namespace rage
|
||||
m_NumVectorRefs = 0;
|
||||
}
|
||||
|
||||
rage::fvector3& GetSourceVector(int index)
|
||||
{
|
||||
return m_VectorRefSources[index];
|
||||
}
|
||||
|
||||
protected:
|
||||
void* m_ReturnValue; // 0x00
|
||||
std::uint32_t m_ArgCount; // 0x08
|
||||
|
||||
Reference in New Issue
Block a user