Skip to content

Commit

Permalink
remove scheduler hooks (use plugin sdk)
Browse files Browse the repository at this point in the history
  • Loading branch information
ineed bots committed Aug 3, 2024
1 parent 232ce3b commit 83ffa1c
Show file tree
Hide file tree
Showing 5 changed files with 5 additions and 296 deletions.
8 changes: 0 additions & 8 deletions src/codsrc/clientscript/cscr_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4702,10 +4702,6 @@ namespace codsrc
// Decomp Status: Tested, Completed
void Scr_InitSystem(game::scriptInstance_t inst)
{
// our additions
scheduler::exec_pre_scr_init_funcs(inst);
//

assert(!game::gScrVarPub[inst].timeArrayId);

//assert(!game::gScrVarPub[inst].ext_threadcount);
Expand All @@ -4731,10 +4727,6 @@ namespace codsrc
assert(!game::gScrVarPub[inst].freeEntList);

game::g_script_error_level[inst] = -1;

// our additions
scheduler::exec_post_scr_init_funcs(inst);
//
}

//Restored function
Expand Down
7 changes: 1 addition & 6 deletions src/component/fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,8 @@ namespace fileio

void add_file_io()
{
scheduler::on_pre_scr_init_system([]([[maybe_unused]] game::scriptInstance_t inst)
scheduler::on_scr_execute([]()
{
if (inst != game::SCRIPTINSTANCE_SERVER)
{
return;
}

close_all_scr_fh();
});

Expand Down
2 changes: 1 addition & 1 deletion src/component/gsc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <stdinc.hpp>
#include "loader/component_loader.hpp"

#include "gsc.hpp"

namespace gsc
Expand Down
259 changes: 2 additions & 257 deletions src/component/scheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,266 +1,11 @@
#include <stdinc.hpp>
#include "loader/component_loader.hpp"

#include "scheduler.hpp"

#include <utils/concurrency.hpp>
#include <utils/hook.hpp>

namespace scheduler
{
namespace
void on_scr_execute(const std::function<void()>& callback)
{
struct task
{
std::function<bool()> handler{};
std::chrono::milliseconds interval{};
std::chrono::high_resolution_clock::time_point last_call{};
};

using task_list = std::vector<task>;

class task_pipeline
{
public:
void add(task&& task)
{
new_callbacks_.access([&task](task_list& tasks)
{
tasks.emplace_back(std::move(task));
});
}

void execute()
{
callbacks_.access([&](task_list& tasks)
{
this->merge_callbacks();

for (auto i = tasks.begin(); i != tasks.end();)
{
const auto now = std::chrono::high_resolution_clock::now();
const auto diff = now - i->last_call;

if (diff < i->interval)
{
++i;
continue;
}

i->last_call = now;

const auto res = i->handler();
if (res == cond_end)
{
i = tasks.erase(i);
}
else
{
++i;
}
}
});
}

private:
utils::concurrency::container<task_list> new_callbacks_;
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;

void merge_callbacks()
{
callbacks_.access([&](task_list& tasks)
{
new_callbacks_.access([&](task_list& new_tasks)
{
tasks.insert(tasks.end(), std::move_iterator<task_list::iterator>(new_tasks.begin()), std::move_iterator<task_list::iterator>(new_tasks.end()));
new_tasks = {};
});
});
}
};

std::thread thread;
task_pipeline pipelines[pipeline::count];

void execute(const pipeline type)
{
assert(type >= 0 && type < pipeline::count);
pipelines[type].execute();
}

void execute_server()
{
execute(pipeline::server);
}

void execute_main()
{
execute(pipeline::main);
}

utils::hook::detour com_init_hook;
utils::hook::detour gscr_postloadscripts_hook;

std::vector<std::function<void()>> post_init_funcs;
bool com_inited = false;

void on_post_init_hook()
{
if (com_inited)
{
return;
}
com_inited = true;
for (const auto& func : post_init_funcs)
{
func();
}

post_init_funcs.clear();
}

void com_init_stub()
{
com_init_hook.invoke<void>();
on_post_init_hook();
}

std::vector<std::function<void(game::scriptInstance_t)>> pre_scr_init_funcs;
std::vector<std::function<void(game::scriptInstance_t)>> post_scr_init_funcs;

utils::hook::detour pre_scr_init_system_hook;
utils::hook::detour post_scr_init_system_hook;

void* pre_scr_init_system_original;
void* post_scr_init_system_original;

NAKED void pre_scr_init_system_stub()
{
__asm
{
pushad;
push eax;
call exec_pre_scr_init_funcs;
add esp, 4;
popad;

push pre_scr_init_system_original;
ret;
}
}

NAKED void post_scr_init_system_stub()
{
__asm
{
pushad;
push eax;
call exec_post_scr_init_funcs;
add esp, 4;
popad;

push post_scr_init_system_original;
ret;
}
}
plugin::get()->get_interface()->callbacks()->on_scripts_execute((plutonium::sdk::v1::interfaces::callbacks::on_scripts_execute_callback)&callback);
}

void schedule(const std::function<bool()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
{
assert(type >= 0 && type < pipeline::count);

task task;
task.handler = callback;
task.interval = delay;
task.last_call = std::chrono::high_resolution_clock::now();

pipelines[type].add(std::move(task));
}

void loop(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
{
schedule([callback]()
{
callback();
return cond_continue;
}, type, delay);
}

void once(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
{
schedule([callback]()
{
callback();
return cond_end;
}, type, delay);
}

void on_init(const std::function<void()>& callback)
{
if (com_inited)
{
once(callback, pipeline::main);
}
else
{
post_init_funcs.push_back(callback);
}
}

void on_pre_scr_init_system(const std::function<void(game::scriptInstance_t)>& callback)
{
pre_scr_init_funcs.push_back(callback);
}

void on_post_scr_init_system(const std::function<void(game::scriptInstance_t)>& callback)
{
post_scr_init_funcs.push_back(callback);
}

void exec_pre_scr_init_funcs(game::scriptInstance_t inst)
{
for (const auto& func : pre_scr_init_funcs)
{
func(inst);
}
}

void exec_post_scr_init_funcs(game::scriptInstance_t inst)
{
for (const auto& func : post_scr_init_funcs)
{
func(inst);
}
}

class component final : public component_interface
{
public:
void post_unpack() override
{
thread = std::thread([]()
{
while (true)
{
execute(pipeline::async);
std::this_thread::sleep_for(10ms);
}
});

com_init_hook.create(SELECT(0x0, 0x59D710), com_init_stub);
utils::hook::call(SELECT(0x0, 0x503B5D), execute_server);
utils::hook::call(SELECT(0x0, 0x59DCFD), execute_main);

// for when we dont use decomp
pre_scr_init_system_hook.create(0x699865, pre_scr_init_system_stub);
pre_scr_init_system_original = pre_scr_init_system_hook.get_original();
post_scr_init_system_hook.create(0x699924, post_scr_init_system_stub);
post_scr_init_system_original = post_scr_init_system_hook.get_original();
}
};
}

REGISTER_COMPONENT(scheduler::component)
25 changes: 1 addition & 24 deletions src/component/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,5 @@

namespace scheduler
{
enum pipeline
{
server,
async,
main,
count,
};

static const bool cond_continue = false;
static const bool cond_end = true;

void schedule(const std::function<bool()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);
void loop(const std::function<void()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);
void once(const std::function<void()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);

void on_init(const std::function<void()>& callback);

void on_pre_scr_init_system(const std::function<void(game::scriptInstance_t)>& callback);
void on_post_scr_init_system(const std::function<void(game::scriptInstance_t)>& callback);
void exec_pre_scr_init_funcs(game::scriptInstance_t inst);
void exec_post_scr_init_funcs(game::scriptInstance_t inst);
void on_scr_execute(const std::function<void()>& callback);
}

0 comments on commit 83ffa1c

Please sign in to comment.