Merge notification and scripting modules
This commit is contained in:
parent
90a63365bd
commit
af35816c0b
@ -24,6 +24,20 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T* get()
|
||||||
|
{
|
||||||
|
for(const auto& module_ : *modules_)
|
||||||
|
{
|
||||||
|
if(typeid(*module_.get()) == typeid(T))
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(module_.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static void register_module(std::unique_ptr<module>&& module);
|
static void register_module(std::unique_ptr<module>&& module);
|
||||||
|
|
||||||
static bool post_start();
|
static bool post_start();
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include "loader/module_loader.hpp"
|
|
||||||
#include "notification.hpp"
|
|
||||||
#include "utils/hook.hpp"
|
|
||||||
|
|
||||||
std::mutex notification::mutex_;
|
|
||||||
std::vector<std::function<void(game::scripting::event*)>> notification::callbacks_;
|
|
||||||
|
|
||||||
void notification::post_load()
|
|
||||||
{
|
|
||||||
utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), &vm_notify_stub, HOOK_CALL).install()->quick();
|
|
||||||
utils::hook(SELECT_VALUE(0x6128BE, 0x56D541, 0x4EFAF9), &vm_notify_stub, HOOK_CALL).install()->quick();
|
|
||||||
|
|
||||||
if (game::is_sp())
|
|
||||||
{
|
|
||||||
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
|
||||||
}
|
|
||||||
|
|
||||||
//scripting::on_start(cleanup);
|
|
||||||
scripting::on_stop(cleanup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void notification::pre_destroy()
|
|
||||||
{
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void notification::listen(const std::function<void(game::scripting::event*)>& callback)
|
|
||||||
{
|
|
||||||
std::lock_guard _(mutex_);
|
|
||||||
callbacks_.push_back(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void notification::cleanup()
|
|
||||||
{
|
|
||||||
std::lock_guard _(mutex_);
|
|
||||||
callbacks_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void notification::dispatch(game::scripting::event* event)
|
|
||||||
{
|
|
||||||
decltype(callbacks_) copy;
|
|
||||||
{
|
|
||||||
std::lock_guard _(mutex_);
|
|
||||||
copy = callbacks_;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& callback : copy)
|
|
||||||
{
|
|
||||||
callback(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void notification::vm_notify_stub(const unsigned int notify_id, const unsigned short type,
|
|
||||||
game::native::VariableValue* stack)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
game::scripting::event e;
|
|
||||||
e.name = game::native::SL_ConvertToString(type);
|
|
||||||
e.entity_id = notify_id;
|
|
||||||
|
|
||||||
if (e.name == "touch") return; // Skip that for now
|
|
||||||
|
|
||||||
//printf("%X: %s\n", e.entity_id, e.name.data());
|
|
||||||
|
|
||||||
for (auto value = stack; value->type != game::native::SCRIPT_END; --value)
|
|
||||||
{
|
|
||||||
e.arguments.emplace_back(*value);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(&e);
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
scripting::propagate_error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
game::native::VM_Notify(notify_id, type, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_MODULE(notification)
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "loader/module_loader.hpp"
|
|
||||||
#include "game/scripting/event.hpp"
|
|
||||||
#include "scripting.hpp"
|
|
||||||
|
|
||||||
class notification final : public module
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void post_load() override;
|
|
||||||
void pre_destroy() override;
|
|
||||||
|
|
||||||
static void listen(const std::function<void(game::scripting::event*)>& callback);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::mutex mutex_;
|
|
||||||
static std::vector<std::function<void(game::scripting::event*)>> callbacks_;
|
|
||||||
|
|
||||||
static void cleanup();
|
|
||||||
static void dispatch(game::scripting::event* event);
|
|
||||||
|
|
||||||
static void vm_notify_stub(unsigned int notify_id, unsigned short type, game::native::VariableValue* stack);
|
|
||||||
};
|
|
@ -1,61 +1,35 @@
|
|||||||
#include <std_include.hpp>
|
#include <std_include.hpp>
|
||||||
#include "notification.hpp"
|
#include "utils/hook.hpp"
|
||||||
#include "utils/io.hpp"
|
#include "utils/io.hpp"
|
||||||
|
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
#include "scripting.hpp"
|
||||||
|
|
||||||
utils::hook scripting::start_hook_;
|
utils::hook scripting::start_hook_;
|
||||||
utils::hook scripting::stop_hook_;
|
utils::hook scripting::stop_hook_;
|
||||||
|
|
||||||
std::mutex scripting::mutex_;
|
|
||||||
std::vector<std::function<void()>> scripting::start_callbacks_;
|
|
||||||
std::vector<std::function<void()>> scripting::stop_callbacks_;
|
|
||||||
|
|
||||||
void scripting::post_start()
|
|
||||||
{
|
|
||||||
on_start([this]()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this->load_scripts();
|
|
||||||
notification::listen([this](game::scripting::event* event)
|
|
||||||
{
|
|
||||||
for(const auto& script : this->scripts_)
|
|
||||||
{
|
|
||||||
script->get_event_handler()->dispatch(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
propagate_error(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
on_stop([this]()
|
|
||||||
{
|
|
||||||
this->scripts_.clear();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void scripting::post_load()
|
void scripting::post_load()
|
||||||
{
|
{
|
||||||
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), []()
|
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), &start_execution_stub, HOOK_CALL) //
|
||||||
{
|
->install() //
|
||||||
start_execution();
|
->quick();
|
||||||
reinterpret_cast<void(*)()>(start_hook_.get_original())();
|
|
||||||
}, HOOK_CALL)->install()->quick();
|
|
||||||
|
|
||||||
stop_hook_.initialize(SELECT_VALUE(0x528B04, 0x569E46, 0x4F03FA), []()
|
stop_hook_.initialize(SELECT_VALUE(0x528B04, 0x569E46, 0x4F03FA), &stop_execution_stub, HOOK_CALL) //
|
||||||
|
->install() //
|
||||||
|
->quick();
|
||||||
|
|
||||||
|
utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), &vm_notify_stub, HOOK_CALL).install()->quick();
|
||||||
|
utils::hook(SELECT_VALUE(0x6128BE, 0x56D541, 0x4EFAF9), &vm_notify_stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
if (game::is_sp())
|
||||||
{
|
{
|
||||||
stop_execution();
|
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
|
||||||
reinterpret_cast<void(*)()>(stop_hook_.get_original())();
|
}
|
||||||
}, HOOK_CALL)->install()->quick();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::pre_destroy()
|
void scripting::pre_destroy()
|
||||||
{
|
{
|
||||||
this->scripts_.clear();
|
this->scripts_.clear();
|
||||||
start_callbacks_.clear();
|
|
||||||
stop_callbacks_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::load_scripts()
|
void scripting::load_scripts()
|
||||||
@ -80,16 +54,29 @@ void scripting::load_scripts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_start(const std::function<void()>& callback)
|
void scripting::start_execution()
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
try
|
||||||
start_callbacks_.push_back(callback);
|
{
|
||||||
|
this->load_scripts();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
propagate_error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::on_stop(const std::function<void()>& callback)
|
void scripting::stop_execution()
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
this->scripts_.clear();
|
||||||
stop_callbacks_.push_back(callback);
|
}
|
||||||
|
|
||||||
|
void scripting::dispatch(game::scripting::event* event)
|
||||||
|
{
|
||||||
|
for (const auto& script : this->scripts_)
|
||||||
|
{
|
||||||
|
script->get_event_handler()->dispatch(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::propagate_error(const std::exception& e)
|
void scripting::propagate_error(const std::exception& e)
|
||||||
@ -101,33 +88,44 @@ void scripting::propagate_error(const std::exception& e)
|
|||||||
scheduler::error("Script execution error\n(see console for actual details)\n", 5);
|
scheduler::error("Script execution error\n(see console for actual details)\n", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::start_execution()
|
void scripting::start_execution_stub()
|
||||||
{
|
{
|
||||||
decltype(start_callbacks_) copy;
|
module_loader::get<scripting>()->start_execution();
|
||||||
{
|
reinterpret_cast<void(*)()>(start_hook_.get_original())();
|
||||||
std::lock_guard _(mutex_);
|
|
||||||
copy = start_callbacks_;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& callback : copy)
|
|
||||||
{
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scripting::stop_execution()
|
void scripting::stop_execution_stub()
|
||||||
{
|
{
|
||||||
decltype(stop_callbacks_) copy;
|
module_loader::get<scripting>()->stop_execution();
|
||||||
|
reinterpret_cast<void(*)()>(stop_hook_.get_original())();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scripting::vm_notify_stub(const unsigned int notify_id, const unsigned short type,
|
||||||
|
game::native::VariableValue* stack)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
game::scripting::event e;
|
||||||
copy = stop_callbacks_;
|
e.name = game::native::SL_ConvertToString(type);
|
||||||
std::reverse(copy.begin(), copy.end());
|
e.entity_id = notify_id;
|
||||||
|
|
||||||
|
if (e.name == "touch") return; // Skip that for now
|
||||||
|
|
||||||
|
//printf("%X: %s\n", e.entity_id, e.name.data());
|
||||||
|
|
||||||
|
for (auto value = stack; value->type != game::native::SCRIPT_END; --value)
|
||||||
|
{
|
||||||
|
e.arguments.emplace_back(*value);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_loader::get<scripting>()->dispatch(&e);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
propagate_error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& callback : copy)
|
game::native::VM_Notify(notify_id, type, stack);
|
||||||
{
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_MODULE(scripting)
|
REGISTER_MODULE(scripting)
|
||||||
|
@ -6,13 +6,9 @@
|
|||||||
class scripting final : public module
|
class scripting final : public module
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_start() override;
|
|
||||||
void post_load() override;
|
void post_load() override;
|
||||||
void pre_destroy() override;
|
void pre_destroy() override;
|
||||||
|
|
||||||
static void on_start(const std::function<void()>& callback);
|
|
||||||
static void on_stop(const std::function<void()>& callback);
|
|
||||||
|
|
||||||
static void propagate_error(const std::exception& e);
|
static void propagate_error(const std::exception& e);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -20,13 +16,16 @@ private:
|
|||||||
|
|
||||||
void load_scripts();
|
void load_scripts();
|
||||||
|
|
||||||
|
void start_execution();
|
||||||
|
void stop_execution();
|
||||||
|
|
||||||
|
void dispatch(game::scripting::event* event);
|
||||||
|
|
||||||
static utils::hook start_hook_;
|
static utils::hook start_hook_;
|
||||||
static utils::hook stop_hook_;
|
static utils::hook stop_hook_;
|
||||||
|
|
||||||
static std::mutex mutex_;
|
static void start_execution_stub();
|
||||||
static std::vector<std::function<void()>> start_callbacks_;
|
static void stop_execution_stub();
|
||||||
static std::vector<std::function<void()>> stop_callbacks_;
|
static void vm_notify_stub(const unsigned int notify_id, const unsigned short type,
|
||||||
|
game::native::VariableValue* stack);
|
||||||
static void start_execution();
|
|
||||||
static void stop_execution();
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user