diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index f8d30530..d902d221 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -6,6 +6,7 @@ #include "game_console.hpp" #include "fastfiles.hpp" #include "scheduler.hpp" +#include "logfile.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -40,6 +41,11 @@ namespace command void client_command(const int client_num) { + if (!logfile::client_command_stub(client_num)) + { + return; + } + params_sv params = {}; const auto command = utils::string::to_lower(params[0]); diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 63e9c434..0edf8476 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -270,7 +270,15 @@ namespace console void post_unpack() override { - ShowWindow(GetConsoleWindow(), SW_SHOW); + if (game::environment::is_dedi()) + { + ShowWindow(GetConsoleWindow(), SW_HIDE); + } + else + { + ShowWindow(GetConsoleWindow(), SW_SHOW); + } + SetConsoleTitle("H1-Mod"); con.kill_event = CreateEvent(NULL, TRUE, FALSE, NULL); diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp index 4a4d049b..15d11826 100644 --- a/src/client/component/filesystem.cpp +++ b/src/client/component/filesystem.cpp @@ -12,36 +12,6 @@ namespace filesystem { - namespace - { - bool custom_path_registered = false; - - std::string get_binary_directory() - { - const auto dir = game_module::get_host_module().get_folder(); - return utils::string::replace(dir, "/", "\\"); - } - - void register_custom_path_stub(const char* path, const char* dir) - { - if (!custom_path_registered) - { - custom_path_registered = true; - - const auto launcher_dir = get_binary_directory(); - game::FS_AddLocalizedGameDirectory(launcher_dir.data(), "data"); - } - - game::FS_AddLocalizedGameDirectory(path, dir); - } - - void fs_startup_stub(const char* gamename) - { - custom_path_registered = false; - game::FS_Startup(gamename); - } - } - file::file(std::string name) : name_(std::move(name)) { @@ -110,19 +80,6 @@ namespace filesystem public: void post_unpack() override { - // Set fs_basegame - dvars::override::register_string("fs_basegame", "h1-mod", game::DVAR_FLAG_WRITE); - - utils::hook::call(SELECT_VALUE(0x1403B76E2, 0x1404ED3E2), fs_startup_stub); - if (game::environment::is_mp()) - { - utils::hook::call(0x1404ED823, fs_startup_stub); - } - - utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); - utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); - utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); - get_search_paths().insert("."); get_search_paths().insert("h1-mod"); get_search_paths().insert("data"); @@ -130,4 +87,4 @@ namespace filesystem }; } -//REGISTER_COMPONENT(filesystem::component) \ No newline at end of file +REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index edb00f28..e728716c 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -2,15 +2,10 @@ #include "loader/component_loader.hpp" #include "scheduler.hpp" -#include "game/scripting/entity.hpp" -#include "game/scripting/execution.hpp" -#include "game/scripting/lua/value_conversion.hpp" -#include "game/scripting/lua/error.hpp" +#include "logfile.hpp" #include -#include "logfile.hpp" - namespace logfile { std::unordered_map vm_execute_hooks; @@ -20,6 +15,9 @@ namespace logfile utils::hook::detour scr_player_killed_hook; utils::hook::detour scr_player_damage_hook; + utils::hook::detour client_command_hook; + utils::hook::detour g_shutdown_game_hook; + std::vector player_killed_callbacks; std::vector player_damage_callbacks; @@ -147,51 +145,6 @@ namespace logfile meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); } - void client_command_stub(const int clientNum) - { - auto self = &game::mp::g_entities[clientNum]; - char cmd[1024] = {0}; - - game::SV_Cmd_ArgvBuffer(0, cmd, 1024); - - if (cmd == "say"s || cmd == "say_team"s) - { - auto hidden = false; - std::string message(game::ConcatArgs(1)); - - hidden = message[1] == '/'; - message.erase(0, hidden ? 2 : 1); - - scheduler::once([cmd, message, self]() - { - const scripting::entity level{*game::levelEntityId}; - const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; - - scripting::notify(level, cmd, {player, message}); - scripting::notify(player, cmd, {message}); - }, scheduler::pipeline::server); - - if (hidden) - { - return; - } - } - - // ClientCommand - return utils::hook::invoke(0x4132E0_b, clientNum); - } - - void g_shutdown_game_stub(const int freeScripts) - { - { - const scripting::entity level{*game::levelEntityId}; - scripting::notify(level, "shutdownGame_called", {1}); - } - - // G_ShutdownGame - return utils::hook::invoke(0x422F30_b, freeScripts); - } - unsigned int local_id_to_entity(unsigned int local_id) { const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; @@ -291,27 +244,55 @@ namespace logfile hook_enabled = false; } + bool client_command_stub(const int client_num) + { + auto self = &game::mp::g_entities[client_num]; + char cmd[1024] = {0}; + + game::SV_Cmd_ArgvBuffer(0, cmd, 1024); + + if (cmd == "say"s || cmd == "say_team"s) + { + auto hidden = false; + std::string message(game::ConcatArgs(1)); + + hidden = message[1] == '/'; + message.erase(0, hidden ? 2 : 1); + + scheduler::once([cmd, message, self, hidden]() + { + const scripting::entity level{*game::levelEntityId}; + const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; + + scripting::notify(level, cmd, {player, message, hidden}); + scripting::notify(player, cmd, {message, hidden}); + }, scheduler::pipeline::server); + + if (hidden) + { + return false; + } + } + + return true; + } + class component final : public component_interface { public: void post_unpack() override { - utils::hook::jump(SELECT_VALUE(0x0, 0x444645_b), utils::hook::assemble(vm_execute_stub), true); + utils::hook::jump(SELECT_VALUE(0x0, 0x5111A5_b), utils::hook::assemble(vm_execute_stub), true); if (game::environment::is_sp()) { return; } - utils::hook::call(0x54EB46_b, client_command_stub); - scr_player_damage_hook.create(0x1CE780_b, scr_player_damage_stub); scr_player_killed_hook.create(0x1CEA60_b, scr_player_killed_stub); - - utils::hook::call(0x5520E0_b, g_shutdown_game_stub); - utils::hook::call(0x5525E1_b, g_shutdown_game_stub); } }; } -//REGISTER_COMPONENT(logfile::component) \ No newline at end of file +REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logfile.hpp b/src/client/component/logfile.hpp index 77f699c8..4ab67966 100644 --- a/src/client/component/logfile.hpp +++ b/src/client/component/logfile.hpp @@ -1,5 +1,10 @@ #pragma once +#include "game/scripting/entity.hpp" +#include "game/scripting/execution.hpp" +#include "game/scripting/lua/value_conversion.hpp" +#include "game/scripting/lua/error.hpp" + namespace logfile { extern std::unordered_map vm_execute_hooks; @@ -10,4 +15,6 @@ namespace logfile void enable_vm_execute_hook(); void disable_vm_execute_hook(); + + bool client_command_stub(const int client_num); } \ No newline at end of file diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index 1d2e9635..fdb8bae6 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -94,6 +94,7 @@ namespace scripting script_function_table.clear(); } + scripting::notify(*game::levelEntityId, "shutdownGame_called", {1}); lua::engine::stop(); return g_shutdown_game_hook.invoke(free_scripts); } @@ -159,26 +160,6 @@ namespace scripting scripting::token_map[str] = result; return result; } - - game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, int allow_create_default) - { - const auto result = db_find_xasset_header_hook.invoke(type, name, allow_create_default); - if (!g_dump_scripts->current.enabled || type != game::XAssetType::ASSET_TYPE_SCRIPTFILE) - { - return result; - } - - std::string buffer; - buffer.append(result.scriptfile->name, strlen(result.scriptfile->name) + 1); - buffer.append(reinterpret_cast(&result.scriptfile->compressedLen), 4); - buffer.append(reinterpret_cast(&result.scriptfile->len), 4); - buffer.append(reinterpret_cast(&result.scriptfile->bytecodeLen), 4); - buffer.append(result.scriptfile->buffer, result.scriptfile->compressedLen); - buffer.append(result.scriptfile->bytecode, result.scriptfile->bytecodeLen); - utils::io::write_file(utils::string::va("gsc_dump/%s.gscbin", name), buffer); - - return result; - } } class component final : public component_interface @@ -205,9 +186,6 @@ namespace scripting g_shutdown_game_hook.create(SELECT_VALUE(0x0, 0x422F30_b), g_shutdown_game_stub); - db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub); - g_dump_scripts = dvars::register_bool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts"); - scheduler::loop([]() { lua::engine::run_frame(); @@ -216,4 +194,4 @@ namespace scripting }; } -//REGISTER_COMPONENT(scripting::component) +REGISTER_COMPONENT(scripting::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index a096119b..ff810c86 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -12,6 +12,7 @@ #include "game_module.hpp" #include "fps.hpp" #include "server_list.hpp" +#include "filesystem.hpp" #include "game/ui_scripting/execution.hpp" #include "game/scripting/execution.hpp" @@ -223,8 +224,19 @@ namespace ui_scripting load_script("lui_common", lui_common); - load_scripts("h1-mod/ui_scripts/"); - load_scripts("data/ui_scripts/"); + for (const auto& path : filesystem::get_search_paths()) + { + load_scripts(path + "/ui_scripts/"); + if (game::environment::is_sp()) + { + load_scripts(path + "/ui_scripts/sp/"); + } + else + { + load_scripts(path + "/ui_scripts/mp/"); + } + } + } void try_start() diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index 906889c0..32dd6865 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -59,10 +59,10 @@ namespace scripting script_function get_function_by_index(const unsigned index) { - static const auto function_table = SELECT_VALUE(0x14B1D1B90, 0xAC85070_b); + static const auto function_table = SELECT_VALUE(0x14B1D1B90, 0xAC83820_b); static const auto method_table = SELECT_VALUE(0x14B1D33A0, 0xAC85070_b); - if (index < 0x301) + if (index < 0x30A) { return reinterpret_cast(function_table)[index - 1]; } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 2a05431d..1ac0746c 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -74,7 +74,7 @@ namespace game float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x0, 0x183010}; WEAK symbol FS_ReadFile{0x0, 0x1EC690}; - WEAK symbol FS_FreeFile{0x0, 0x0}; + WEAK symbol FS_FreeFile{0x0, 0x59E2F0}; WEAK symbol FS_Startup{0x0, 0x0}; WEAK symbol FS_AddLocalizedGameDirectory{0x0, 0x1878F0}; @@ -204,8 +204,8 @@ namespace game WEAK symbol UI_SafeTranslateString{0x0, 0x4E8BC0}; - WEAK symbol longjmp{0x0, 0x0}; - WEAK symbol _setjmp{0x0, 0x0}; + WEAK symbol longjmp{0x0, 0x826710}; + WEAK symbol _setjmp{0x0, 0x8A3190}; /*************************************************************** * Variables