#include "develhook.h" #include "util/logging.h" #include "util/detour.h" #include "util/libutils.h" #include "util/utils.h" #include "avs/core.h" #include "avs/game.h" #include "hooks/wmischook.h" #include "external/stackwalker/stackwalker.h" #include #include #include namespace hooks::devel { static class Thumbnail : public Routine { public: using Routine::Routine; void entry_main() override { log_warning("hooks::devel::thumbnail", "Forcing thumbnail patch.."); hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "FORCE", "thumbnail"); } } thumbnail_("thum_test"); static class Msacm : public Routine { public: using Routine::Routine; void entry_main() override { log_warning("hooks::devel::msacm", "Forcing msacm patch.."); hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "FORCE", "msacm"); } } msacm_("acm_test"); static class Wmisc : public Routine { public: using Routine::Routine; void attach() override { log_warning("hooks::devel::wmisc", "Disabling auto-patching.."); hooks::wmisc::skip_patching_by_model(true); hooks::wmisc::apply_performance_hacks(avs::game::DLL_INSTANCE, "FORCE", "bmsound"); } } wmisc_("wmisc_test"); static class Avs_fs : public Routine { private: static constexpr char needle_[] = ""; // set to "" to print all inline static avs::core::AVS_FS_LSTAT_T avs_fs_lstat_; inline static avs::core::AVS_FS_MOUNT_T avs_fs_mount_; inline static avs::core::AVS_FS_OPEN_T avs_fs_open_; static int on_avs_fs_lstat(const char *path, struct avs::core::avs_stat *stat) { if (strstr(path, needle_)) { log_info("hooks::devel", "{}({})", __FUNCTION__, path); } return avs_fs_lstat_(path, stat); } static avs::core::avs_file_t on_avs_fs_mount(const char *mountpoint, const char *fsroot, const char *fstype, void *data) { if (strstr(fsroot, needle_)) { log_info("hooks::devel", "{}({}=>{}) @{} :nullptr data?{} ", __FUNCTION__, fsroot, mountpoint, fstype, data == nullptr); } return avs_fs_mount_(mountpoint, fsroot, fstype, data); } static avs::core::avs_file_t on_avs_fs_open(const char *name, uint16_t mode, int flags) { if (strstr(name, needle_)) { log_info("hooks::devel", "{}({}::{}) @{}", __FUNCTION__, name, mode, flags); } return avs_fs_open_(name, mode, flags); } public: using Routine::Routine; void entry_main() override { detour::trampoline(reinterpret_cast(avs::core::avs_fs_lstat), reinterpret_cast(on_avs_fs_lstat), reinterpret_cast(&avs_fs_lstat_)); detour::trampoline(reinterpret_cast(avs::core::avs_fs_mount), reinterpret_cast(on_avs_fs_mount), reinterpret_cast(&avs_fs_mount_)); detour::trampoline(reinterpret_cast(avs::core::avs_fs_open), reinterpret_cast(on_avs_fs_open), reinterpret_cast(&avs_fs_open_)); } } avs_fs_("avs_fs_detour"); std::vector from_env(const char *str) { std::vector r; std::stringstream ss(getenv(str) ? getenv(str) : ""); std::string flag; while (std::getline(ss, flag, ';')) { r.push_back(flag); } return r; } static std::vector &routines() { static std::vector routines_; if (routines_.empty()) { //Default routines routines_.push_back(&avs_fs_); routines_.push_back(&thumbnail_); routines_.push_back(&msacm_); routines_.push_back(&wmisc_); } return routines_; } Routine *active_routine(const char *name) { unsigned int hash = to_hash(name); for (auto &routine: routines()) { if (routine->hash() == hash) return routine; } return nullptr; } void bind_routine(Routine *routine) { routines().push_back(routine); } void log_environment() { log_warning("hooks::devel", "WINEDLLOVERRIDES: '{}'", getenv("WINEDLLOVERRIDES") ? getenv("WINEDLLOVERRIDES") : "null"); } void entry_main() { log_environment(); const auto rnames = from_env("SPICE_DEVEL"); if (!rnames.empty()) log_info("hooks::devel", "Run subroutines.."); for (const auto &routinename: from_env("SPICE_DEVEL")) { Routine *routine = active_routine(routinename.c_str()); if (routine) routine->entry_main(); } } void attach() { const auto rnames = from_env("SPICE_DEVEL"); if (!rnames.empty()) log_info("hooks::devel", "Attach subroutines.."); for (const auto &rname: rnames) { Routine *routine = active_routine(rname.c_str()); if (routine) routine->attach(); } } }