Safely call script functions
This commit is contained in:
parent
fcc8971d43
commit
e51f7afa3d
@ -36,6 +36,9 @@ namespace game
|
|||||||
|
|
||||||
unsigned int* levelEntityId;
|
unsigned int* levelEntityId;
|
||||||
|
|
||||||
|
int* g_script_error_level;
|
||||||
|
jmp_buf* g_script_error;
|
||||||
|
|
||||||
void AddRefToValue(VariableValue* value)
|
void AddRefToValue(VariableValue* value)
|
||||||
{
|
{
|
||||||
if (value->type == SCRIPT_OBJECT)
|
if (value->type == SCRIPT_OBJECT)
|
||||||
@ -153,6 +156,9 @@ namespace game
|
|||||||
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x184CDB0, 0x1D4F258, 0x1BF59C8));
|
native::scr_instanceFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x184CDB0, 0x1D4F258, 0x1BF59C8));
|
||||||
native::scr_globalFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x186C68C, 0x1D6EB34, 0x1C152A4));
|
native::scr_globalFunctions = reinterpret_cast<native::scr_call_t*>(SELECT_VALUE(0x186C68C, 0x1D6EB34, 0x1C152A4));
|
||||||
|
|
||||||
|
native::g_script_error_level = reinterpret_cast<int*>(SELECT_VALUE(0x1BEFCFC, 0x20B21FC, 0x1F5B058));
|
||||||
|
native::g_script_error = reinterpret_cast<jmp_buf*>(SELECT_VALUE(0x1BF1D18, 0x20B4218, 0x1F5A818));
|
||||||
|
|
||||||
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
native::levelEntityId = reinterpret_cast<unsigned int*>(SELECT_VALUE(0x1BCBCA4, 0x208E1A4, 0x1CD873C));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,9 @@ namespace game
|
|||||||
|
|
||||||
extern unsigned int* levelEntityId;
|
extern unsigned int* levelEntityId;
|
||||||
|
|
||||||
|
extern int* g_script_error_level;
|
||||||
|
extern jmp_buf* g_script_error;
|
||||||
|
|
||||||
void AddRefToValue(VariableValue* value);
|
void AddRefToValue(VariableValue* value);
|
||||||
|
|
||||||
void Scr_ClearOutParams();
|
void Scr_ClearOutParams();
|
||||||
|
@ -77,7 +77,7 @@ void notification::vm_notify_stub(const unsigned int notify_id, const unsigned s
|
|||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
scripting::propagate_scripting_error(e);
|
scripting::propagate_error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ void scripting::post_start()
|
|||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
propagate_scripting_error(e);
|
propagate_error(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
on_stop([this]()
|
on_stop([this]()
|
||||||
@ -225,7 +225,7 @@ void scripting::on_stop(const std::function<void()>& callback)
|
|||||||
stop_callbacks_.push_back(callback);
|
stop_callbacks_.push_back(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::propagate_scripting_error(const std::exception& e)
|
void scripting::propagate_error(const std::exception& e)
|
||||||
{
|
{
|
||||||
printf("\n******* Script execution error *******\n");
|
printf("\n******* Script execution error *******\n");
|
||||||
printf("%s\n", e.what());
|
printf("%s\n", e.what());
|
||||||
@ -269,7 +269,7 @@ void scripting::call(const std::string& function, const unsigned int entity_id,
|
|||||||
const int function_index = find_function_index(function);
|
const int function_index = find_function_index(function);
|
||||||
if (function_index < 0)
|
if (function_index < 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("No function found for name " + function);
|
throw std::runtime_error("No function found for name '" + function + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
const game::native::scr_entref_t entity = function_index > 0x1C7
|
const game::native::scr_entref_t entity = function_index > 0x1C7
|
||||||
@ -278,20 +278,32 @@ void scripting::call(const std::string& function, const unsigned int entity_id,
|
|||||||
|
|
||||||
const auto function_ptr = game::native::Scr_GetFunc(function_index);
|
const auto function_ptr = game::native::Scr_GetFunc(function_index);
|
||||||
|
|
||||||
/*static_assert(sizeof(jmp_buf) == 64);
|
if(!call_safe(function_ptr, entity))
|
||||||
++*(DWORD*)0x20B21FC;
|
|
||||||
int res = setjmp(((jmp_buf*)0x20B4218)[*(DWORD*)0x20B21FC]);
|
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
--*(DWORD*)0x20B21FC;
|
throw std::runtime_error("Error executing function '" + function + "'");
|
||||||
return;
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
function_ptr(entity.val);
|
|
||||||
|
|
||||||
//--*(DWORD*)0x20B21FC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4611)
|
||||||
|
bool scripting::call_safe(const game::native::scr_call_t function, const game::native::scr_entref_t entref)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(jmp_buf) == 64);
|
||||||
|
|
||||||
|
*game::native::g_script_error_level += 1;
|
||||||
|
if (setjmp(game::native::g_script_error[*game::native::g_script_error_level]))
|
||||||
|
{
|
||||||
|
*game::native::g_script_error_level -= 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function(entref.val);
|
||||||
|
|
||||||
|
*game::native::g_script_error_level -= 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
int scripting::find_function_index(const std::string& function)
|
int scripting::find_function_index(const std::string& function)
|
||||||
{
|
{
|
||||||
auto function_entry = game::scripting::instance_function_map.find(function);
|
auto function_entry = game::scripting::instance_function_map.find(function);
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
static void on_start(const std::function<void()>& callback);
|
static void on_start(const std::function<void()>& callback);
|
||||||
static void on_stop(const std::function<void()>& callback);
|
static void on_stop(const std::function<void()>& callback);
|
||||||
|
|
||||||
static void propagate_scripting_error(const std::exception& e);
|
static void propagate_error(const std::exception& e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<chaiscript::ChaiScript> chai_;
|
std::unique_ptr<chaiscript::ChaiScript> chai_;
|
||||||
@ -80,5 +80,6 @@ private:
|
|||||||
static void stop_execution();
|
static void stop_execution();
|
||||||
|
|
||||||
static void call(const std::string& function, unsigned int entity_id, const std::vector<chaiscript::Boxed_Value>& arguments);
|
static void call(const std::string& function, unsigned int entity_id, const std::vector<chaiscript::Boxed_Value>& arguments);
|
||||||
|
static bool call_safe(game::native::scr_call_t function, game::native::scr_entref_t entref);
|
||||||
static int find_function_index(const std::string& function);
|
static int find_function_index(const std::string& function);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user