Some fixes + lightuserdata & some more functions support
This commit is contained in:
parent
5c345fc275
commit
d6d016dac8
@ -27,6 +27,7 @@ namespace ui_scripting
|
|||||||
{
|
{
|
||||||
utils::hook::detour hksi_open_lib_hook;
|
utils::hook::detour hksi_open_lib_hook;
|
||||||
utils::hook::detour hksi_lual_error_hook;
|
utils::hook::detour hksi_lual_error_hook;
|
||||||
|
utils::hook::detour hksi_add_function_hook;
|
||||||
utils::hook::detour hks_start_hook;
|
utils::hook::detour hks_start_hook;
|
||||||
utils::hook::detour hks_shutdown_hook;
|
utils::hook::detour hks_shutdown_hook;
|
||||||
|
|
||||||
@ -83,6 +84,18 @@ namespace ui_scripting
|
|||||||
ui_scripting::lua::engine::stop();
|
ui_scripting::lua::engine::stop();
|
||||||
hks_shutdown_hook.invoke<void*>();
|
hks_shutdown_hook.invoke<void*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hksi_add_function_stub(game::hks::lua_State* s, game::hks::lua_function f, int a3, const char* name, int a5)
|
||||||
|
{
|
||||||
|
if (name != "( lua_CFunction )LUI_CoD_LuaCall_UIExpression"s)
|
||||||
|
{
|
||||||
|
std::string name_ = name;
|
||||||
|
const auto sub = name_.substr(13, name_.size() - 14);
|
||||||
|
libs["Global"][sub] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
hksi_add_function_hook.invoke<void>(s, f, a3, name, a5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_error_hook()
|
void enable_error_hook()
|
||||||
@ -158,6 +171,7 @@ namespace ui_scripting
|
|||||||
hks_shutdown_hook.create(game::base_address + 0x3203B0, hks_shutdown_stub);
|
hks_shutdown_hook.create(game::base_address + 0x3203B0, hks_shutdown_stub);
|
||||||
hksi_open_lib_hook.create(game::base_address + 0x2E4530, hksi_open_lib_stub);
|
hksi_open_lib_hook.create(game::base_address + 0x2E4530, hksi_open_lib_stub);
|
||||||
hksi_lual_error_hook.create(game::base_address + 0x2E3E40, hksi_lual_error_stub);
|
hksi_lual_error_hook.create(game::base_address + 0x2E3E40, hksi_lual_error_stub);
|
||||||
|
hksi_add_function_hook.create(game::base_address + 0x2DB570, hksi_add_function_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -917,6 +917,23 @@ namespace game
|
|||||||
|
|
||||||
namespace hks
|
namespace hks
|
||||||
{
|
{
|
||||||
|
struct GenericChunkHeader
|
||||||
|
{
|
||||||
|
unsigned __int64 m_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChunkHeader : GenericChunkHeader
|
||||||
|
{
|
||||||
|
ChunkHeader* m_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UserData : ChunkHeader
|
||||||
|
{
|
||||||
|
unsigned __int64 m_envAndSizeOffsetHighBits;
|
||||||
|
unsigned __int64 m_metaAndSizeOffsetLowBits;
|
||||||
|
char m_data[8];
|
||||||
|
};
|
||||||
|
|
||||||
struct InternString
|
struct InternString
|
||||||
{
|
{
|
||||||
unsigned __int64 m_flags;
|
unsigned __int64 m_flags;
|
||||||
@ -929,7 +946,7 @@ namespace game
|
|||||||
{
|
{
|
||||||
void* cClosure;
|
void* cClosure;
|
||||||
void* closure;
|
void* closure;
|
||||||
void* userData;
|
UserData* userData;
|
||||||
void* table;
|
void* table;
|
||||||
void* tstruct;
|
void* tstruct;
|
||||||
InternString* str;
|
InternString* str;
|
||||||
@ -940,25 +957,29 @@ namespace game
|
|||||||
bool boolean;
|
bool boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HksType
|
enum HksObjectType
|
||||||
{
|
{
|
||||||
HKS_LUA_TNONE = 0xFFFFFFFF,
|
TANY = 0xFFFFFFFE,
|
||||||
HKS_LUA_TNIL = 0x0,
|
TNONE = 0xFFFFFFFF,
|
||||||
HKS_LUA_TBOOLEAN = 0x1,
|
TNIL = 0x0,
|
||||||
HKS_LUA_TLIGHTUSERDATA = 0x2,
|
TBOOLEAN = 0x1,
|
||||||
HKS_LUA_TNUMBER = 0x3,
|
TLIGHTUSERDATA = 0x2,
|
||||||
HKS_LUA_TSTRING = 0x4,
|
TNUMBER = 0x3,
|
||||||
HKS_LUA_TTABLE = 0x5,
|
TSTRING = 0x4,
|
||||||
HKS_LUA_TFUNCTION = 0x6,
|
TTABLE = 0x5,
|
||||||
HKS_LUA_TUSERDATA = 0x7,
|
TFUNCTION = 0x6,
|
||||||
HKS_LUA_TTHREAD = 0x8,
|
TUSERDATA = 0x7,
|
||||||
HKS_LUA_TUI64 = 0xB,
|
TTHREAD = 0x8,
|
||||||
HKS_LUA_TSTRUCT = 0xC,
|
TIFUNCTION = 0x9,
|
||||||
|
TCFUNCTION = 0xA,
|
||||||
|
TUI64 = 0xB,
|
||||||
|
TSTRUCT = 0xC,
|
||||||
|
NUM_TYPE_OBJECTS = 0xE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HksObject
|
struct HksObject
|
||||||
{
|
{
|
||||||
HksType t;
|
HksObjectType t;
|
||||||
HksValue v;
|
HksValue v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace ui_scripting
|
|||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
const auto value = std::get<bool>(value_);
|
const auto value = std::get<bool>(value_);
|
||||||
state->top->t = game::hks::HksType::HKS_LUA_TBOOLEAN;
|
state->top->t = game::hks::HksObjectType::TBOOLEAN;
|
||||||
state->top->v.boolean = value;
|
state->top->v.boolean = value;
|
||||||
state->top++;
|
state->top++;
|
||||||
break;
|
break;
|
||||||
@ -37,7 +37,7 @@ namespace ui_scripting
|
|||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
const auto value = std::get<int>(value_);
|
const auto value = std::get<int>(value_);
|
||||||
state->top->t = game::hks::HksType::HKS_LUA_TNUMBER;
|
state->top->t = game::hks::HksObjectType::TNUMBER;
|
||||||
state->top->v.number = static_cast<float>(value);
|
state->top->v.number = static_cast<float>(value);
|
||||||
state->top++;
|
state->top++;
|
||||||
break;
|
break;
|
||||||
@ -45,7 +45,7 @@ namespace ui_scripting
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
const auto value = std::get<float>(value_);
|
const auto value = std::get<float>(value_);
|
||||||
state->top->t = game::hks::HksType::HKS_LUA_TNUMBER;
|
state->top->t = game::hks::HksObjectType::TNUMBER;
|
||||||
state->top->v.number = value;
|
state->top->v.number = value;
|
||||||
state->top++;
|
state->top++;
|
||||||
break;
|
break;
|
||||||
@ -56,6 +56,15 @@ namespace ui_scripting
|
|||||||
game::hks::hksi_lua_pushlstring(state, str.data(), (unsigned int)str.size());
|
game::hks::hksi_lua_pushlstring(state, str.data(), (unsigned int)str.size());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
const auto data = std::get<lightuserdata>(value_);
|
||||||
|
|
||||||
|
state->top->t = game::hks::HksObjectType::TLIGHTUSERDATA;
|
||||||
|
state->top->v.ptr = data.ptr;
|
||||||
|
state->top++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +74,7 @@ namespace ui_scripting
|
|||||||
return static_cast<int>(number) == number;
|
return static_cast<int>(number) == number;
|
||||||
}
|
}
|
||||||
|
|
||||||
value get_return_value()
|
value get_return_value(int offset)
|
||||||
{
|
{
|
||||||
if (!valid_state())
|
if (!valid_state())
|
||||||
{
|
{
|
||||||
@ -73,16 +82,15 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
const auto top = &state->top[-1];
|
const auto top = &state->top[-1 - offset];
|
||||||
|
|
||||||
switch (top->t)
|
switch (top->t)
|
||||||
{
|
{
|
||||||
case game::hks::HksType::HKS_LUA_TBOOLEAN:
|
case game::hks::HksObjectType::TBOOLEAN:
|
||||||
{
|
{
|
||||||
return {top->v.boolean};
|
return {top->v.boolean};
|
||||||
}
|
}
|
||||||
break;
|
case game::hks::HksObjectType::TNUMBER:
|
||||||
case game::hks::HksType::HKS_LUA_TNUMBER:
|
|
||||||
{
|
{
|
||||||
const auto number = top->v.number;
|
const auto number = top->v.number;
|
||||||
if (is_integer(number))
|
if (is_integer(number))
|
||||||
@ -94,13 +102,15 @@ namespace ui_scripting
|
|||||||
return {top->v.number};
|
return {top->v.number};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
case game::hks::HksObjectType::TSTRING:
|
||||||
case game::hks::HksType::HKS_LUA_TSTRING:
|
|
||||||
{
|
{
|
||||||
const auto value = top->v.str->m_data;
|
const auto value = top->v.str->m_data;
|
||||||
return {std::string(value)};
|
return {std::string(value)};
|
||||||
}
|
}
|
||||||
break;
|
case game::hks::HksObjectType::TLIGHTUSERDATA:
|
||||||
|
{
|
||||||
|
return lightuserdata{top->v.ptr};
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@ -108,13 +118,16 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value call(const std::string& name, const arguments& arguments)
|
std::vector<value> call(const std::string& name, const arguments& arguments)
|
||||||
{
|
{
|
||||||
if (!valid_state())
|
if (!valid_state())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid lua state");
|
throw std::runtime_error("Invalid lua state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto state = *game::hks::lua_state;
|
||||||
|
state->top = state->base;
|
||||||
|
|
||||||
const auto function = ui_scripting::find_function(name);
|
const auto function = ui_scripting::find_function(name);
|
||||||
if (!function)
|
if (!function)
|
||||||
{
|
{
|
||||||
@ -135,8 +148,15 @@ namespace ui_scripting
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
function(*game::hks::lua_state);
|
const auto count = function(*game::hks::lua_state);
|
||||||
return get_return_value();
|
std::vector<value> values;
|
||||||
|
|
||||||
|
for (auto i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
values.push_back(get_return_value(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
|
|
||||||
namespace ui_scripting
|
namespace ui_scripting
|
||||||
{
|
{
|
||||||
value call(const std::string& name, const arguments& arguments);
|
std::vector<value> call(const std::string& name, const arguments& arguments);
|
||||||
}
|
}
|
||||||
|
@ -986,15 +986,8 @@ namespace ui_scripting::lua
|
|||||||
arguments.push_back(arg);
|
arguments.push_back(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto value = call(name, arguments);
|
const auto values = call(name, arguments);
|
||||||
if (value.index() == 0)
|
return sol::as_returns(values);
|
||||||
{
|
|
||||||
return sol::lua_value{s, sol::lua_nil};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sol::lua_value{s, value};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1007,14 +1000,14 @@ namespace ui_scripting::lua
|
|||||||
arguments.push_back(arg);
|
arguments.push_back(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto value = call(name, arguments);
|
const auto values = call(name, arguments);
|
||||||
if (value.index() == 0)
|
if (values.size() == 0)
|
||||||
{
|
{
|
||||||
return sol::lua_value{s, sol::lua_nil};
|
return sol::lua_value{s, sol::lua_nil};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return sol::lua_value{s, value};
|
return sol::lua_value{s, sol::as_returns(values)};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
namespace ui_scripting
|
namespace ui_scripting
|
||||||
{
|
{
|
||||||
using value = std::variant<std::monostate, bool, int, float, std::string>;
|
struct lightuserdata
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
|
||||||
|
bool operator==(const lightuserdata other) const noexcept
|
||||||
|
{
|
||||||
|
return this->ptr == other.ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using value = std::variant<std::monostate, bool, int, float, std::string, lightuserdata>;
|
||||||
using arguments = std::vector<value>;
|
using arguments = std::vector<value>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user