Continue scripting

This commit is contained in:
momo5502 2019-01-13 21:28:05 +01:00
parent 508cc5d51e
commit 7cde029b78
5 changed files with 116 additions and 22 deletions

View File

@ -32,7 +32,7 @@ namespace game
{
++scrVarGlob[4 * value->u.entityId];
}
else if (value->type == SCRIPT_STRING)
else if ((value->type & ~1) == SCRIPT_STRING)
{
static const auto size = is_sp() ? 16 : 12;
const auto ref_count = reinterpret_cast<unsigned volatile *>(*scrMemTreePub + size * value

View File

@ -3,6 +3,9 @@
#include "notification.hpp"
#include "utils/hook.hpp"
std::mutex notification::mutex_;
std::vector<std::function<void(notification::event*)>> notification::callbacks_;
void notification::post_load()
{
utils::hook(SELECT_VALUE(0x6109F3, 0x56B637, 0x4EDFF7), vm_notify_stub, HOOK_CALL).install()->quick();
@ -12,6 +15,40 @@ void notification::post_load()
{
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(event*)>& callback)
{
std::lock_guard _(mutex_);
callbacks_.push_back(callback);
}
void notification::cleanup()
{
std::lock_guard _(mutex_);
callbacks_.clear();
}
void notification::dispatch(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,
@ -26,10 +63,7 @@ void notification::vm_notify_stub(const unsigned int notify_id, const unsigned s
e.arguments.emplace_back(*value);
}
if(!e.arguments.empty())
{
printf("");
}
dispatch(&e);
game::native::VM_Notify(notify_id, type, stack);
}

View File

@ -14,7 +14,16 @@ public:
};
void post_load() override;
void pre_destroy() override;
static void listen(const std::function<void(event*)>& callback);
private:
static std::mutex mutex_;
static std::vector<std::function<void(event*)>> callbacks_;
static void cleanup();
static void dispatch(event* event);
static void vm_notify_stub(unsigned int notify_id, unsigned short type, game::native::VariableValue* stack);
};

View File

@ -1,5 +1,7 @@
#include <std_include.hpp>
#include "scripting.hpp"
#include "notification.hpp"
#include "utils/io.hpp"
#include "utils/string.hpp"
utils::hook scripting::start_hook_;
utils::hook scripting::stop_hook_;
@ -10,12 +12,12 @@ std::vector<std::function<void()>> scripting::stop_callbacks_;
scripting::variable::variable(game::native::VariableValue value) : value_(value)
{
game::native::AddRefToValue(&value);
//game::native::AddRefToValue(&value);
}
scripting::variable::~variable()
{
game::native::RemoveRefToValue(this->value_.type, this->value_.u);
//game::native::RemoveRefToValue(this->value_.type, this->value_.u);
}
scripting::variable::operator game::native::VariableValue() const
@ -23,6 +25,15 @@ scripting::variable::operator game::native::VariableValue() const
return this->value_;
}
void scripting::post_start()
{
on_start(std::bind(&scripting::initialize, this));
on_stop([this]()
{
this->chai_ = {};
});
}
void scripting::post_load()
{
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), []()
@ -36,16 +47,6 @@ void scripting::post_load()
stop_execution();
static_cast<void(*)()>(stop_hook_.get_original())();
}, HOOK_CALL)->install()->quick();
on_start([this]()
{
this->chai_ = std::make_unique<chaiscript::ChaiScript>();
});
on_stop([this]()
{
this->chai_ = {};
});
}
void scripting::pre_destroy()
@ -55,6 +56,52 @@ void scripting::pre_destroy()
stop_callbacks_.clear();
}
void scripting::initialize()
{
this->chai_ = std::make_unique<chaiscript::ChaiScript>();
this->chai_->add(chaiscript::fun([](const std::string& string)
{
printf("%s\n", string.data());
}), "print");
this->chai_->add(chaiscript::fun(
[this](const std::function<void(const std::string&,
const std::vector<chaiscript::Boxed_Value>&)>& callback)
{
std::lock_guard _(mutex_);
this->callbacks_.push_back(callback);
}), "onNotify");
this->load_scripts();
notification::listen([this](notification::event* event)
{
decltype(this->callbacks_) copy;
{
std::lock_guard _(mutex_);
copy = this->callbacks_;
}
for (const auto& callback : copy)
{
callback(event->name, {});
}
});
}
void scripting::load_scripts() const
{
const auto scripts = utils::io::list_files("open-iw5/scripts/");
for (const auto& script : scripts)
{
if (script.substr(script.find_last_of('.') + 1) == "chai")
{
this->chai_->eval_file(script);
}
}
}
void scripting::on_start(const std::function<void()>& callback)
{
std::lock_guard _(mutex_);
@ -69,8 +116,7 @@ void scripting::on_stop(const std::function<void()>& callback)
void scripting::start_execution()
{
std::vector<std::function<void()>> copy;
decltype(start_callbacks_) copy;
{
std::lock_guard _(mutex_);
copy = start_callbacks_;
@ -84,11 +130,11 @@ void scripting::start_execution()
void scripting::stop_execution()
{
std::vector<std::function<void()>> copy;
decltype(stop_callbacks_) copy;
{
std::lock_guard _(mutex_);
copy = stop_callbacks_;
std::reverse(copy.begin(), copy.end());
}
for (const auto& callback : copy)

View File

@ -18,6 +18,7 @@ public:
game::native::VariableValue value_;
};
void post_start() override;
void post_load() override;
void pre_destroy() override;
@ -26,6 +27,10 @@ public:
private:
std::unique_ptr<chaiscript::ChaiScript> chai_;
std::vector<std::function<void(const std::string&, const std::vector<chaiscript::Boxed_Value>&)>> callbacks_;
void initialize();
void load_scripts() const;
static utils::hook start_hook_;
static utils::hook stop_hook_;