From 35cc0ca091b2444ce961948581c551be97dab694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Feb 2022 22:21:44 +0000 Subject: [PATCH 01/52] Bump deps/curl from `049f376` to `161cbc5` Bumps [deps/curl](https://github.com/curl/curl) from `049f376` to `161cbc5`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/049f3765c7016a3f7a92b7f88aae6405c49b84fb...161cbc502ee0bdbda052d6da17d24fa7835f83e7) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 049f3765..161cbc50 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 049f3765c7016a3f7a92b7f88aae6405c49b84fb +Subproject commit 161cbc502ee0bdbda052d6da17d24fa7835f83e7 From 5afa80b0853db04cca1040a5046929a33e152d00 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 18 Feb 2022 01:19:40 +0100 Subject: [PATCH 02/52] Small fix --- src/common/utils/http.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/common/utils/http.cpp b/src/common/utils/http.cpp index fca7d8f3..a558b13a 100644 --- a/src/common/utils/http.cpp +++ b/src/common/utils/http.cpp @@ -1,9 +1,14 @@ #include "http.hpp" +#include #include #include #pragma comment(lib, "ws2_32.lib") +#ifdef max +#undef max +#endif + namespace utils::http { namespace @@ -22,8 +27,8 @@ namespace utils::http try { const auto now = std::chrono::high_resolution_clock::now(); - const auto count = std::chrono::duration_cast< - std::chrono::milliseconds>(now - helper->start).count(); + const auto count = std::max(1, static_cast(std::chrono::duration_cast< + std::chrono::seconds>(now - helper->start).count())); const auto speed = dlnow / count; if (*helper->callback) From eb42628813aa44ba98eae42e346bc0d7a5249e48 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Fri, 18 Feb 2022 07:33:43 +0000 Subject: [PATCH 03/52] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ff4538a..092913b2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ **NOTE**: Cracked/Pirated versions of the game are NOT compatible with this mod, if you run such a version and have issues/crashes launching the client refer to [this issue](https://github.com/fedddddd/h2-mod/issues/111). -- **[Click here to get the latest release](https://ci.appveyor.com/api/projects/fedddddd/h2-mod/artifacts/build%2Fbin%2Fx64%2FRelease%2Fh2-mod.exe?branch=develop&job=Environment%3A%20APPVEYOR_BUILD_WORKER_IMAGE%3DVisual%20Studio%202019%2C%20PREMAKE_ACTION%3Dvs2019%2C%20CI%3D1%3B%20Configuration%3A%20Release)** +- **[Click here to get the latest release](https://ci.appveyor.com/api/projects/fedddddd/h2-mod/artifacts/build%2Fbin%2Fx64%2FRelease%2Fh2-mod.exe?branch=develop&job=Environment%3A%20APPVEYOR_BUILD_WORKER_IMAGE%3DVisual%20Studio%202022%2C%20PREMAKE_ACTION%3Dvs2022%2C%20CI%3D1%3B%20Configuration%3A%20Release)** - **You will need to drop this in your Call of Duty: Modern Warfare 2 Campaign Remastered installation folder. If you don't have Call of Duty: Modern Warfare 2 Campaign Remastered, get those game files first.** ## Compile from source From 112c0b1ca87cbf0a87e4e917476508be9874b908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Feb 2022 22:24:17 +0000 Subject: [PATCH 04/52] Bump deps/curl from `161cbc5` to `bbe7042` Bumps [deps/curl](https://github.com/curl/curl) from `161cbc5` to `bbe7042`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/161cbc502ee0bdbda052d6da17d24fa7835f83e7...bbe70421132bee3912a196d1db6af92e2bd12e21) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 161cbc50..bbe70421 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 161cbc502ee0bdbda052d6da17d24fa7835f83e7 +Subproject commit bbe70421132bee3912a196d1db6af92e2bd12e21 From 0a7d49933eed2cc8b1bc3d55780f56c868cb6caa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Feb 2022 22:24:26 +0000 Subject: [PATCH 05/52] Bump deps/protobuf from `2f7ee91` to `763d852` Bumps [deps/protobuf](https://github.com/google/protobuf) from `2f7ee91` to `763d852`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/2f7ee91e326d95915b63918f968244cfefbc022a...763d85293dba5b5f71ef393e70cc54279d75aae4) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 2f7ee91e..763d8529 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 2f7ee91e326d95915b63918f968244cfefbc022a +Subproject commit 763d85293dba5b5f71ef393e70cc54279d75aae4 From 4a047b9caf9f6de9da8cfbfbd40f6bfc5c4c30c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Feb 2022 22:19:36 +0000 Subject: [PATCH 06/52] Bump deps/asmjit from `28c4d8c` to `a4e1e88` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `28c4d8c` to `a4e1e88`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/28c4d8c528527141955006f09124ce672ddfbe3f...a4e1e88374142f4a842892f9c4bd0b0776fdcd0a) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 28c4d8c5..a4e1e883 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 28c4d8c528527141955006f09124ce672ddfbe3f +Subproject commit a4e1e88374142f4a842892f9c4bd0b0776fdcd0a From 6ca3cfa54b00b6a8aaf2c64208c088944e38f1e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Feb 2022 22:19:40 +0000 Subject: [PATCH 07/52] Bump deps/curl from `bbe7042` to `999c217` Bumps [deps/curl](https://github.com/curl/curl) from `bbe7042` to `999c217`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/bbe70421132bee3912a196d1db6af92e2bd12e21...999c2179a114f531ed09cc16fc8c852dc8ad5b50) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index bbe70421..999c2179 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit bbe70421132bee3912a196d1db6af92e2bd12e21 +Subproject commit 999c2179a114f531ed09cc16fc8c852dc8ad5b50 From 7b328e801b33418b50acfb0ea64ea6fdba1122a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Feb 2022 22:19:46 +0000 Subject: [PATCH 08/52] Bump deps/protobuf from `763d852` to `2f91da5` Bumps [deps/protobuf](https://github.com/google/protobuf) from `763d852` to `2f91da5`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/763d85293dba5b5f71ef393e70cc54279d75aae4...2f91da585e96a7efe43505f714f03c7716a94ecb) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 763d8529..2f91da58 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 763d85293dba5b5f71ef393e70cc54279d75aae4 +Subproject commit 2f91da585e96a7efe43505f714f03c7716a94ecb From 2558840ede25ae3bc10c180f522d967e306aa8a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Feb 2022 22:19:45 +0000 Subject: [PATCH 09/52] Bump deps/lua from `5d708c3` to `8426d9b` Bumps [deps/lua](https://github.com/lua/lua) from `5d708c3` to `8426d9b`. - [Release notes](https://github.com/lua/lua/releases) - [Commits](https://github.com/lua/lua/compare/5d708c3f9cae12820e415d4f89c9eacbe2ab964b...8426d9b4d4df1da3c5b2d759e509ae1c50a86667) --- updated-dependencies: - dependency-name: deps/lua dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/lua b/deps/lua index 5d708c3f..8426d9b4 160000 --- a/deps/lua +++ b/deps/lua @@ -1 +1 @@ -Subproject commit 5d708c3f9cae12820e415d4f89c9eacbe2ab964b +Subproject commit 8426d9b4d4df1da3c5b2d759e509ae1c50a86667 From 2cca7eae6ae0d2d0e27fb0444cd9febd051e9aa5 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 23 Feb 2022 20:50:05 +0100 Subject: [PATCH 10/52] Fix converted functions --- src/client/component/ui_scripting.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index a810606c..f4122cf2 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -27,6 +27,7 @@ namespace ui_scripting utils::hook::detour hksi_lual_error_hook2; utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; + utils::hook::detour hks_allocator_hook; bool error_hook_enabled = false; @@ -66,6 +67,17 @@ namespace ui_scripting ui_scripting::lua::engine::stop(); hks_shutdown_hook.invoke(); } + + void* hks_allocator_stub(void* userData, void* oldMemory, unsigned __int64 oldSize, unsigned __int64 newSize) + { + const auto closure = reinterpret_cast(oldMemory); + if (converted_functions.find(closure) != converted_functions.end()) + { + converted_functions.erase(closure); + } + + return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); + } } int main_function_handler(game::hks::lua_State* state) @@ -137,11 +149,11 @@ namespace ui_scripting void post_unpack() override { scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui); - hks_start_hook.create(0x328BE0_b, hks_start_stub); hks_shutdown_hook.create(0x3203B0_b, hks_shutdown_stub); hksi_lual_error_hook.create(0x2E3E40_b, hksi_lual_error_stub); hksi_lual_error_hook2.create(0x2DCB40_b, hksi_lual_error_stub); + hks_allocator_hook.create(0x2D92A0_b, hks_allocator_stub); } }; } From 213ec956a188b319949b0271f390ef4a8733b3e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Feb 2022 22:16:22 +0000 Subject: [PATCH 11/52] Bump deps/asmjit from `a4e1e88` to `6efd4d5` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `a4e1e88` to `6efd4d5`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/a4e1e88374142f4a842892f9c4bd0b0776fdcd0a...6efd4d563dee6832224295fa3bbf1647964246c4) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index a4e1e883..6efd4d56 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit a4e1e88374142f4a842892f9c4bd0b0776fdcd0a +Subproject commit 6efd4d563dee6832224295fa3bbf1647964246c4 From b3cf8eebc79cad5c1253dd071cfa169b6aeb2558 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Feb 2022 22:16:29 +0000 Subject: [PATCH 12/52] Bump deps/protobuf from `2f91da5` to `e847034` Bumps [deps/protobuf](https://github.com/google/protobuf) from `2f91da5` to `e847034`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/2f91da585e96a7efe43505f714f03c7716a94ecb...e8470340e003b1e417cecf8eb9ed0cd41d496aef) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 2f91da58..e8470340 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 2f91da585e96a7efe43505f714f03c7716a94ecb +Subproject commit e8470340e003b1e417cecf8eb9ed0cd41d496aef From da4a57d23e005e82839cd5be3193039e5a2ea176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Feb 2022 22:16:32 +0000 Subject: [PATCH 13/52] Bump deps/curl from `999c217` to `6e9373b` Bumps [deps/curl](https://github.com/curl/curl) from `999c217` to `6e9373b`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/999c2179a114f531ed09cc16fc8c852dc8ad5b50...6e9373b5f4c9d945ec323a7357358ca51d4dfbf7) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 999c2179..6e9373b5 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 999c2179a114f531ed09cc16fc8c852dc8ad5b50 +Subproject commit 6e9373b5f4c9d945ec323a7357358ca51d4dfbf7 From faccb47c916e4aee5ec230cd47b9619e16467a1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 22:24:43 +0000 Subject: [PATCH 14/52] Bump deps/curl from `6e9373b` to `c07b95e` Bumps [deps/curl](https://github.com/curl/curl) from `6e9373b` to `c07b95e`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/6e9373b5f4c9d945ec323a7357358ca51d4dfbf7...c07b95e280cc2acf45586ae9f48db140ce68f5d8) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 6e9373b5..c07b95e2 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 6e9373b5f4c9d945ec323a7357358ca51d4dfbf7 +Subproject commit c07b95e280cc2acf45586ae9f48db140ce68f5d8 From 82a79009a3a265216c924b8b967eeeee5996bec8 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 3 Mar 2022 01:17:22 +0100 Subject: [PATCH 15/52] Small fix --- src/client/game/scripting/lua/context.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 0bee5fba..06b61680 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -48,16 +48,6 @@ namespace scripting::lua state["level"] = entity{*::game::levelEntityId}; state["player"] = call("getentbynum", {0}).as(); - state["io"]["fileexists"] = utils::io::file_exists; - state["io"]["writefile"] = utils::io::write_file; - state["io"]["filesize"] = utils::io::file_size; - state["io"]["createdirectory"] = utils::io::create_directory; - state["io"]["directoryexists"] = utils::io::directory_exists; - state["io"]["directoryisempty"] = utils::io::directory_is_empty; - state["io"]["listfiles"] = utils::io::list_files; - state["io"]["copyfolder"] = utils::io::copy_folder; - state["io"]["readfile"] = static_cast(utils::io::read_file); - auto vector_type = state.new_usertype("vector", sol::constructors()); vector_type["x"] = sol::property(&vector::get_x, &vector::set_x); vector_type["y"] = sol::property(&vector::get_y, &vector::set_y); @@ -198,8 +188,8 @@ namespace scripting::lua void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) { - state["level"] = entity{ *::game::levelEntityId }; - state["player"] = call("getentbynum", { 0 }).as(); + state["level"] = entity{*::game::levelEntityId}; + state["player"] = call("getentbynum", {0}).as(); auto entity_type = state.new_usertype("entity"); From ad8397ca506ece1d0f294e05b55ed7ae36b38bd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 22:14:44 +0000 Subject: [PATCH 16/52] Bump deps/protobuf from `e847034` to `0a246e2` Bumps [deps/protobuf](https://github.com/google/protobuf) from `e847034` to `0a246e2`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/e8470340e003b1e417cecf8eb9ed0cd41d496aef...0a246e23f8e9997e2f7e5887b2523e867c8653c5) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index e8470340..0a246e23 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit e8470340e003b1e417cecf8eb9ed0cd41d496aef +Subproject commit 0a246e23f8e9997e2f7e5887b2523e867c8653c5 From a6fb0757c805cf08dc3eb68026979dd5349204b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Mar 2022 22:23:25 +0000 Subject: [PATCH 17/52] Bump deps/protobuf from `0a246e2` to `5ad0697` Bumps [deps/protobuf](https://github.com/google/protobuf) from `0a246e2` to `5ad0697`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/0a246e23f8e9997e2f7e5887b2523e867c8653c5...5ad0697c868235f24559dc07f8a42870d160af76) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 0a246e23..5ad0697c 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 0a246e23f8e9997e2f7e5887b2523e867c8653c5 +Subproject commit 5ad0697c868235f24559dc07f8a42870d160af76 From b2330b1546d067d7397327ae01952c9b87952b37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Mar 2022 22:23:28 +0000 Subject: [PATCH 18/52] Bump deps/rapidjson from `e4bde97` to `8261c1d` Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `e4bde97` to `8261c1d`. - [Release notes](https://github.com/Tencent/rapidjson/releases) - [Commits](https://github.com/Tencent/rapidjson/compare/e4bde977440d4a00f820b6586899e48a972d2493...8261c1ddf43f10de00fd8c9a67811d1486b2c784) --- updated-dependencies: - dependency-name: deps/rapidjson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/rapidjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rapidjson b/deps/rapidjson index e4bde977..8261c1dd 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit e4bde977440d4a00f820b6586899e48a972d2493 +Subproject commit 8261c1ddf43f10de00fd8c9a67811d1486b2c784 From 62151a86ef3dfd1cd81b500db4a0321f481e867d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Mar 2022 22:23:32 +0000 Subject: [PATCH 19/52] Bump deps/curl from `c07b95e` to `2583c3d` Bumps [deps/curl](https://github.com/curl/curl) from `c07b95e` to `2583c3d`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/c07b95e280cc2acf45586ae9f48db140ce68f5d8...2583c3d1ce813db30954b6c7b36e8097066ad68b) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index c07b95e2..2583c3d1 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit c07b95e280cc2acf45586ae9f48db140ce68f5d8 +Subproject commit 2583c3d1ce813db30954b6c7b36e8097066ad68b From 725e0605e81b66f5b11e7931939676f8c6ea655c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 22:06:05 +0100 Subject: [PATCH 20/52] More LUI error handling --- src/client/component/ui_scripting.cpp | 35 +++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index f4122cf2..9c2214ac 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -28,6 +28,8 @@ namespace ui_scripting utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; utils::hook::detour hks_allocator_hook; + utils::hook::detour lui_error_hook; + utils::hook::detour hksi_hks_error_hook; bool error_hook_enabled = false; @@ -46,10 +48,37 @@ namespace ui_scripting { return hksi_lual_error_hook.invoke(s, formatted.data()); } - else + + throw std::runtime_error(formatted); + } + + void hksi_hks_error_stub(game::hks::lua_State* s, int a2) + { + if (!error_hook_enabled) { - throw std::runtime_error(formatted); + return hksi_hks_error_hook.invoke(s, a2); } + + throw std::runtime_error("unknown error"); + } + + void lui_error_stub(game::hks::lua_State* s) + { + if (!error_hook_enabled) + { + return lui_error_hook.invoke(s); + } + + const auto count = static_cast(s->m_apistack.top - s->m_apistack.base); + const auto arguments = get_return_values(count); + + std::string error_str = "LUI Error"; + if (count && arguments[0].is()) + { + error_str = arguments[0].as(); + } + + throw std::runtime_error(error_str); } void* hks_start_stub(char a1) @@ -154,6 +183,8 @@ namespace ui_scripting hksi_lual_error_hook.create(0x2E3E40_b, hksi_lual_error_stub); hksi_lual_error_hook2.create(0x2DCB40_b, hksi_lual_error_stub); hks_allocator_hook.create(0x2D92A0_b, hks_allocator_stub); + lui_error_hook.create(0x2B9D90_b, lui_error_stub); + hksi_hks_error_hook.create(0x2DBC00_b, hksi_hks_error_stub); } }; } From a70fd7bd8035e02410eb9431682a84c2d5a63074 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 19:35:38 +0100 Subject: [PATCH 21/52] Small fix --- src/client/component/command.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index b5350491..0240cc7e 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -333,8 +333,7 @@ namespace command } else if (arg == "health"s) { - - if (params.size() > 3) + if (params.size() > 2) { const auto amount = atoi(params.get(2)); const auto health = player.get("health").as(); From 14930ad3fd78c0352b79dcd0469e3fc08e466e85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:19:13 +0000 Subject: [PATCH 22/52] Bump deps/libtommath from `04e9d1e` to `66de864` Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `04e9d1e` to `66de864`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/04e9d1e7a0493910b2eb5e757d623870692ada04...66de86426e9cdb88526974c765108f01554af2b0) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index 04e9d1e7..66de8642 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 04e9d1e7a0493910b2eb5e757d623870692ada04 +Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 From be3d0a935a828bd6bba4d300ceb4ba4b6876c29e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 22:19:32 +0000 Subject: [PATCH 23/52] Bump deps/asmjit from `6efd4d5` to `f1a399c` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `6efd4d5` to `f1a399c`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/6efd4d563dee6832224295fa3bbf1647964246c4...f1a399c4fe74d1535a4190a2b8727c51045cc914) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 6efd4d56..f1a399c4 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 6efd4d563dee6832224295fa3bbf1647964246c4 +Subproject commit f1a399c4fe74d1535a4190a2b8727c51045cc914 From 5fc0bf3447f8df94b9a53a70658a8078ef0077c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Mar 2022 22:23:48 +0000 Subject: [PATCH 24/52] Bump deps/libtomcrypt from `673f5ce` to `06a81ae` Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `673f5ce` to `06a81ae`. - [Release notes](https://github.com/libtom/libtomcrypt/releases) - [Commits](https://github.com/libtom/libtomcrypt/compare/673f5ce29015a9bba3c96792920a10601b5b0718...06a81aeb227424182125363f7554fad5146d6d2a) --- updated-dependencies: - dependency-name: deps/libtomcrypt dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 673f5ce2..06a81aeb 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 673f5ce29015a9bba3c96792920a10601b5b0718 +Subproject commit 06a81aeb227424182125363f7554fad5146d6d2a From 22b14523b7f2915f791d7ec9213285a5916dec5f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 18 Mar 2022 22:02:44 +0100 Subject: [PATCH 25/52] Use different loader method --- src/client/component/binding.cpp | 6 +- src/client/component/branding.cpp | 2 +- src/client/component/command.cpp | 11 +- src/client/component/exception.cpp | 1 - src/client/component/fastfiles.cpp | 2 +- src/client/component/fps.cpp | 2 +- src/client/component/gameplay.cpp | 10 +- src/client/component/gui.cpp | 6 +- src/client/component/images.cpp | 4 +- src/client/component/input.cpp | 6 +- src/client/component/localized_strings.cpp | 2 +- src/client/component/logger.cpp | 8 +- src/client/component/lui.cpp | 4 +- src/client/component/notifies.cpp | 10 +- src/client/component/patches.cpp | 22 +- src/client/component/renderer.cpp | 4 +- src/client/component/scheduler.cpp | 6 +- src/client/component/scripting.cpp | 14 +- src/client/component/ui_scripting.cpp | 14 +- src/client/game/game.cpp | 13 - src/client/game/game.hpp | 9 +- src/client/game/scripting/functions.cpp | 8 +- src/client/game/symbols.hpp | 260 +++++++++---------- src/client/game/ui_scripting/lua/context.cpp | 2 +- src/client/loader/loader.cpp | 5 +- src/client/loader/loader.hpp | 2 +- src/client/main.cpp | 10 +- src/client/std_include.cpp | 9 +- 28 files changed, 215 insertions(+), 237 deletions(-) diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp index 0eb88f30..e29c2871 100644 --- a/src/client/component/binding.cpp +++ b/src/client/component/binding.cpp @@ -118,13 +118,13 @@ namespace binding void post_unpack() override { // write all bindings to config file - key_write_bindings_to_buffer_hook.create(0x3D3840_b, key_write_bindings_to_buffer_stub); + key_write_bindings_to_buffer_hook.create(0x1403D3840, key_write_bindings_to_buffer_stub); // links a custom command to an index - utils::hook::jump(0x59AE30_b, key_get_binding_for_cmd_stub, true); + utils::hook::jump(0x14059AE30, key_get_binding_for_cmd_stub, true); // execute custom binds - cl_execute_key_hook.create(0x3CF1E0_b, &cl_execute_key_stub); + cl_execute_key_hook.create(0x1403CF1E0, &cl_execute_key_stub); } }; } diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 46f0ad7f..42204839 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -45,7 +45,7 @@ namespace branding localized_strings::override("MENU_SYSINFO_DONATION_LINK", "Donation Link:"); localized_strings::override("MENU_SYSINFO_DONATION_URL", "https://paypal.me/fedecek"); - utils::hook::jump(0x33D550_b, get_build_number_stub, true); + utils::hook::jump(0x14033D550, get_build_number_stub, true); } }; } diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 0240cc7e..d5737946 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -148,7 +148,7 @@ namespace command public: void post_unpack() override { - utils::hook::jump(0x5A74F0_b, dvar_command_stub, true); + utils::hook::jump(0x1405A74F0, dvar_command_stub, true); add("quit", game::Quit); @@ -156,7 +156,7 @@ namespace command { const auto map = params.get(1); - const auto exists = utils::hook::invoke(0x412B50_b, map, 0); + const auto exists = utils::hook::invoke(0x140412B50, map, 0); if (!exists) { @@ -165,7 +165,7 @@ namespace command } // SV_SpawnServer - utils::hook::invoke(0x6B3AA0_b, map, 0, 0, 0, 0); + utils::hook::invoke(0x1406B3AA0, map, 0, 0, 0, 0); }); add("say", [](const params& params) @@ -207,11 +207,6 @@ namespace command } }); - add("baseAddress", []() - { - printf("%p\n", (void*)game::base_address); - }); - add("commandDump", []() { printf("======== Start command dump =========\n"); diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index c4f0f1dd..91805379 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -158,7 +158,6 @@ namespace exception line("Timestamp: "s + get_timestamp()); line(utils::string::va("Exception: 0x%08X", exceptioninfo->ExceptionRecord->ExceptionCode)); line(utils::string::va("Address: 0x%llX", exceptioninfo->ExceptionRecord->ExceptionAddress)); - line(utils::string::va("Base: 0x%llX", game::base_address)); #pragma warning(push) #pragma warning(disable: 4996) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 3b71d881..f0426f56 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -51,7 +51,7 @@ namespace fastfiles public: void post_unpack() override { - db_try_load_x_file_internal_hook.create(0x4173B0_b, &db_try_load_x_file_internal); + db_try_load_x_file_internal_hook.create(0x1404173B0, &db_try_load_x_file_internal); command::add("loadzone", [](const command::params& params) { diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index ff522f5d..e2761b29 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -303,7 +303,7 @@ namespace fps { scheduler::loop(draw, scheduler::pipeline::renderer); - sub_7C55D0_hook.create(0x7C55D0_b, perf_update); + sub_7C55D0_hook.create(0x1407C55D0, perf_update); cg_drawSpeed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED); cg_drawFps = dvars::register_int("cg_drawFPS", 0, 0, 4, game::DVAR_FLAG_SAVED); diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index ce946769..d727335b 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -46,10 +46,10 @@ namespace gameplay a.jnz(allsolid); a.bind(stand); - a.jmp(0x6878CD_b); + a.jmp(0x1406878CD); a.bind(allsolid); - a.jmp(0x6878D4_b); + a.jmp(0x1406878D4); } void pm_crashland_stub(void* ps, void* pm) @@ -70,12 +70,12 @@ namespace gameplay dvars::jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED); // Influence PM_JitterPoint code flow so the trace->startsolid checks are 'ignored' - pm_player_trace_hook.create(0x068F0A0_b, &pm_player_trace_stub); + pm_player_trace_hook.create(0x14068F0A0, &pm_player_trace_stub); // If g_enableElevators is 1 the 'ducked' flag will always be removed from the player state - utils::hook::jump(0x6878C1_b, utils::hook::assemble(pm_trace_stub), true); + utils::hook::jump(0x1406878C1, utils::hook::assemble(pm_trace_stub), true); - pm_crashland_hook.create(0x688A20_b, pm_crashland_stub); + pm_crashland_hook.create(0x140688A20, pm_crashland_stub); dvars::register_float("jump_height", 39, 0, 1000, game::DVAR_FLAG_REPLICATED); dvars::register_float("g_gravity", 800, 1, 1000, game::DVAR_FLAG_REPLICATED); diff --git a/src/client/component/gui.cpp b/src/client/component/gui.cpp index 34e0af53..d4852c7c 100644 --- a/src/client/component/gui.cpp +++ b/src/client/component/gui.cpp @@ -208,7 +208,7 @@ namespace gui a.call_aligned(rbx); a.mov(ecx, eax); - a.jmp(0x7A14D1_b); + a.jmp(0x1407A14D1); } utils::hook::detour wnd_proc_hook; @@ -301,8 +301,8 @@ namespace gui void post_unpack() override { - utils::hook::jump(0x7A14C4_b, utils::hook::assemble(dxgi_swap_chain_present_stub), true); - wnd_proc_hook.create(0x650F10_b, wnd_proc_stub); + utils::hook::jump(0x1407A14C4, utils::hook::assemble(dxgi_swap_chain_present_stub), true); + wnd_proc_hook.create(0x140650F10, wnd_proc_stub); on_frame([]() { diff --git a/src/client/component/images.cpp b/src/client/component/images.cpp index 693f208d..e3bfbd61 100644 --- a/src/client/component/images.cpp +++ b/src/client/component/images.cpp @@ -111,8 +111,8 @@ namespace images public: void post_unpack() override { - setup_texture_hook.create(0x74A390_b, setup_texture_stub); - load_texture_hook.create(0x2A7940_b, load_texture_stub); + setup_texture_hook.create(0x14074A390, setup_texture_stub); + load_texture_hook.create(0x1402A7940, load_texture_stub); } }; } diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 198ea92a..a890cf43 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -74,9 +74,9 @@ namespace input public: void post_unpack() override { - cl_char_event_hook.create(0x3D27B0_b, cl_char_event_stub); - cl_key_event_hook.create(0x3D2AE0_b, cl_key_event_stub); - cl_mouse_move_hook.create(0x3296F0_b, cl_mouse_move_stub); + cl_char_event_hook.create(0x1403D27B0, cl_char_event_stub); + cl_key_event_hook.create(0x1403D2AE0, cl_key_event_stub); + cl_mouse_move_hook.create(0x1403296F0, cl_mouse_move_stub); } }; } diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index f09fe247..b968d498 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -46,7 +46,7 @@ namespace localized_strings void post_unpack() override { // Change some localized strings - seh_string_ed_get_string_hook.create(0x5E5FD0_b, &seh_string_ed_get_string); + seh_string_ed_get_string_hook.create(0x1405E5FD0, &seh_string_ed_get_string); } }; } diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp index 9d7b4b50..554ce013 100644 --- a/src/client/component/logger.cpp +++ b/src/client/component/logger.cpp @@ -142,10 +142,10 @@ namespace logger public: void post_unpack() override { - utils::hook::jump(0x32C620_b, print_warning, true); - utils::hook::jump(0x32C630_b, print_warning, true); - utils::hook::jump(0x32AEF0_b, lui_print, true); - com_error_hook.create(0x5A2D80_b, com_error_stub); + utils::hook::jump(0x14032C620, print_warning, true); + utils::hook::jump(0x14032C630, print_warning, true); + utils::hook::jump(0x14032AEF0, lui_print, true); + com_error_hook.create(0x1405A2D80, com_error_stub); } }; } diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp index 87ee13b4..a1d9988d 100644 --- a/src/client/component/lui.cpp +++ b/src/client/component/lui.cpp @@ -39,8 +39,8 @@ namespace lui command::add("lui_restart", []() { - utils::hook::invoke(0x3203B0_b); - utils::hook::invoke(0x32D370_b); + utils::hook::invoke(0x1403203B0); + utils::hook::invoke(0x14032D370); }); } }; diff --git a/src/client/component/notifies.cpp b/src/client/component/notifies.cpp index 1419fa67..4d8b6fa9 100644 --- a/src/client/component/notifies.cpp +++ b/src/client/component/notifies.cpp @@ -94,7 +94,7 @@ namespace notifies a.inc(r14); a.mov(dword_ptr(rbp, 0xA4), r15d); - a.jmp(0x5C90B3_b); + a.jmp(0x1405C90B3); a.bind(replace); @@ -137,7 +137,7 @@ namespace notifies std::string convert_mod(const int meansOfDeath) { - const auto value = reinterpret_cast(0xBF49B0_b)[meansOfDeath]; + const auto value = reinterpret_cast(0x140BF49B0)[meansOfDeath]; const auto string = game::SL_ConvertToString(*value); return string; @@ -147,7 +147,7 @@ namespace notifies int damage, int dflags, const unsigned int hitLoc, const unsigned int weapon, bool isAlternate, unsigned int a11, const int meansOfDeath, unsigned int a13, unsigned int a14) { { - const std::string _hitLoc = reinterpret_cast(0xBF4AA0_b)[hitLoc]; + const std::string _hitLoc = reinterpret_cast(0x140BF4AA0)[hitLoc]; const auto _mod = convert_mod(meansOfDeath); const auto _weapon = get_weapon_name(weapon, isAlternate); @@ -199,9 +199,9 @@ namespace notifies public: void post_unpack() override { - utils::hook::jump(0x5C90A5_b, utils::hook::assemble(vm_execute_stub), true); + utils::hook::jump(0x1405C90A5, utils::hook::assemble(vm_execute_stub), true); - scr_entity_damage_hook.create(0x4BD2E0_b, scr_entity_damage_stub); + scr_entity_damage_hook.create(0x1404BD2E0, scr_entity_damage_stub); } }; } diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 8465f83d..c569b84a 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -16,7 +16,7 @@ namespace patches void* sub_46148() { - static uint64_t off_11C52460 = 0xAD0C58_b; + static uint64_t off_11C52460 = 0x140AD0C58; return &off_11C52460; } @@ -28,7 +28,7 @@ namespace patches void gscr_set_save_dvar_stub() { - const auto string = utils::string::to_lower(utils::hook::invoke(0x5C7C20_b, 0)); + const auto string = utils::string::to_lower(utils::hook::invoke(0x1405C7C20, 0)); if (string == "cg_fov" || string == "cg_fovscale") { return; @@ -65,24 +65,24 @@ namespace patches void post_unpack() override { // Fix startup crashes - utils::hook::set(0x633080_b, 0xC301B0); - utils::hook::set(0x272F70_b, 0xC301B0); - utils::hook::jump(0x46148_b, sub_46148, true); + utils::hook::set(0x140633080, 0xC301B0); + utils::hook::set(0x140272F70, 0xC301B0); + utils::hook::jump(0x140046148, sub_46148, true); - utils::hook::jump(0x64EF10_b, quit_stub, true); + utils::hook::jump(0x14064EF10, quit_stub, true); // Unlock fps in main menu - utils::hook::set(0x3D8E1B_b, 0xEB); + utils::hook::set(0x1403D8E1B, 0xEB); // Disable battle net popup - utils::hook::nop(0x5F4496_b, 5); + utils::hook::nop(0x1405F4496, 5); // Allow kbam input when gamepad is enabled - utils::hook::nop(0x3D2F8E_b, 2); - utils::hook::nop(0x3D0C9C_b, 6); + utils::hook::nop(0x1403D2F8E, 2); + utils::hook::nop(0x1403D0C9C, 6); // Prevent game from overriding cg_fov and cg_fovscale values - gscr_set_save_dvar_hook.create(0x504C60_b, &gscr_set_save_dvar_stub); + gscr_set_save_dvar_hook.create(0x140504C60, &gscr_set_save_dvar_stub); // Make cg_fov and cg_fovscale saved dvars diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index be9f7360..236f8a45 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -63,8 +63,8 @@ namespace renderer { dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED); - r_init_draw_method_hook.create(0x72F950_b, &r_init_draw_method_stub); - r_update_front_end_dvar_options_hook.create(0x76EE70_b, &r_update_front_end_dvar_options_stub); + r_init_draw_method_hook.create(0x14072F950, &r_init_draw_method_stub); + r_update_front_end_dvar_options_hook.create(0x14076EE70, &r_update_front_end_dvar_options_stub); } }; } diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index a266a693..ed0301b8 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -183,9 +183,9 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(0x76D7B0_b, scheduler::r_end_frame_stub); - g_run_frame_hook.create(0x4CB030_b, scheduler::server_frame_stub); - main_frame_hook.create(0x417FA0_b, scheduler::main_frame_stub); + r_end_frame_hook.create(0x14076D7B0, scheduler::r_end_frame_stub); + g_run_frame_hook.create(0x1404CB030, scheduler::server_frame_stub); + main_frame_hook.create(0x140417FA0, scheduler::main_frame_stub); } void pre_destroy() override diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index cf4167cd..b876c479 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -116,19 +116,19 @@ namespace scripting public: void post_unpack() override { - vm_notify_hook.create(0x5CC450_b, vm_notify_stub); + vm_notify_hook.create(0x1405CC450, vm_notify_stub); - g_shutdown_game_hook.create(0x4CBAD0_b, g_shutdown_game_stub); - player_spawn_hook.create(0x4B0710_b, player_spawn_stub); + g_shutdown_game_hook.create(0x1404CBAD0, g_shutdown_game_stub); + player_spawn_hook.create(0x1404B0710, player_spawn_stub); - scr_add_class_field_hook.create(0x5C2C30_b, scr_add_class_field_stub); - scr_set_thread_position_hook.create(0x5BC7E0_b, scr_set_thread_position_stub); - process_script_hook.create(0x5C6160_b, process_script_stub); + scr_add_class_field_hook.create(0x1405C2C30, scr_add_class_field_stub); + scr_set_thread_position_hook.create(0x1405BC7E0, scr_set_thread_position_stub); + process_script_hook.create(0x1405C6160, process_script_stub); // Loading last checkpoint doesn't call spawn player again (player_spawn_hook) // Not sure what this function does but `a1` is != nullptr when loading // the last checkpoint so we need to start lua in this context - sub_6B2940_hook.create(0x6B2940_b, sub_6B2940_stub); + sub_6B2940_hook.create(0x1406B2940, sub_6B2940_stub); scheduler::loop([]() { diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 9c2214ac..f6cdba10 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -178,13 +178,13 @@ namespace ui_scripting void post_unpack() override { scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui); - hks_start_hook.create(0x328BE0_b, hks_start_stub); - hks_shutdown_hook.create(0x3203B0_b, hks_shutdown_stub); - hksi_lual_error_hook.create(0x2E3E40_b, hksi_lual_error_stub); - hksi_lual_error_hook2.create(0x2DCB40_b, hksi_lual_error_stub); - hks_allocator_hook.create(0x2D92A0_b, hks_allocator_stub); - lui_error_hook.create(0x2B9D90_b, lui_error_stub); - hksi_hks_error_hook.create(0x2DBC00_b, hksi_hks_error_stub); + hks_start_hook.create(0x140328BE0, hks_start_stub); + hks_shutdown_hook.create(0x1403203B0, hks_shutdown_stub); + hksi_lual_error_hook.create(0x1402E3E40, hksi_lual_error_stub); + hksi_lual_error_hook2.create(0x1402DCB40, hksi_lual_error_stub); + hks_allocator_hook.create(0x1402D92A0, hks_allocator_stub); + lui_error_hook.create(0x1402B9D90, lui_error_stub); + hksi_hks_error_hook.create(0x1402DBC00, hksi_hks_error_stub); } }; } diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 28261c72..e4c8dccd 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,14 +3,6 @@ namespace game { - uint64_t base_address; - - void load_base_address() - { - const auto module = GetModuleHandle(NULL); - base_address = uint64_t(module); - } - std::string mod_folder{}; namespace environment @@ -81,8 +73,3 @@ namespace game } } } - -uintptr_t operator"" _b(const uintptr_t ptr) -{ - return game::base_address + ptr; -} \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 601179ad..4da1c52d 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -5,9 +5,6 @@ namespace game { - extern uint64_t base_address; - void load_base_address(); - extern std::string mod_folder; namespace environment @@ -35,7 +32,7 @@ namespace game T* get() const { - return reinterpret_cast((uint64_t)address_ + base_address); + return reinterpret_cast(address_); } operator T* () const @@ -53,6 +50,4 @@ namespace game }; } -uintptr_t operator"" _b(const uintptr_t ptr); - -#include "symbols.hpp" \ No newline at end of file +#include "symbols.hpp" diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index c6977ad1..0a3da8b3 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -59,15 +59,15 @@ namespace scripting script_function get_function_by_index(const unsigned index) { - static const auto function_table = 0xB153F90; - static const auto method_table = 0xB155890; + static const auto function_table = 0x14B153F90; + static const auto method_table = 0x14B155890; if (index < 0x320) { - return reinterpret_cast(game::base_address + function_table)[index - 1]; + return reinterpret_cast(function_table)[index - 1]; } - return reinterpret_cast(game::base_address + method_table)[index - 0x8000]; + return reinterpret_cast(method_table)[index - 0x8000]; } } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index f9108c0a..6abaeafa 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -6,198 +6,198 @@ namespace game { // Functions - WEAK symbol AddRefToValue{0x5C0EB0}; - WEAK symbol AddRefToObject{0x5C0EA0}; - WEAK symbol AllocThread{0x5C1200}; - WEAK symbol AllocVariable{0x5C1260}; - WEAK symbol RemoveRefToValue{0x5C29B0}; - WEAK symbol RemoveRefToObject{0x5C28A0}; + WEAK symbol AddRefToValue{0x1405C0EB0}; + WEAK symbol AddRefToObject{0x1405C0EA0}; + WEAK symbol AllocThread{0x1405C1200}; + WEAK symbol AllocVariable{0x1405C1260}; + WEAK symbol RemoveRefToValue{0x1405C29B0}; + WEAK symbol RemoveRefToObject{0x1405C28A0}; WEAK symbol BG_GetWeaponNameComplete{0x6A0800}; + char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x1406A0800}; - WEAK symbol Cbuf_AddText{0x59A050}; + WEAK symbol Cbuf_AddText{0x14059A050}; - WEAK symbol CG_GameMessage{0x37F450}; - WEAK symbol CG_GameMessageBold{0x37F1B0}; + WEAK symbol CG_GameMessage{0x14037F450}; + WEAK symbol CG_GameMessageBold{0x14037F1B0}; WEAK symbol CG_GetWeaponDisplayName{0x3B9210}; + bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x1403B9210}; - WEAK symbol Cmd_AddCommandInternal{0x59A5F0}; - WEAK symbol Cmd_ExecuteSingleCommand{0x59ABA0}; + WEAK symbol Cmd_AddCommandInternal{0x14059A5F0}; + WEAK symbol Cmd_ExecuteSingleCommand{0x14059ABA0}; - WEAK symbol Com_Error{0x5A2D80}; - WEAK symbol Com_Quit_f{0x5A50D0}; - WEAK symbol Quit{0x5A52A0}; + WEAK symbol Com_Error{0x1405A2D80}; + WEAK symbol Com_Quit_f{0x1405A50D0}; + WEAK symbol Quit{0x1405A52A0}; WEAK symbol - DB_EnumXAssets_Internal{0x4129F0}; - WEAK symbol DB_GetXAssetName{0x3E4090}; - WEAK symbol DB_LoadXAssets{0x414FF0}; - WEAK symbol DB_FindXAssetHeader{0x412F60}; - WEAK symbol DB_GetRawFileLen{0x413D80}; - WEAK symbol DB_GetRawBuffer{0x413C40}; + DB_EnumXAssets_Internal{0x1404129F0}; + WEAK symbol DB_GetXAssetName{0x1403E4090}; + WEAK symbol DB_LoadXAssets{0x140414FF0}; + WEAK symbol DB_FindXAssetHeader{0x140412F60}; + WEAK symbol DB_GetRawFileLen{0x140413D80}; + WEAK symbol DB_GetRawBuffer{0x140413C40}; - WEAK symbol Dvar_FindVar{0x618F90}; - WEAK symbol Dvar_GetCombinedString{0x5A75D0}; - WEAK symbol Dvar_RegisterBool{0x617BB0}; - WEAK symbol Dvar_RegisterInt{0x618090}; + WEAK symbol Dvar_FindVar{0x140618F90}; + WEAK symbol Dvar_GetCombinedString{0x1405A75D0}; + WEAK symbol Dvar_RegisterBool{0x140617BB0}; + WEAK symbol Dvar_RegisterInt{0x140618090}; WEAK symbol - Dvar_RegisterFloat{0x617F80}; + Dvar_RegisterFloat{0x140617F80}; WEAK symbol - Dvar_RegisterString{0x618170}; + Dvar_RegisterString{0x140618170}; WEAK symbol Dvar_RegisterVec4{0x6185F0}; - WEAK symbol Dvar_DisplayableValue{0x618EA0}; - WEAK symbol Dvar_ValueToString{0x61B8F0}; - WEAK symbol Dvar_SetCommand{0x61A5C0}; - WEAK symbol Dvar_SetFromStringFromSource{0x61A910}; + unsigned int flags)> Dvar_RegisterVec4{0x1406185F0}; + WEAK symbol Dvar_DisplayableValue{0x140618EA0}; + WEAK symbol Dvar_ValueToString{0x14061B8F0}; + WEAK symbol Dvar_SetCommand{0x14061A5C0}; + WEAK symbol Dvar_SetFromStringFromSource{0x14061A910}; - WEAK symbol generateHashValue{0x343D20}; + WEAK symbol generateHashValue{0x140343D20}; - WEAK symbol CL_IsCgameInitialized{0x3CA0C0}; + WEAK symbol CL_IsCgameInitialized{0x1403CA0C0}; WEAK symbol CL_DrawTextPhysicalWithEffects{0x3D4990}; + int fxBirthTime, int fxLetterTime, int fxDecayStartTime, int fxDecayDuration, int a17)> CL_DrawTextPhysicalWithEffects{0x1403D4990}; - WEAK symbol FindVariable{0x5C1D50}; - WEAK symbol FindEntityId{0x5C1C50}; - WEAK symbol GetEntityFieldValue{0x5C6100}; - WEAK symbol GetVariable{0x5C2690}; - WEAK symbol GetNewVariable{0x5C22B0}; - WEAK symbol GetNewArrayVariable{0x5C2130}; - WEAK symbol SetNewVariableValue{0x5C5EA0}; - WEAK symbol RemoveVariableValue{0x5C2A50}; + WEAK symbol FindVariable{0x1405C1D50}; + WEAK symbol FindEntityId{0x1405C1C50}; + WEAK symbol GetEntityFieldValue{0x1405C6100}; + WEAK symbol GetVariable{0x1405C2690}; + WEAK symbol GetNewVariable{0x1405C22B0}; + WEAK symbol GetNewArrayVariable{0x1405C2130}; + WEAK symbol SetNewVariableValue{0x1405C5EA0}; + WEAK symbol RemoveVariableValue{0x1405C2A50}; - WEAK symbol G_GetWeaponForName{0x51B260}; + WEAK symbol G_GetWeaponForName{0x14051B260}; WEAK symbol - G_GivePlayerWeapon{0x51B660}; - WEAK symbol G_InitializeAmmo{0x4C4110}; - WEAK symbol G_SelectWeapon{0x51C0D0}; - WEAK symbol WorldPosToScreenPos{0x36F310}; + G_GivePlayerWeapon{0x14051B660}; + WEAK symbol G_InitializeAmmo{0x1404C4110}; + WEAK symbol G_SelectWeapon{0x14051C0D0}; + WEAK symbol WorldPosToScreenPos{0x14036F310}; - WEAK symbol I_CleanStr{0x620660}; + WEAK symbol I_CleanStr{0x140620660}; WEAK symbol Image_Setup{0x74B2A0}; + uint32_t imageFlags, DXGI_FORMAT imageFormat, int a8, const char* name, const void* initData)> Image_Setup{0x14074B2A0}; - WEAK symbol Key_KeynumToString{0x3D32D0}; + WEAK symbol Key_KeynumToString{0x1403D32D0}; - WEAK symbol LUI_OpenMenu{0x5F0EE0}; - WEAK symbol Menu_IsMenuOpenAndVisible{0x5EE1A0}; + WEAK symbol LUI_OpenMenu{0x1405F0EE0}; + WEAK symbol Menu_IsMenuOpenAndVisible{0x1405EE1A0}; - WEAK symbol Material_RegisterHandle{0x759BA0}; + WEAK symbol Material_RegisterHandle{0x140759BA0}; - WEAK symbol PathNode_WorldifyPosFromParent{0x525830}; + WEAK symbol PathNode_WorldifyPosFromParent{0x140525830}; - WEAK symbol Scr_AllocVector{0x5C3220}; - WEAK symbol Scr_ClearOutParams{0x5C6E50}; - WEAK symbol Scr_GetEntityIdRef{0x5C56C0}; - WEAK symbol Scr_GetEntityId{0x5C5610}; - WEAK symbol Scr_SetObjectField{0x512190}; - WEAK symbol Scr_NotifyId{0x5C8240}; - WEAK symbol Scr_GetSelf{0x5C57C0}; - WEAK symbol Scr_ErrorInternal{0x5C6EC0}; + WEAK symbol Scr_AllocVector{0x1405C3220}; + WEAK symbol Scr_ClearOutParams{0x1405C6E50}; + WEAK symbol Scr_GetEntityIdRef{0x1405C56C0}; + WEAK symbol Scr_GetEntityId{0x1405C5610}; + WEAK symbol Scr_SetObjectField{0x140512190}; + WEAK symbol Scr_NotifyId{0x1405C8240}; + WEAK symbol Scr_GetSelf{0x1405C57C0}; + WEAK symbol Scr_ErrorInternal{0x1405C6EC0}; - WEAK symbol VM_Execute{0x5C8DB0}; + WEAK symbol VM_Execute{0x1405C8DB0}; WEAK symbol R_AddCmdDrawStretchPic{0x3C9710}; + float* color, Material* material)> R_AddCmdDrawStretchPic{0x1403C9710}; WEAK symbol R_AddCmdDrawStretchPicRotateXY{0x3C99B0}; + float angle, float* color, Material* material)> R_AddCmdDrawStretchPicRotateXY{0x1403C99B0}; WEAK symbol R_AddCmdDrawText{0x76C660}; + float rotation, float* color, int style)> R_AddCmdDrawText{0x14076C660}; WEAK symbol R_AddCmdDrawText2{0x76C860}; - WEAK symbol R_DrawRectangle{0x76A280}; + float rotation, float* color1, float* color2, int style)> R_AddCmdDrawText2{0x14076C860}; + WEAK symbol R_DrawRectangle{0x14076A280}; WEAK symbol R_AddCmdDrawTextWithCursor{0x76CAF0}; + const float* color, int style, int cursorPos, char cursor)> R_AddCmdDrawTextWithCursor{0x14076CAF0}; WEAK symbol R_AddCmdDrawTextGradient{0x76C570}; - WEAK symbol R_RegisterFont{0x746FE0}; - WEAK symbol R_TextWidth{0x7472A0}; - WEAK symbol R_SyncRenderThread{0x76E7D0}; + int a8, float* color1, unsigned int style, rgba color2)> R_AddCmdDrawTextGradient{0x14076C570}; + WEAK symbol R_RegisterFont{0x140746FE0}; + WEAK symbol R_TextWidth{0x1407472A0}; + WEAK symbol R_SyncRenderThread{0x14076E7D0}; WEAK symbol R_AddDObjToScene{0x775C40}; + float materialTime, __int64 a7, __int64 a8)> R_AddDObjToScene{0x140775C40}; - WEAK symbol ScrPlace_GetViewPlacement{0x3E16A0}; - WEAK symbol ScrPlace_GetView{0x3E1660}; + WEAK symbol ScrPlace_GetViewPlacement{0x1403E16A0}; + WEAK symbol ScrPlace_GetView{0x1403E1660}; - WEAK symbol SL_ConvertToString{0x5BFBB0}; - WEAK symbol SL_GetString{0x5C0170}; + WEAK symbol SL_ConvertToString{0x1405BFBB0}; + WEAK symbol SL_GetString{0x1405C0170}; - WEAK symbol SV_Loaded{0x6B3860}; + WEAK symbol SV_Loaded{0x1406B3860}; - WEAK symbol Sys_ShowConsole{0x633080}; - WEAK symbol Sys_IsDatabaseReady2{0x5A9FE0}; - WEAK symbol Sys_Milliseconds{0x650720}; - WEAK symbol Sys_IsMainThread{0x5AA020}; + WEAK symbol Sys_ShowConsole{0x140633080}; + WEAK symbol Sys_IsDatabaseReady2{0x1405A9FE0}; + WEAK symbol Sys_Milliseconds{0x140650720}; + WEAK symbol Sys_IsMainThread{0x1405AA020}; - WEAK symbol UI_SafeTranslateString{0x5A2930}; - WEAK symbol UI_PlayLocalSoundAlias{0x606080}; + WEAK symbol UI_SafeTranslateString{0x1405A2930}; + WEAK symbol UI_PlayLocalSoundAlias{0x140606080}; WEAK symbol PM_playerTrace{0x68F0A0}; + const Bounds*, int, int)> PM_playerTrace{0x14068F0A0}; WEAK symbol PM_trace{0x68F1D0}; + const Bounds*, int, int)> PM_trace{0x14068F1D0}; - WEAK symbol longjmp{0x89EED0}; - WEAK symbol _setjmp{0x8EC2E0}; + WEAK symbol longjmp{0x14089EED0}; + WEAK symbol _setjmp{0x1408EC2E0}; // Variables - WEAK symbol cmd_functions{0xAD17BB8}; - WEAK symbol cmd_args{0xAD17A60}; - WEAK symbol command_whitelist{0xBF84E0}; + WEAK symbol cmd_functions{0x14AD17BB8}; + WEAK symbol cmd_args{0x14AD17A60}; + WEAK symbol command_whitelist{0x140BF84E0}; - WEAK symbol hWnd{0xCCF81C0}; + WEAK symbol hWnd{0x14CCF81C0}; - WEAK symbol g_assetNames{0xBEF280}; - WEAK symbol g_poolSize{0xBF2E40}; + WEAK symbol g_assetNames{0x140BEF280}; + WEAK symbol g_poolSize{0x140BF2E40}; - WEAK symbol g_entities{0x52DDDA0}; - WEAK symbol num_entities{0x55CC738}; - WEAK symbol pathData{0x52CCDA0}; - WEAK symbol vehicle_pathnode_count{0xD009A30}; + WEAK symbol g_entities{0x1452DDDA0}; + WEAK symbol num_entities{0x1455CC738}; + WEAK symbol pathData{0x1452CCDA0}; + WEAK symbol vehicle_pathnode_count{0x14D009A30}; - WEAK symbol threadIds{0xB11DC80}; + WEAK symbol threadIds{0x14B11DC80}; - WEAK symbol gfxDrawMethod{0xEDF9E00}; - WEAK symbol refdef{0x1BC2500}; + WEAK symbol gfxDrawMethod{0x14EDF9E00}; + WEAK symbol refdef{0x141BC2500}; - WEAK symbol keyCatchers{0x203F3C0}; + WEAK symbol keyCatchers{0x14203F3C0}; - WEAK symbol playerKeys{0x1E8767C}; + WEAK symbol playerKeys{0x141E8767C}; - WEAK symbol dvarCount{0xBFBB310}; - WEAK symbol dvarPool{0xBFBB320}; + WEAK symbol dvarCount{0x14BFBB310}; + WEAK symbol dvarPool{0x14BFBB320}; - WEAK symbol levelEntityId{0xB5E0B30}; - WEAK symbol g_script_error_level{0xBA9CC24}; - WEAK symbol g_script_error{0xBA9CD40}; - WEAK symbol g_classMap{0xBF95C0}; + WEAK symbol levelEntityId{0x14B5E0B30}; + WEAK symbol g_script_error_level{0x14BA9CC24}; + WEAK symbol g_script_error{0x14BA9CD40}; + WEAK symbol g_classMap{0x140BF95C0}; - WEAK symbol scr_VarGlob{0xB617C00}; - WEAK symbol scr_VmPub{0xBA9EE40}; - WEAK symbol scr_function_stack{0xBAA93C0}; + WEAK symbol scr_VarGlob{0x14B617C00}; + WEAK symbol scr_VmPub{0x14BA9EE40}; + WEAK symbol scr_function_stack{0x14BAA93C0}; namespace hks { - WEAK symbol lua_state{0x19D83E8}; - WEAK symbol hksi_lua_pushlstring{0x287410}; - WEAK symbol hks_obj_tolstring{0x287410}; - WEAK symbol hks_obj_getmetatable{0x2DA210}; - WEAK symbol hks_obj_getfield{0x2D9E20}; - WEAK symbol hks_obj_settable{0x2DB040}; - WEAK symbol hks_obj_gettable{0x2DA300}; - WEAK symbol vm_call_internal{0x30AB60}; - WEAK symbol hksi_lua_pushvalue{0x2DE040}; - WEAK symbol Hashtable_Create{0x2C8290}; - WEAK symbol Hashtable_getNextHash{0x2D5150}; - WEAK symbol hks_obj_next{0x2DA850}; + WEAK symbol lua_state{0x1419D83E8}; + WEAK symbol hksi_lua_pushlstring{0x140287410}; + WEAK symbol hks_obj_tolstring{0x140287410}; + WEAK symbol hks_obj_getmetatable{0x1402DA210}; + WEAK symbol hks_obj_getfield{0x1402D9E20}; + WEAK symbol hks_obj_settable{0x1402DB040}; + WEAK symbol hks_obj_gettable{0x1402DA300}; + WEAK symbol vm_call_internal{0x14030AB60}; + WEAK symbol hksi_lua_pushvalue{0x1402DE040}; + WEAK symbol Hashtable_Create{0x1402C8290}; + WEAK symbol Hashtable_getNextHash{0x1402D5150}; + WEAK symbol hks_obj_next{0x1402DA850}; WEAK symbol cclosure_Create{0x2C84B0}; - WEAK symbol hksi_luaL_ref{0x2E4520}; - WEAK symbol hksi_luaL_unref{0x2DCE50}; + int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x1402C84B0}; + WEAK symbol hksi_luaL_ref{0x1402E4520}; + WEAK symbol hksi_luaL_unref{0x1402DCE50}; } } \ No newline at end of file diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 8c422965..1d7bdd9b 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -360,7 +360,7 @@ namespace ui_scripting::lua game_type["playmenuvideo"] = [](const game&, const std::string& video) { reinterpret_cast - (0x71B970_b)(video.data(), 64, 0); + (0x14071B970)(video.data(), 64, 0); }; game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value) diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index 4ec12c7c..cc3437c5 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe return FARPROC(library.get_ptr() + source.get_relative_entry_point()); } -FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const +FARPROC loader::load_library(const std::string& filename) const { const auto target = utils::nt::library::load(filename); if (!target) @@ -39,9 +39,6 @@ FARPROC loader::load_library(const std::string& filename, uint64_t* base_address throw std::runtime_error{"Failed to map binary!"}; } - const auto base = size_t(target.get_ptr()); - *base_address = base; - this->load_imports(target, target); this->load_tls(target, target); diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp index 0c0b5a12..2c5d86f9 100644 --- a/src/client/loader/loader.hpp +++ b/src/client/loader/loader.hpp @@ -5,7 +5,7 @@ class loader final { public: FARPROC load(const utils::nt::library& library, const std::string& buffer) const; - FARPROC load_library(const std::string& filename, uint64_t* base_address) const; + FARPROC load_library(const std::string& filename) const; void set_import_resolver(const std::function& resolver); diff --git a/src/client/main.cpp b/src/client/main.cpp index b24acb2a..41365a72 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -39,7 +39,7 @@ launcher::mode detect_mode_from_arguments() return launcher::mode::none; } -FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) +FARPROC load_binary(const launcher::mode mode) { loader loader; utils::nt::library self; @@ -87,7 +87,7 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) binary.data())); } - return loader.load_library(binary, base_address); + return loader.load(self, data); } void remove_crash_file() @@ -97,7 +97,7 @@ void remove_crash_file() void verify_version() { - const auto value = *reinterpret_cast(0x123456_b); + const auto value = *reinterpret_cast(0x140123456); if (value != 0xE465E151) { throw std::runtime_error("Unsupported Call of Duty: Modern Warfare 2 Campaign Remastered version"); @@ -184,14 +184,12 @@ int main() game::environment::set_mode(mode); - uint64_t base_address{}; - entry_point = load_binary(mode, &base_address); + entry_point = load_binary(mode); if (!entry_point) { throw std::runtime_error("Unable to load binary into memory"); } - game::base_address = base_address; verify_version(); if (!component_loader::post_load()) diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp index a5497531..e0a46eed 100644 --- a/src/client/std_include.cpp +++ b/src/client/std_include.cpp @@ -1,6 +1,13 @@ #include -#pragma comment(linker, "/base:0x7FFF00000000") +#pragma comment(linker, "/merge:.data=.cld") +#pragma comment(linker, "/merge:.rdata=.clr") +#pragma comment(linker, "/merge:.cl=.main") +#pragma comment(linker, "/merge:.text=.main") +#pragma comment(linker, "/stack:0x1000000") +#pragma comment(linker, "/base:0x140000000") +#pragma bss_seg(".payload") +char payload_data[BINARY_PAYLOAD_SIZE]; extern "C" { From 80015c3839f7b540afb4a10428ac311ef4d40bbb Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 18 Mar 2022 22:11:08 +0100 Subject: [PATCH 26/52] Fix event_handler --- src/client/game/scripting/lua/event_handler.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index 6c9286bb..b57b1250 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -33,15 +33,16 @@ namespace scripting::lua this->merge_callbacks(); this->handle_endon_conditions(event); - for (auto i = tasks.begin(); i != tasks.end();) + for (auto i = 0; i < tasks.size();) { - if (i->event != event.name || i->entity != event.entity) + const auto task = tasks[i]; + if (task.event != event.name || task.entity != event.entity) { ++i; continue; } - if (!i->is_deleted) + if (!task.is_deleted) { if (!has_built_arguments) { @@ -49,12 +50,12 @@ namespace scripting::lua arguments = this->build_arguments(event); } - handle_error(i->callback(sol::as_args(arguments))); + handle_error(task.callback(sol::as_args(arguments))); } - if (i->is_volatile || i->is_deleted) + if (task.is_volatile || task.is_deleted) { - i = tasks.erase(i); + tasks.erase(tasks.begin() + i); } else { @@ -94,8 +95,8 @@ namespace scripting::lua callbacks_.access([&](task_list& tasks) { - merger(tasks); - new_callbacks_.access(merger); + merger(tasks); + new_callbacks_.access(merger); }); } From d85be87f880fb7be56c521fd3fce3863124124b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 22:17:24 +0000 Subject: [PATCH 27/52] Bump deps/protobuf from `5ad0697` to `46c3651` Bumps [deps/protobuf](https://github.com/google/protobuf) from `5ad0697` to `46c3651`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/5ad0697c868235f24559dc07f8a42870d160af76...46c3651c315cf77f1bcf5ad662074f04f095a04a) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 5ad0697c..46c3651c 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 5ad0697c868235f24559dc07f8a42870d160af76 +Subproject commit 46c3651c315cf77f1bcf5ad662074f04f095a04a From 9fa920e8834ef86e7a5ed4b42fa881b209097a10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 22:17:28 +0000 Subject: [PATCH 28/52] Bump deps/curl from `2583c3d` to `c20a516` Bumps [deps/curl](https://github.com/curl/curl) from `2583c3d` to `c20a516`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/2583c3d1ce813db30954b6c7b36e8097066ad68b...c20a516d03165c4d047fd79edd109a07f8a3f543) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 2583c3d1..c20a516d 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 2583c3d1ce813db30954b6c7b36e8097066ad68b +Subproject commit c20a516d03165c4d047fd79edd109a07f8a3f543 From 964ceb5be9f730b9ef8aceafa293a02bfaf02067 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 19 Mar 2022 23:06:00 +0100 Subject: [PATCH 29/52] Custom font & material support --- src/client/component/filesystem.cpp | 56 ++++++ src/client/component/filesystem.hpp | 8 + src/client/component/fonts.cpp | 131 +++++++++++++ src/client/component/fonts.hpp | 7 + src/client/component/images.cpp | 7 +- src/client/component/materials.cpp | 200 ++++++++++++++++++++ src/client/component/materials.hpp | 7 + src/client/component/mods.cpp | 43 +++-- src/client/game/scripting/lua/engine.cpp | 9 +- src/client/game/structs.hpp | 88 +++++++++ src/client/game/symbols.hpp | 3 + src/client/game/ui_scripting/lua/engine.cpp | 9 +- 12 files changed, 542 insertions(+), 26 deletions(-) create mode 100644 src/client/component/filesystem.cpp create mode 100644 src/client/component/filesystem.hpp create mode 100644 src/client/component/fonts.cpp create mode 100644 src/client/component/fonts.hpp create mode 100644 src/client/component/materials.cpp create mode 100644 src/client/component/materials.hpp diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp new file mode 100644 index 00000000..cba191cc --- /dev/null +++ b/src/client/component/filesystem.cpp @@ -0,0 +1,56 @@ +#include +#include "loader/component_loader.hpp" + +#include "filesystem.hpp" + +#include + +namespace filesystem +{ + std::unordered_set& get_search_paths() + { + static std::unordered_set search_paths{}; + return search_paths; + } + + std::string read_file(const std::string& path) + { + for (const auto& search_path : get_search_paths()) + { + const auto path_ = search_path + "/" + path; + if (utils::io::file_exists(path_)) + { + return utils::io::read_file(path_); + } + } + + return {}; + } + + bool read_file(const std::string& path, std::string* data) + { + for (const auto& search_path : get_search_paths()) + { + const auto path_ = search_path + "/" + path; + if (utils::io::read_file(path_, data)) + { + return true; + } + } + + return false; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + get_search_paths().insert("."); + get_search_paths().insert("h2-mod"); + get_search_paths().insert("data"); + } + }; +} + +REGISTER_COMPONENT(filesystem::component) diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp new file mode 100644 index 00000000..718e5377 --- /dev/null +++ b/src/client/component/filesystem.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace filesystem +{ + std::unordered_set& get_search_paths(); + std::string read_file(const std::string& path); + bool read_file(const std::string& path, std::string* data); +} \ No newline at end of file diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp new file mode 100644 index 00000000..bdd16e53 --- /dev/null +++ b/src/client/component/fonts.cpp @@ -0,0 +1,131 @@ +#include +#include "loader/component_loader.hpp" + +#include "fonts.hpp" +#include "game_console.hpp" +#include "filesystem.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +namespace fonts +{ + namespace + { + struct font_data_t + { + std::unordered_map fonts; + std::unordered_map raw_fonts; + }; + + utils::concurrency::container font_data; + + game::TTF* create_font(const std::string& name, const std::string& data) + { + const auto font = utils::memory::get_allocator()->allocate(); + font->name = utils::memory::get_allocator()->duplicate_string(name); + font->buffer = utils::memory::get_allocator()->duplicate_string(data); + font->len = static_cast(data.size()); + font->fontFace = 0; + return font; + } + + void free_font(game::TTF* font) + { + utils::memory::get_allocator()->free(font->buffer); + utils::memory::get_allocator()->free(font->name); + utils::memory::get_allocator()->free(font); + } + + game::TTF* load_font(const std::string& name) + { + return font_data.access([&](font_data_t& data_) -> game::TTF* + { + if (const auto i = data_.fonts.find(name); i != data_.fonts.end()) + { + return i->second; + } + + std::string data{}; + if (const auto i = data_.raw_fonts.find(name); i != data_.raw_fonts.end()) + { + data = i->second; + } + + if (data.empty() && !filesystem::read_file(name, &data)) + { + return nullptr; + } + + const auto material = create_font(name, data); + data_.fonts[name] = material; + + return material; + }); + } + + game::TTF* try_load_font(const std::string& name) + { + try + { + return load_font(name); + } + catch (const std::exception& e) + { + game_console::print(game_console::con_type_error, "Failed to load font %s: %s\n", name.data(), e.what()); + } + + return nullptr; + } + + game::TTF* db_find_xasset_header_stub(game::XAssetType type, const char* name, int create_default) + { + auto result = try_load_font(name); + if (result == nullptr) + { + result = game::DB_FindXAssetHeader(type, name, create_default).ttf; + } + return result; + } + } + + void add(const std::string& name, const std::string& data) + { + font_data.access([&](font_data_t& data_) + { + data_.raw_fonts[name] = data; + }); + } + + void clear() + { + font_data.access([&](font_data_t& data_) + { + for (auto& font : data_.fonts) + { + free_font(font.second); + } + + data_.fonts.clear(); + utils::hook::set(0x14EE3ACB8, 0); // reset registered font count + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + utils::hook::call(0x140747096, db_find_xasset_header_stub); + } + }; +} + +REGISTER_COMPONENT(fonts::component) diff --git a/src/client/component/fonts.hpp b/src/client/component/fonts.hpp new file mode 100644 index 00000000..c2d22869 --- /dev/null +++ b/src/client/component/fonts.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace fonts +{ + void add(const std::string& name, const std::string& data); + void clear(); +} diff --git a/src/client/component/images.cpp b/src/client/component/images.cpp index e3bfbd61..ff7bcf8e 100644 --- a/src/client/component/images.cpp +++ b/src/client/component/images.cpp @@ -1,8 +1,11 @@ #include #include "loader/component_loader.hpp" -#include "game/game.hpp" + #include "images.hpp" #include "game_console.hpp" +#include "filesystem.hpp" + +#include "game/game.hpp" #include #include @@ -29,7 +32,7 @@ namespace images } }); - if (data.empty() && !utils::io::read_file(utils::string::va("images/%s.png", image->name), &data)) + if (data.empty() && !filesystem::read_file(utils::string::va("images/%s.png", image->name), &data)) { return {}; } diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp new file mode 100644 index 00000000..d84a6b93 --- /dev/null +++ b/src/client/component/materials.cpp @@ -0,0 +1,200 @@ +#include +#include "loader/component_loader.hpp" + +#include "materials.hpp" +#include "game_console.hpp" +#include "filesystem.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +namespace materials +{ + namespace + { + utils::hook::detour db_material_streaming_fail_hook; + utils::hook::detour material_register_handle_hook; + utils::hook::detour db_get_material_index_hook; + + struct material_data_t + { + std::unordered_map materials; + std::unordered_map images; + }; + + char constant_table[0x20] = {}; + + utils::concurrency::container material_data; + + game::GfxImage* setup_image(game::GfxImage* image, const utils::image& raw_image) + { + image->imageFormat = 0x1000003; + image->resourceSize = -1; + + D3D11_SUBRESOURCE_DATA data{}; + data.SysMemPitch = raw_image.get_width() * 4; + data.SysMemSlicePitch = data.SysMemPitch * raw_image.get_height(); + data.pSysMem = raw_image.get_buffer(); + + game::Image_Setup(image, raw_image.get_width(), raw_image.get_height(), image->depth, image->numElements, + image->imageFormat, DXGI_FORMAT_R8G8B8A8_UNORM, 0, image->name, &data); + + return image; + } + + game::Material* create_material(const std::string& name, const std::string& data) + { + const auto white = *reinterpret_cast(0x141B09208); + + const auto material = utils::memory::get_allocator()->allocate(); + const auto texture_table = utils::memory::get_allocator()->allocate(); + const auto image = utils::memory::get_allocator()->allocate(); + + std::memcpy(material, white, sizeof(game::Material)); + std::memcpy(texture_table, white->textureTable, sizeof(game::MaterialTextureDef)); + std::memcpy(image, white->textureTable->u.image, sizeof(game::GfxImage)); + + material->constantTable = &constant_table; + material->name = utils::memory::get_allocator()->duplicate_string(name); + image->name = material->name; + + material->textureTable = texture_table; + material->textureTable->u.image = setup_image(image, data); + + return material; + } + + void free_material(game::Material* material) + { + material->textureTable->u.image->textures.___u0.map->Release(); + material->textureTable->u.image->textures.shaderView->Release(); + utils::memory::get_allocator()->free(material->textureTable->u.image); + utils::memory::get_allocator()->free(material->textureTable); + utils::memory::get_allocator()->free(material->name); + utils::memory::get_allocator()->free(material); + } + + game::Material* load_material(const std::string& name) + { + return material_data.access([&](material_data_t& data_) -> game::Material* + { + if (const auto i = data_.materials.find(name); i != data_.materials.end()) + { + return i->second; + } + + std::string data{}; + if (const auto i = data_.images.find(name); i != data_.images.end()) + { + data = i->second; + } + + if (data.empty() && !filesystem::read_file(utils::string::va("materials/%s.png", name.data()), &data)) + { + data_.materials[name] = nullptr; + return nullptr; + } + + const auto material = create_material(name, data); + data_.materials[name] = material; + + return material; + }); + } + + game::Material* try_load_material(const std::string& name) + { + if (name == "white") + { + return nullptr; + } + + try + { + return load_material(name); + } + catch (const std::exception& e) + { + game_console::print(game_console::con_type_error, "Failed to load material %s: %s\n", name.data(), e.what()); + } + + return nullptr; + } + + game::Material* material_register_handle_stub(const char* name) + { + auto result = try_load_material(name); + if (result == nullptr) + { + result = material_register_handle_hook.invoke(name); + } + return result; + } + + int db_material_streaming_fail_stub(game::Material* material) + { + if (material->constantTable == &constant_table) + { + return 0; + } + + return db_material_streaming_fail_hook.invoke(material); + } + + unsigned int db_get_material_index_stub(game::Material* material) + { + if (material->constantTable == &constant_table) + { + return 0; + } + + return db_get_material_index_hook.invoke(material); + } + } + + void add(const std::string& name, const std::string& data) + { + material_data.access([&](material_data_t& data_) + { + data_.images[name] = data; + }); + } + + void clear() + { + material_data.access([&](material_data_t& data_) + { + for (auto& material : data_.materials) + { + if (material.second == nullptr) + { + continue; + } + + free_material(material.second); + } + + data_.materials.clear(); + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + material_register_handle_hook.create(game::Material_RegisterHandle.get(), material_register_handle_stub); + db_material_streaming_fail_hook.create(0x14041D140, db_material_streaming_fail_stub); + db_get_material_index_hook.create(0x140413BC0, db_get_material_index_stub); + } + }; +} + +REGISTER_COMPONENT(materials::component) diff --git a/src/client/component/materials.hpp b/src/client/component/materials.hpp new file mode 100644 index 00000000..3a548548 --- /dev/null +++ b/src/client/component/materials.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace materials +{ + void add(const std::string& name, const std::string& data); + void clear(); +} diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index 32b58052..ae78b9e7 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -6,12 +6,35 @@ #include "command.hpp" #include "game_console.hpp" #include "scheduler.hpp" +#include "filesystem.hpp" +#include "materials.hpp" +#include "fonts.hpp" #include #include namespace mods { + namespace + { + utils::hook::detour db_release_xassets_hook; + + void db_release_xassets_stub() + { + materials::clear(); + fonts::clear(); + db_release_xassets_hook.invoke(); + } + + void restart() + { + scheduler::once([]() + { + game::Com_Shutdown(""); + }, scheduler::pipeline::main); + } + } + class component final : public component_interface { public: @@ -22,6 +45,8 @@ namespace mods utils::io::create_directory("mods"); } + db_release_xassets_hook.create(0x140416A80, db_release_xassets_stub); + command::add("loadmod", [](const command::params& params) { if (params.size() < 2) @@ -30,7 +55,7 @@ namespace mods return; } - if (::game::SV_Loaded()) + if (!game::Com_InFrontend()) { game_console::print(game_console::con_type_error, "Cannot load mod while in-game!\n"); game::CG_GameMessage(0, "^1Cannot unload mod while in-game!"); @@ -46,12 +71,9 @@ namespace mods return; } + filesystem::get_search_paths().insert(path); game::mod_folder = path; - - scheduler::once([]() - { - command::execute("lui_restart", true); - }, scheduler::pipeline::renderer); + restart(); }); command::add("unloadmod", [](const command::params& params) @@ -62,7 +84,7 @@ namespace mods return; } - if (::game::SV_Loaded()) + if (!game::Com_InFrontend()) { game_console::print(game_console::con_type_error, "Cannot unload mod while in-game!\n"); game::CG_GameMessage(0, "^1Cannot unload mod while in-game!"); @@ -70,12 +92,9 @@ namespace mods } game_console::print(game_console::con_type_info, "Unloading mod %s\n", game::mod_folder.data()); + filesystem::get_search_paths().erase(game::mod_folder); game::mod_folder.clear(); - - scheduler::once([]() - { - command::execute("lui_restart", true); - }, scheduler::pipeline::renderer); + restart(); }); } }; diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp index 58008313..d9f0ae0e 100644 --- a/src/client/game/scripting/lua/engine.cpp +++ b/src/client/game/scripting/lua/engine.cpp @@ -3,6 +3,7 @@ #include "context.hpp" #include "../../../component/notifies.hpp" +#include "../../../component/filesystem.hpp" #include "../execution.hpp" #include @@ -49,13 +50,9 @@ namespace scripting::lua::engine load_generic_script(); - load_scripts("scripts/"); - load_scripts("h2-mod/scripts/"); - load_scripts("data/scripts/"); - - if (!game::mod_folder.empty()) + for (const auto& path : filesystem::get_search_paths()) { - load_scripts(utils::string::va("%s/scripts/", game::mod_folder.data())); + load_scripts(path + "/scripts/"); } } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 291203a8..8c3017c2 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -126,11 +126,90 @@ namespace game // ... }; + struct GfxImage; + + union MaterialTextureDefInfo + { + GfxImage* image; + void* water; + }; + + struct MaterialTextureDef + { + unsigned int nameHash; + char nameStart; + char nameEnd; + char samplerState; + char semantic; + MaterialTextureDefInfo u; + }; + + struct MaterialPass + { + void* vertexShader; + void* vertexDecl; + void* hullShader; + void* domainShader; + void* pixelShader; + char pixelOutputMask; + char perPrimArgCount; + char perObjArgCount; + char stableArgCount; + unsigned __int16 perPrimArgSize; + unsigned __int16 perObjArgSize; + unsigned __int16 stableArgSize; + char zone; + char perPrimConstantBuffer; + char perObjConstantBuffer; + char stableConstantBuffer; + unsigned int customBufferFlags; + char customSamplerFlags; + char precompiledIndex; + char stageConfig; + void* args; + }; + + struct MaterialTechnique + { + const char* name; + unsigned __int16 flags; + unsigned __int16 passCount; + MaterialPass passArray[1]; + }; + + struct MaterialTechniqueSet + { + const char* name; + unsigned __int16 flags; + char worldVertFormat; + char preDisplacementOnlyCount; + MaterialTechnique* techniques[309]; + }; + + struct GfxStateBits + { + unsigned int loadBits[3]; + char zone; + char depthStencilState[11]; + char blendState; + char rasterizerState; + }; + struct Material { const char* name; + char __pad0[0x124]; + char textureCount; + char __pad1[0xB]; + MaterialTechniqueSet* techniqueSet; + MaterialTextureDef* textureTable; + void* constantTable; + GfxStateBits* stateBitsTable; + char __pad2[0x118]; }; + static_assert(sizeof(Material) == 0x270); + struct point { float x; @@ -678,6 +757,14 @@ namespace game const char* buffer; }; + struct TTF + { + const char* name; + int len; + const char* buffer; + int fontFace; + }; + union XAssetHeader { void* data; @@ -687,6 +774,7 @@ namespace game ScriptFile* scriptfile; StringTable* stringTable; LuaFile* luaFile; + TTF* ttf; }; struct XAsset diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 6abaeafa..920ab7d2 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -27,7 +27,9 @@ namespace game WEAK symbol Cmd_ExecuteSingleCommand{0x14059ABA0}; WEAK symbol Com_Error{0x1405A2D80}; + WEAK symbol Com_Shutdown{0x1405A62C0}; WEAK symbol Com_Quit_f{0x1405A50D0}; + WEAK symbol Com_InFrontend{0x140328BD0}; WEAK symbol Quit{0x1405A52A0}; WEAK symbol @@ -117,6 +119,7 @@ namespace game WEAK symbol R_RegisterFont{0x140746FE0}; WEAK symbol R_TextWidth{0x1407472A0}; WEAK symbol R_SyncRenderThread{0x14076E7D0}; + WEAK symbol R_WaitWorkerCmds{0x140794330}; WEAK symbol R_AddDObjToScene{0x140775C40}; diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index b204a78b..34fde3d1 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -4,6 +4,7 @@ #include "../../../component/scheduler.hpp" #include "../../../component/ui_scripting.hpp" +#include "../../../component/filesystem.hpp" #include #include @@ -73,13 +74,9 @@ namespace ui_scripting::lua::engine load_code(updater_script); - load_scripts("ui_scripts/"); - load_scripts("h2-mod/ui_scripts/"); - load_scripts("data/ui_scripts/"); - - if (!game::mod_folder.empty()) + for (const auto& path : filesystem::get_search_paths()) { - load_scripts(utils::string::va("%s/ui_scripts/", game::mod_folder.data())); + load_scripts(path + "/ui_scripts/"); } } From ad042ec91d1f8bb819e2bfb491b1a30b411b649b Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 19 Mar 2022 23:38:50 +0100 Subject: [PATCH 30/52] Fix release build crash --- src/client/std_include.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp index e0a46eed..773e1c19 100644 --- a/src/client/std_include.cpp +++ b/src/client/std_include.cpp @@ -17,6 +17,12 @@ extern "C" extern "C" { + // workaround for release build removing 'payload_data' + char* dont_remove_this() + { + return payload_data; + } + int s_read_arc4random(void*, size_t) { return -1; From 0b50ac734d1190ec9016a353297773ac0768197a Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 00:13:14 +0100 Subject: [PATCH 31/52] New updater --- src/client/component/updater.cpp | 418 +++++++++++++++++++ src/client/component/updater.hpp | 26 ++ src/client/game/ui_scripting/lua/context.cpp | 153 ++----- src/client/game/ui_scripting/lua/engine.cpp | 6 +- src/client/resource.hpp | 22 +- src/client/resource.rc | 4 +- src/client/resources/json.lua | 388 ----------------- src/client/resources/ui_scripts/common.lua | 162 +++++++ src/client/resources/ui_scripts/updater.lua | 164 ++++++++ src/client/resources/updater.lua | 411 ------------------ 10 files changed, 810 insertions(+), 944 deletions(-) create mode 100644 src/client/component/updater.cpp create mode 100644 src/client/component/updater.hpp delete mode 100644 src/client/resources/json.lua create mode 100644 src/client/resources/ui_scripts/common.lua create mode 100644 src/client/resources/ui_scripts/updater.lua delete mode 100644 src/client/resources/updater.lua diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp new file mode 100644 index 00000000..9700d72f --- /dev/null +++ b/src/client/component/updater.cpp @@ -0,0 +1,418 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "updater.hpp" + +#include "version.h" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +#define MASTER "https://master.fed0001.xyz/" + +#define FILES_PATH "files.json" +#define FILES_PATH_DEV "files-dev.json" + +#define DATA_PATH "data/" +#define DATA_PATH_DEV "data-dev/" + +#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" +#define ERR_DOWNLOAD_FAIL "Failed to download file " +#define ERR_WRITE_FAIL "Failed to write file " + +namespace updater +{ + namespace + { + game::dvar_t* cl_auto_update; + bool has_tried_update = false; + + struct status + { + bool done; + bool success; + }; + + struct file_data + { + std::string name; + std::string data; + }; + + struct update_data_t + { + bool restart_required{}; + bool cancelled{}; + status check{}; + status download{}; + std::string error{}; + std::string current_file{}; + std::vector required_files{}; + }; + + utils::concurrency::container update_data; + + std::string select(const std::string& main, const std::string& develop) + { + if (GIT_BRANCH == "develop"s) + { + return develop; + } + + return main; + } + + std::string get_data_path() + { + if (GIT_BRANCH == "develop"s) + { + return DATA_PATH_DEV; + } + + return DATA_PATH; + } + + void set_update_check_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.check.done = done; + data_.check.success = success; + data_.error = error; + }); + } + + void set_update_download_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.download.done = done; + data_.download.success = success; + data_.error = error; + }); + } + + bool check_file(const std::string& name, const std::string& sha) + { + std::string data; + if (!utils::io::read_file(name, &data)) + { + return false; + } + + if (utils::cryptography::sha1::compute(data, true) != sha) + { + return false; + } + + return true; + } + + std::string load_binary_name() + { + utils::nt::library self; + return self.get_name(); + } + + std::string get_binary_name() + { + static const auto name = load_binary_name(); + return name; + } + + std::string get_time_str() + { + return utils::string::va("%i", uint32_t(time(nullptr))); + } + + std::optional download_file(const std::string& name) + { + return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); + } + + bool is_update_cancelled() + { + return update_data.access([](update_data_t& data_) + { + return data_.cancelled; + }); + } + + bool write_file(const std::string& name, const std::string& data) + { + if (get_binary_name() == name && + utils::io::file_exists(name) && + !utils::io::move_file(name, name + ".old")) + { + return false; + } + + return utils::io::write_file(name, data); + } + + void delete_old_file() + { + utils::io::remove_file(get_binary_name() + ".old"); + } + + void reset_data() + { + update_data.access([](update_data_t& data_) + { + data_ = {}; + }); + } + } + + void relaunch() + { + utils::nt::relaunch_self("-singleplayer"); + utils::nt::terminate(); + } + + void set_has_tried_update(bool tried) + { + has_tried_update = tried; + } + + bool get_has_tried_update() + { + return has_tried_update; + } + + bool auto_updates_enabled() + { + return cl_auto_update->current.enabled; + } + + bool is_update_check_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.done; + }); + } + + bool is_update_download_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.done; + }); + } + + bool get_update_check_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.success; + }); + } + + bool get_update_download_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.success; + }); + } + + bool is_update_available() + { + return update_data.access([](update_data_t& data_) + { + return data_.required_files.size() > 0; + }); + } + + bool is_restart_required() + { + return update_data.access([](update_data_t& data_) + { + return data_.restart_required; + }); + } + + std::string get_last_error() + { + return update_data.access([](update_data_t& data_) + { + return data_.error; + }); + } + + std::string get_current_file() + { + return update_data.access([](update_data_t& data_) + { + return data_.current_file; + }); + } + + void cancel_update() + { +#ifdef DEBUG + printf("[Updater] Cancelling update\n"); +#endif + + return update_data.access([](update_data_t& data_) + { + data_.cancelled = true; + }); + } + + void start_update_check() + { + cancel_update(); + reset_data(); + +#ifdef DEBUG + printf("[Updater] starting update check\n"); +#endif + + scheduler::once([]() + { + const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!files_data.has_value()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + rapidjson::Document j; + j.Parse(files_data.value().data()); + + if (!j.IsArray()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + std::vector required_files; + + const auto files = j.GetArray(); + for (const auto& file : files) + { + if (!file.IsArray() || file.Size() != 3 || !file[0].IsString() || !file[2].IsString()) + { + continue; + } + + const auto name = file[0].GetString(); + const auto sha = file[2].GetString(); + + if (!check_file(name, sha)) + { + if (get_binary_name() == name) + { + update_data.access([](update_data_t& data_) + { + data_.restart_required = true; + }); + } + +#ifdef DEBUG + printf("[Updater] need file %s\n", name); +#endif + + required_files.push_back(name); + } + } + + update_data.access([&required_files](update_data_t& data_) + { + data_.check.done = true; + data_.check.success = true; + data_.required_files = required_files; + }); + }, scheduler::pipeline::async); + } + + void start_update_download() + { +#ifdef DEBUG + printf("[Updater] starting update download\n"); +#endif + + if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) + { + return; + }// + + scheduler::once([]() + { + const auto required_files = update_data.access>([](update_data_t& data_) + { + return data_.required_files; + }); + + std::vector downloads; + + for (const auto& file : required_files) + { + update_data.access([file](update_data_t& data_) + { + data_.current_file = file; + }); + +#ifdef DEBUG + printf("[Updater] downloading file %s\n", file.data()); +#endif + + const auto data = download_file(file); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!data.has_value()) + { + set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); + return; + } + + downloads.push_back({file, data.value()}); + } + + for (const auto& download : downloads) + { + if (!write_file(download.name, download.data)) + { + set_update_download_status(true, false, ERR_WRITE_FAIL + download.name); + return; + } + } + + set_update_download_status(true, true); + }, scheduler::pipeline::async); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + delete_old_file(); + cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED); + } + }; +} + +REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp new file mode 100644 index 00000000..9a3dd45e --- /dev/null +++ b/src/client/component/updater.hpp @@ -0,0 +1,26 @@ +#pragma once + +namespace updater +{ + void relaunch(); + + void set_has_tried_update(bool tried); + bool get_has_tried_update(); + bool auto_updates_enabled(); + + bool is_update_available(); + bool is_update_check_done(); + bool get_update_check_status(); + + bool is_update_download_done(); + bool get_update_download_status(); + + bool is_restart_required(); + + std::string get_last_error(); + std::string get_current_file(); + + void start_update_check(); + void start_update_download(); + void cancel_update(); +} \ No newline at end of file diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 1d7bdd9b..a146787a 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -10,6 +10,8 @@ #include "../../../component/scripting.hpp" #include "../../../component/command.hpp" #include "../../../component/fastfiles.hpp" +#include "../../../component/updater.hpp" +#include "../../../component/localized_strings.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -25,8 +27,6 @@ namespace ui_scripting::lua { namespace { - const auto json_script = utils::nt::load_resource(LUA_JSON_SCRIPT); - scripting::script_value script_convert(const sol::lua_value& value) { if (value.is()) @@ -95,13 +95,6 @@ namespace ui_scripting::lua state["io"]["readfile"] = static_cast(utils::io::read_file); } - void setup_json(sol::state& state) - { - const auto json = state.safe_script(json_script, &sol::script_pass_on_error); - handle_error(json); - state["json"] = json; - } - void setup_vector_type(sol::state& state) { auto vector_type = state.new_usertype("vector", sol::constructors()); @@ -435,121 +428,10 @@ namespace ui_scripting::lua return ::game::mod_folder; }; - static int request_id{}; - game_type["httpget"] = [](const game&, const std::string& url) + game_type["addlocalizedstring"] = [](const game&, const std::string& string, + const std::string& value) { - const auto id = request_id++; - ::scheduler::once([url, id]() - { - const auto result = utils::http::get_data(url); - ::scheduler::once([result, id] - { - event event; - event.name = "http_request_done"; - - if (result.has_value()) - { - event.arguments = {id, true, result.value()}; - } - else - { - event.arguments = {id, false}; - } - - notify(event); - }, ::scheduler::pipeline::lui); - }, ::scheduler::pipeline::async); - return id; - }; - - game_type["httpgettofile"] = [](const game&, const std::string& url, - const std::string& dest) - { - const auto id = request_id++; - ::scheduler::once([url, id, dest]() - { - auto last_report = std::chrono::high_resolution_clock::now(); - const auto result = utils::http::get_data(url, {}, [&last_report, id](size_t progress, size_t total, size_t speed) - { - const auto now = std::chrono::high_resolution_clock::now(); - if (now - last_report < 100ms && progress < total) - { - return; - } - - last_report = now; - - ::scheduler::once([id, progress, total, speed] - { - event event; - event.name = "http_request_progress"; - event.arguments = { - id, - static_cast(progress), - static_cast(total), - static_cast(speed) - }; - - notify(event); - }, ::scheduler::pipeline::lui); - }); - - if (result.has_value()) - { - const auto write = utils::io::write_file(dest, result.value(), false); - ::scheduler::once([result, id, write]() - { - event event; - event.name = "http_request_done"; - event.arguments = {id, true, write}; - - notify(event); - }, ::scheduler::pipeline::lui); - } - else - { - ::scheduler::once([result, id]() - { - event event; - event.name = "http_request_done"; - event.arguments = {id, false}; - - notify(event); - }, ::scheduler::pipeline::lui); - } - }, ::scheduler::pipeline::async); - return id; - }; - - game_type["sha"] = [](const game&, const std::string& data) - { - return utils::string::to_upper(utils::cryptography::sha1::compute(data, true)); - }; - - game_type["environment"] = [](const game&) - { - return GIT_BRANCH; - }; - - game_type["binaryname"] = [](const game&) - { - utils::nt::library self; - return self.get_name(); - }; - - game_type["relaunch"] = [](const game&) - { - utils::nt::relaunch_self("-singleplayer"); - utils::nt::terminate(); - }; - - game_type["isdebugbuild"] = [](const game&) - { -#ifdef DEBUG - return true; -#else - return false; -#endif + localized_strings::override(string, value); }; struct player @@ -677,6 +559,30 @@ namespace ui_scripting::lua state["LUI"] = state["luiglobals"]["LUI"]; state["Engine"] = state["luiglobals"]["Engine"]; state["Game"] = state["luiglobals"]["Game"]; + + auto updater_table = sol::table::create(state.lua_state()); + + updater_table["relaunch"] = updater::relaunch; + + updater_table["sethastriedupdate"] = updater::set_has_tried_update; + updater_table["gethastriedupdate"] = updater::get_has_tried_update; + updater_table["autoupdatesenabled"] = updater::auto_updates_enabled; + + updater_table["startupdatecheck"] = updater::start_update_check; + updater_table["isupdatecheckdone"] = updater::is_update_check_done; + updater_table["getupdatecheckstatus"] = updater::get_update_check_status; + updater_table["isupdateavailable"] = updater::is_update_available; + + updater_table["startupdatedownload"] = updater::start_update_download; + updater_table["isupdatedownloaddone"] = updater::is_update_download_done; + updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; + updater_table["cancelupdate"] = updater::cancel_update; + updater_table["isrestartrequired"] = updater::is_restart_required; + + updater_table["getlasterror"] = updater::get_last_error; + updater_table["getcurrentfile"] = updater::get_current_file; + + state["updater"] = updater_table; } } @@ -694,7 +600,6 @@ namespace ui_scripting::lua sol::lib::table); setup_io(this->state_); - setup_json(this->state_); setup_vector_type(this->state_); setup_game_type(this->state_, this->event_handler_, this->scheduler_); setup_lui_types(this->state_, this->event_handler_, this->scheduler_); diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 34fde3d1..d1bd4245 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -14,7 +14,8 @@ namespace ui_scripting::lua::engine { namespace { - const auto updater_script = utils::nt::load_resource(LUI_UPDATER_MENU); + const auto lui_common = utils::nt::load_resource(LUI_COMMON); + const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); void handle_key_event(const int key, const int down) { @@ -72,7 +73,8 @@ namespace ui_scripting::lua::engine clear_converted_functions(); get_scripts().clear(); - load_code(updater_script); + load_code(lui_common); + // load_code(lui_updater); for (const auto& path : filesystem::get_search_paths()) { diff --git a/src/client/resource.hpp b/src/client/resource.hpp index a5a6b649..0a6f027a 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -2,23 +2,11 @@ #define ID_ICON 102 -#define IMAGE_SPLASH 300 -#define IMAGE_LOGO 301 +#define MENU_MAIN 300 -#define DW_ENTITLEMENT_CONFIG 302 -#define DW_SOCIAL_CONFIG 303 -#define DW_MM_CONFIG 304 -#define DW_LOOT_CONFIG 305 -#define DW_STORE_CONFIG 306 -#define DW_MOTD 307 -#define DW_FASTFILE 308 -#define DW_PLAYLISTS 309 +#define TLS_DLL 301 -#define MENU_MAIN 310 +#define ICON_IMAGE 302 -#define TLS_DLL 311 - -#define ICON_IMAGE 312 - -#define LUA_JSON_SCRIPT 313 -#define LUI_UPDATER_MENU 314 +#define LUI_COMMON 303 +#define LUI_UPDATER 304 diff --git a/src/client/resource.rc b/src/client/resource.rc index b42a1e0c..1b9843d6 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -97,8 +97,8 @@ ID_ICON ICON "resources/icon.ico" MENU_MAIN RCDATA "resources/main.html" -LUA_JSON_SCRIPT RCDATA "resources/json.lua" -LUI_UPDATER_MENU RCDATA "resources/updater.lua" +LUI_COMMON RCDATA "resources/ui_scripts/common.lua" +LUI_UPDATER RCDATA "resources/ui_scripts/updater.lua" #ifdef _DEBUG TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll" diff --git a/src/client/resources/json.lua b/src/client/resources/json.lua deleted file mode 100644 index 711ef786..00000000 --- a/src/client/resources/json.lua +++ /dev/null @@ -1,388 +0,0 @@ --- --- json.lua --- --- Copyright (c) 2020 rxi --- --- Permission is hereby granted, free of charge, to any person obtaining a copy of --- this software and associated documentation files (the "Software"), to deal in --- the Software without restriction, including without limitation the rights to --- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies --- of the Software, and to permit persons to whom the Software is furnished to do --- so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in all --- copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --- SOFTWARE. --- - -local json = { _version = "0.1.2" } - -------------------------------------------------------------------------------- --- Encode -------------------------------------------------------------------------------- - -local encode - -local escape_char_map = { - [ "\\" ] = "\\", - [ "\"" ] = "\"", - [ "\b" ] = "b", - [ "\f" ] = "f", - [ "\n" ] = "n", - [ "\r" ] = "r", - [ "\t" ] = "t", -} - -local escape_char_map_inv = { [ "/" ] = "/" } -for k, v in pairs(escape_char_map) do - escape_char_map_inv[v] = k -end - - -local function escape_char(c) - return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) -end - - -local function encode_nil(val) - return "null" -end - - -local function encode_table(val, stack) - local res = {} - stack = stack or {} - - -- Circular reference? - if stack[val] then error("circular reference") end - - stack[val] = true - - if rawget(val, 1) ~= nil or next(val) == nil then - -- Treat as array -- check keys are valid and it is not sparse - local n = 0 - for k in pairs(val) do - if type(k) ~= "number" then - error("invalid table: mixed or invalid key types") - end - n = n + 1 - end - if n ~= #val then - error("invalid table: sparse array") - end - -- Encode - for i, v in ipairs(val) do - table.insert(res, encode(v, stack)) - end - stack[val] = nil - return "[" .. table.concat(res, ",") .. "]" - - else - -- Treat as an object - for k, v in pairs(val) do - if type(k) ~= "string" then - error("invalid table: mixed or invalid key types") - end - table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) - end - stack[val] = nil - return "{" .. table.concat(res, ",") .. "}" - end -end - - -local function encode_string(val) - return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' -end - - -local function encode_number(val) - -- Check for NaN, -inf and inf - if val ~= val or val <= -math.huge or val >= math.huge then - error("unexpected number value '" .. tostring(val) .. "'") - end - return string.format("%.14g", val) -end - - -local type_func_map = { - [ "nil" ] = encode_nil, - [ "table" ] = encode_table, - [ "string" ] = encode_string, - [ "number" ] = encode_number, - [ "boolean" ] = tostring, -} - - -encode = function(val, stack) - local t = type(val) - local f = type_func_map[t] - if f then - return f(val, stack) - end - error("unexpected type '" .. t .. "'") -end - - -function json.encode(val) - return ( encode(val) ) -end - - -------------------------------------------------------------------------------- --- Decode -------------------------------------------------------------------------------- - -local parse - -local function create_set(...) - local res = {} - for i = 1, select("#", ...) do - res[ select(i, ...) ] = true - end - return res -end - -local space_chars = create_set(" ", "\t", "\r", "\n") -local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") -local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") -local literals = create_set("true", "false", "null") - -local literal_map = { - [ "true" ] = true, - [ "false" ] = false, - [ "null" ] = nil, -} - - -local function next_char(str, idx, set, negate) - for i = idx, #str do - if set[str:sub(i, i)] ~= negate then - return i - end - end - return #str + 1 -end - - -local function decode_error(str, idx, msg) - local line_count = 1 - local col_count = 1 - for i = 1, idx - 1 do - col_count = col_count + 1 - if str:sub(i, i) == "\n" then - line_count = line_count + 1 - col_count = 1 - end - end - error( string.format("%s at line %d col %d", msg, line_count, col_count) ) -end - - -local function codepoint_to_utf8(n) - -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa - local f = math.floor - if n <= 0x7f then - return string.char(n) - elseif n <= 0x7ff then - return string.char(f(n / 64) + 192, n % 64 + 128) - elseif n <= 0xffff then - return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) - elseif n <= 0x10ffff then - return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, - f(n % 4096 / 64) + 128, n % 64 + 128) - end - error( string.format("invalid unicode codepoint '%x'", n) ) -end - - -local function parse_unicode_escape(s) - local n1 = tonumber( s:sub(1, 4), 16 ) - local n2 = tonumber( s:sub(7, 10), 16 ) - -- Surrogate pair? - if n2 then - return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) - else - return codepoint_to_utf8(n1) - end -end - - -local function parse_string(str, i) - local res = "" - local j = i + 1 - local k = j - - while j <= #str do - local x = str:byte(j) - - if x < 32 then - decode_error(str, j, "control character in string") - - elseif x == 92 then -- `\`: Escape - res = res .. str:sub(k, j - 1) - j = j + 1 - local c = str:sub(j, j) - if c == "u" then - local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) - or str:match("^%x%x%x%x", j + 1) - or decode_error(str, j - 1, "invalid unicode escape in string") - res = res .. parse_unicode_escape(hex) - j = j + #hex - else - if not escape_chars[c] then - decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") - end - res = res .. escape_char_map_inv[c] - end - k = j + 1 - - elseif x == 34 then -- `"`: End of string - res = res .. str:sub(k, j - 1) - return res, j + 1 - end - - j = j + 1 - end - - decode_error(str, i, "expected closing quote for string") -end - - -local function parse_number(str, i) - local x = next_char(str, i, delim_chars) - local s = str:sub(i, x - 1) - local n = tonumber(s) - if not n then - decode_error(str, i, "invalid number '" .. s .. "'") - end - return n, x -end - - -local function parse_literal(str, i) - local x = next_char(str, i, delim_chars) - local word = str:sub(i, x - 1) - if not literals[word] then - decode_error(str, i, "invalid literal '" .. word .. "'") - end - return literal_map[word], x -end - - -local function parse_array(str, i) - local res = {} - local n = 1 - i = i + 1 - while 1 do - local x - i = next_char(str, i, space_chars, true) - -- Empty / end of array? - if str:sub(i, i) == "]" then - i = i + 1 - break - end - -- Read token - x, i = parse(str, i) - res[n] = x - n = n + 1 - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "]" then break end - if chr ~= "," then decode_error(str, i, "expected ']' or ','") end - end - return res, i -end - - -local function parse_object(str, i) - local res = {} - i = i + 1 - while 1 do - local key, val - i = next_char(str, i, space_chars, true) - -- Empty / end of object? - if str:sub(i, i) == "}" then - i = i + 1 - break - end - -- Read key - if str:sub(i, i) ~= '"' then - decode_error(str, i, "expected string for key") - end - key, i = parse(str, i) - -- Read ':' delimiter - i = next_char(str, i, space_chars, true) - if str:sub(i, i) ~= ":" then - decode_error(str, i, "expected ':' after key") - end - i = next_char(str, i + 1, space_chars, true) - -- Read value - val, i = parse(str, i) - -- Set - res[key] = val - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "}" then break end - if chr ~= "," then decode_error(str, i, "expected '}' or ','") end - end - return res, i -end - - -local char_func_map = { - [ '"' ] = parse_string, - [ "0" ] = parse_number, - [ "1" ] = parse_number, - [ "2" ] = parse_number, - [ "3" ] = parse_number, - [ "4" ] = parse_number, - [ "5" ] = parse_number, - [ "6" ] = parse_number, - [ "7" ] = parse_number, - [ "8" ] = parse_number, - [ "9" ] = parse_number, - [ "-" ] = parse_number, - [ "t" ] = parse_literal, - [ "f" ] = parse_literal, - [ "n" ] = parse_literal, - [ "[" ] = parse_array, - [ "{" ] = parse_object, -} - - -parse = function(str, idx) - local chr = str:sub(idx, idx) - local f = char_func_map[chr] - if f then - return f(str, idx) - end - decode_error(str, idx, "unexpected character '" .. chr .. "'") -end - - -function json.decode(str) - if type(str) ~= "string" then - error("expected argument of type string, got " .. type(str)) - end - local res, idx = parse(str, next_char(str, 1, space_chars, true)) - idx = next_char(str, idx, space_chars, true) - if idx <= #str then - decode_error(str, idx, "trailing garbage") - end - return res -end - - -return json diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua new file mode 100644 index 00000000..a5dd91e0 --- /dev/null +++ b/src/client/resources/ui_scripts/common.lua @@ -0,0 +1,162 @@ +menucallbacks = {} +originalmenus = {} +stack = {} + +LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) + local oncancel = stack.oncancel + local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { + message_text = stack.text, + isLiveWithCancel = true, + cancel_func = function(...) + local args = {...} + oncancel() + LUI.FlowManager.RequestLeaveMenu(args[1]) + end + }) + + popup.text = popup:getchildren()[7] + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() + local callback = stack.callback + local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { + popup_title = stack.title, + message_text = stack.text, + yes_action = function() + callback(true) + end, + no_action = function() + callback(false) + end + }) + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() + local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { + cancel_will_close = false, + popup_title = stack.title, + message_text = stack.text, + button_text = stack.buttontext, + confirmation_action = stack.callback + }) + + stack = { + ret = popup + } + + return stack.ret +end + +LUI.onmenuopen = function(name, callback) + if (not LUI.MenuBuilder.m_types_build[name]) then + return + end + + if (not menucallbacks[name]) then + menucallbacks[name] = {} + end + + table.insert(menucallbacks[name], callback) + + if (not originalmenus[name]) then + originalmenus[name] = LUI.MenuBuilder.m_types_build[name] + LUI.MenuBuilder.m_types_build[name] = function(...) + local args = {...} + local menu = originalmenus[name](table.unpack(args)) + + for k, v in luiglobals.next, menucallbacks[name] do + v(menu, table.unpack(args)) + end + + return menu + end + end +end + +local addoptionstextinfo = LUI.Options.AddOptionTextInfo +LUI.Options.AddOptionTextInfo = function(menu) + local result = addoptionstextinfo(menu) + menu.optionTextInfo = result + return result +end + +LUI.addmenubutton = function(name, data) + LUI.onmenuopen(name, function(menu) + if (not menu.list) then + return + end + + local button = menu:AddButton(data.text, data.callback, nil, true, nil, { + desc_text = data.description + }) + + local buttonlist = menu:getChildById(menu.type .. "_list") + + if (data.id) then + button.id = data.id + end + + if (data.index) then + buttonlist:removeElement(button) + buttonlist:insertElement(button, data.index) + end + + local hintbox = menu.optionTextInfo + menu:removeElement(hintbox) + + LUI.Options.InitScrollingList(menu.list, nil) + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + end) +end + +LUI.openmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestAddMenu(nil, menu) + return stack.ret +end + +LUI.openpopupmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestPopupMenu(nil, menu) + return stack.ret +end + +LUI.yesnopopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") + return stack.ret +end + +LUI.confirmationpopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") + return stack.ret +end + +function userdata_:getchildren() + local children = {} + local first = self:getFirstChild() + + while (first) do + table.insert(children, first) + first = first:getNextSibling() + end + + return children +end diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua new file mode 100644 index 00000000..01d77360 --- /dev/null +++ b/src/client/resources/ui_scripts/updater.lua @@ -0,0 +1,164 @@ +updatecancelled = false +taskinterval = 100 + +updater.cancelupdate() + +function startupdatecheck(popup, autoclose) + updatecancelled = false + + local callback = function() + if (not updater.getupdatecheckstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + if (not updater.isupdateavailable()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("No updates available") + return + end + + LUI.yesnopopup({ + title = "NOTICE", + text = "An update is available, proceed with installation?", + callback = function(result) + if (result) then + startupdatedownload(popup, autoclose) + else + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + }) + end + + updater.startupdatecheck() + createtask({ + done = updater.isupdatecheckdone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function startupdatedownload(popup, autoclose) + updater.startupdatedownload() + + local textupdate = nil + local previousfile = nil + textupdate = game:oninterval(function() + local file = updater.getcurrentfile() + if (file == previousfile) then + return + end + + file = previousfile + popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") + end, 10) + + local callback = function() + textupdate:clear() + + if (not updater.getupdatedownloadstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + popup.text:setText("Update successful") + + if (updater.isrestartrequired()) then + LUI.confirmationpopup({ + title = "RESTART REQUIRED", + text = "Update requires restart", + buttontext = "RESTART", + callback = function() + updater.relaunch() + end + }) + else + if (LUI.mp_menus) then + Engine.Exec("lui_restart; lui_open mp_main_menu") + else + Engine.Exec("lui_restart") + end + end + + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + + createtask({ + done = updater.isupdatedownloaddone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function updaterpopup(oncancel) + return LUI.openpopupmenu("generic_waiting_popup_", { + oncancel = oncancel, + withcancel = true, + text = "Checking for updates..." + }) +end + +function createtask(data) + local interval = nil + interval = game:oninterval(function() + if (data.cancelled()) then + interval:clear() + return + end + + if (data.done()) then + interval:clear() + data.callback() + end + end, data.interval) + return interval +end + +function isupdatecancelled() + return updatecancelled +end + +function tryupdate(autoclose) + updatecancelled = false + local popup = updaterpopup(function() + updater.cancelupdate() + updatecancelled = true + end) + + startupdatecheck(popup, autoclose) +end + +function tryautoupdate() + if (not updater.autoupdatesenabled()) then + return + end + + if (not updater.gethastriedupdate()) then + game:ontimeout(function() + updater.sethastriedupdate(true) + tryupdate(true) + end, 100) + end +end + +LUI.onmenuopen("mp_main_menu", tryautoupdate) +LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file diff --git a/src/client/resources/updater.lua b/src/client/resources/updater.lua deleted file mode 100644 index 2e3b79f6..00000000 --- a/src/client/resources/updater.lua +++ /dev/null @@ -1,411 +0,0 @@ -menucallbacks = {} -originalmenus = {} - -LUI.onmenuopen = function(name, callback) - if (not LUI.MenuBuilder.m_types_build[name]) then - return - end - - if (not menucallbacks[name]) then - menucallbacks[name] = {} - end - - table.insert(menucallbacks[name], callback) - - if (not originalmenus[name]) then - originalmenus[name] = LUI.MenuBuilder.m_types_build[name] - LUI.MenuBuilder.m_types_build[name] = function(...) - local args = {...} - local menu = originalmenus[name](table.unpack(args)) - - for k, v in luiglobals.next, menucallbacks[name] do - v(menu, table.unpack(args)) - end - - return menu - end - end -end - -local addoptionstextinfo = LUI.Options.AddOptionTextInfo -LUI.Options.AddOptionTextInfo = function(menu) - local result = addoptionstextinfo(menu) - menu.optionTextInfo = result - return result -end - -LUI.addmenubutton = function(name, data) - LUI.onmenuopen(name, function(menu) - if (not menu.list) then - return - end - - local button = menu:AddButton(data.text, data.callback, nil, true, nil, { - desc_text = data.description - }) - - local buttonlist = menu:getChildById(menu.type .. "_list") - - if (data.id) then - button.id = data.id - end - - if (data.index) then - buttonlist:removeElement(button) - buttonlist:insertElement(button, data.index) - end - - local hintbox = menu.optionTextInfo - menu:removeElement(hintbox) - - LUI.Options.InitScrollingList(menu.list, nil) - menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) - end) -end - -stack = {} -LUI.openmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestAddMenu(nil, menu) - return stack.ret -end - -LUI.openpopupmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestPopupMenu(nil, menu) - return stack.ret -end - -LUI.onmenuopen("main_lockout", function() - if (game:isdebugbuild() or not Engine.GetDvarBool("cg_autoUpdate")) then - return - end - - if (game:sharedget("has_tried_updating") == "") then - game:ontimeout(function() - game:sharedset("has_tried_updating", "1") - tryupdate(true) - end, 0) - end -end) - -stack = {} -LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) - local oncancel = stack.oncancel - local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { - message_text = stack.text, - isLiveWithCancel = true, - cancel_func = function(...) - local args = {...} - oncancel() - LUI.common_menus.CommonPopups.CancelCSSDownload(table.unpack(args)) - end - }) - - stack = { - ret = popup - } - - return popup -end - -LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() - local callback = stack.callback - local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { - popup_title = stack.title, - message_text = stack.text, - yes_action = function() - callback(true) - end, - no_action = function() - callback(false) - end - }) - - stack = { - ret = popup - } - - return popup -end - -LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() - local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { - cancel_will_close = false, - popup_title = stack.title, - message_text = stack.text, - button_text = stack.buttontext, - confirmation_action = stack.callback - }) - - stack = { - ret = popup - } - - return stack.ret -end - -LUI.yesnopopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") - return stack.ret -end - -LUI.confirmationpopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") - return stack.ret -end - -function updaterpopup(oncancel) - return LUI.openpopupmenu("generic_waiting_popup_", { - oncancel = oncancel, - withcancel = true, - text = "Checking for updates..." - }) -end - -function deleteoldfile() - io.removefile(game:binaryname() .. ".old") -end - -deleteoldfile() - -function verifyfiles(files) - local needed = {} - local updatebinary = false - - if (game:isdebugbuild()) then - return needed, updatebinary - end - - local binaryname = game:binaryname() - - for i = 1, #files do - local name = files[i][1] - - if (io.fileexists(name) and game:sha(io.readfile(name)) == files[i][3]) then - goto continue - end - - if (name == binaryname) then - updatebinary = true - end - - table.insert(needed, files[i]) - - ::continue:: - end - - return needed, updatebinary -end - -local canceled = false - -function downloadfiles(popup, files, callback) - deleteoldfile() - - local text = popup:getchildren()[7] - local folder = game:environment() == "develop" and "data-dev" or "data" - - if (#files == 0) then - callback(true) - return - end - - local total = 0 - local filedownloaded = function() - total = total + 1 - if (total == #files) then - callback(true) - end - end - - local download = nil - local stop = false - download = function(index) - if (canceled or stop) then - return - end - - local filename = files[index][1] - - local url = "https://master.fed0001.xyz/" .. folder .. "/" .. filename .. "?" .. os.time() - text:setText(string.format("Downloading file [%i/%i]\n%s", index, #files, filename)) - - if (filename == game:binaryname()) then - io.movefile(filename, filename .. ".old") - end - - httprequesttofile(url, filename, function(valid, success) - if (not valid) then - callback(false, "Invalid server response") - stop = true - return - end - - if (not success) then - callback(false, "Failed to write file " .. filename) - stop = true - return - end - - filedownloaded() - - if (files[index + 1]) then - download(index + 1) - else - callback(true) - end - end) - end - - download(1) -end - -function userdata_:getchildren() - local children = {} - local first = self:getFirstChild() - - while (first) do - table.insert(children, first) - first = first:getNextSibling() - end - - return children -end - -function tryupdate(autoclose) - canceled = false - local popup = updaterpopup(function() - canceled = true - end) - - local text = popup:getchildren()[7] - local file = game:environment() == "develop" and "files-dev.json" or "files.json" - local url = "https://master.fed0001.xyz/" .. file .. "?" .. os.time() - - httprequest(url, function(valid, data) - if (not valid) then - text:setText("Update check failed: Invalid server response") - return - end - - local valid = pcall(function() - local files = json.decode(data) - local needed, updatebinary = verifyfiles(files) - - if (#needed == 0) then - text:setText("No updates available") - if (autoclose) then - LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {}) - end - return - end - - local download = function() - local gotresult = false - downloadfiles(popup, needed, function(result, error) - if (gotresult or canceled) then - return - end - - gotresult = true - - if (not result) then - text:setText("Update failed: " .. error) - return - end - - if (updatebinary) then - LUI.confirmationpopup({ - title = "RESTART REQUIRED", - text = "Update requires restart", - buttontext = "RESTART", - callback = function() - game:relaunch() - end - }) - return - end - - if (result and #needed > 0) then - game:executecommand("lui_restart") - return - end - - text:setText("Update successful!") - - if (autoclose) then - LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {}) - end - end) - end - - if (autoclose) then - download() - else - LUI.yesnopopup({ - title = "NOTICE", - text = "An update is available, proceed with installation?", - callback = function(result) - if (not result) then - LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {}) - else - download() - end - end - }) - end - end) - - if (not valid) then - text:setText("Update failed: unknown error") - end - end) -end - -LUI.tryupdating = function(autoclose) - tryupdate(autoclose) -end - -function httprequest(url, callback) - local request = game:httpget(url) - local listener = nil - listener = game:onnotify("http_request_done", function(id, valid, data) - if (id ~= request) then - return - end - - listener:clear() - callback(valid, data) - end) -end - -function httprequesttofile(url, dest, callback) - local request = game:httpgettofile(url, dest) - local listener = nil - listener = game:onnotify("http_request_done", function(id, valid, success) - if (id ~= request) then - return - end - - listener:clear() - callback(valid, success) - end) -end - -local localize = Engine.Localize -Engine.Localize = function(...) - local args = {...} - - if (type(args[1]) == "string" and args[1]:sub(1, 2) == "$_") then - return args[1]:sub(3, -1) - end - - return localize(table.unpack(args)) -end \ No newline at end of file From 769d2c74cb4209f451f185151fb5a5f419c813a4 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 00:41:25 +0100 Subject: [PATCH 32/52] Some fixes --- data/ui_scripts/settings/__init__.lua | 145 +++++++++++--------- src/client/component/updater.cpp | 2 +- src/client/game/ui_scripting/lua/engine.cpp | 2 +- src/client/resources/ui_scripts/updater.lua | 8 +- 4 files changed, 81 insertions(+), 76 deletions(-) diff --git a/data/ui_scripts/settings/__init__.lua b/data/ui_scripts/settings/__init__.lua index 2e3db5bd..4bd4beab 100644 --- a/data/ui_scripts/settings/__init__.lua +++ b/data/ui_scripts/settings/__init__.lua @@ -1,3 +1,28 @@ +game:addlocalizedstring("MENU_GENERAL", "General") +game:addlocalizedstring("MENU_GENERAL_DESC", "Set the client's settings.") +game:addlocalizedstring("LUA_MENU_AUTO_UPDATE", "Automatic updates") +game:addlocalizedstring("LUA_MENU_CHECK_UPDATES", "Check for updates") +game:addlocalizedstring("LUA_MENU_CHECK_UPDATES_DESC", "Check for updates.") +game:addlocalizedstring("LUA_MENU_DRAWING", "Drawing") +game:addlocalizedstring("LUA_MENU_UPDATES", "Updates") +game:addlocalizedstring("LUA_MENU_RENDERING", "Rendering") + +game:addlocalizedstring("LUA_MENU_DRAW_FPS", "Draw FPS") +game:addlocalizedstring("LUA_MENU_DRAW_FPS_DESC", "Enable or disable drawing fps or viewpos on screen.") +game:addlocalizedstring("LUA_MENU_FPS_ONLY", "FPS only") +game:addlocalizedstring("LUA_MENU_FPS_AND_VIEWPOS", "FPS and View Pos") + +game:addlocalizedstring("LUA_MENU_DRAW_SPEED", "Draw speed") +game:addlocalizedstring("LUA_MENU_DRAW_SPEED_DESC", "Enable or disable drawing the player speed on screen.") + +game:addlocalizedstring("LUA_MENU_DRAW_SPEEDGRAPH", "Draw speed graph") +game:addlocalizedstring("LUA_MENU_DRAW_SPEEDGRAPH_DESC", "Enable or disable the speed graph.") + +game:addlocalizedstring("LUA_MENU_R_FULLBRIGHT", "Fullbright") +game:addlocalizedstring("LUA_MENU_R_FULLBRIGHT_DESC", "Change the fullbright mode.") +game:addlocalizedstring("LUA_MENU_MODE2", "Mode 2") +game:addlocalizedstring("LUA_MENU_MODE3", "Mode 3") + function createdivider(menu, text) local element = LUI.UIElement.new({ leftAnchor = true, @@ -20,8 +45,8 @@ end LUI.addmenubutton("pc_controls", { index = 4, - text = "$_GENERAL", - description = "Set the client's settings.", + text = "@MENU_GENERAL", + description = "@MENU_GENERAL_DESC", callback = function() LUI.FlowManager.RequestAddMenu(nil, "settings_menu") end @@ -29,134 +54,118 @@ LUI.addmenubutton("pc_controls", { LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) local menu = LUI.MenuTemplate.new(a1, { - menu_title = "$_GENERAL", + menu_title = "@MENU_GENERAL", menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + luiglobals.H1MenuDims.spacing), menu_width = luiglobals.GenericMenuDims.OptionMenuWidth }) - Engine.SetDvarFromString("ui_cg_autoUpdate", Engine.GetDvarBool("cg_autoUpdate") and "1" or "0") - Engine.SetDvarFromString("ui_cg_drawFps", Engine.GetDvarInt("cg_drawFps") .. "") - Engine.SetDvarFromString("ui_cg_speedGraph", Engine.GetDvarBool("cg_speedGraph") and "1" or "0") - Engine.SetDvarFromString("ui_cg_drawSpeed", Engine.GetDvarBool("cg_drawSpeed") and "1" or "0") - Engine.SetDvarFromString("ui_r_fullbright", Engine.GetDvarInt("r_fullbright") .. "") - - createdivider(menu, "$_UPDATES") + createdivider(menu, "@LUA_MENU_UPDATES") LUI.Options.CreateOptionButton( menu, - "ui_cg_autoUpdate", - "$_AUTOMATIC UPDATES", + "cg_autoUpdate", + "@LUA_MENU_AUTO_UPDATE", "Enable or disable automatic updates on startup.", { { - text = "$_ENABLED", - value = "1" + text = "@LUA_MENU_ENABLED", + value = true }, { - text = "$_DISABLED", - value = "0" + text = "@LUA_MENU_DISABLED", + value = false } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_autoUpdate", Engine.GetDvarString("ui_cg_autoUpdate") == "1") - end + } ) - menu:AddButton("$_CHECK FOR UPDATES", function() + menu:AddButton("@LUA_MENU_CHECK_UPDATES", function() LUI.tryupdating(false) end, nil, true, nil, { - desc_text = "Check for updates." + desc_text = Engine.Localize("@LUA_MENU_CHECK_UPDATES_DESC") }) - createdivider(menu, "$_DRAWING") + createdivider(menu, "@LUA_MENU_DRAWING") LUI.Options.CreateOptionButton( menu, - "ui_cg_drawFps", - "$_DRAW FPS", - "Enable or disable drawing fps or viewpos on screen.", + "cg_drawFps", + "@LUA_MENU_DRAW_FPS", + "@LUA_MENU_DRAW_FPS_DESC", { { - text = "$_DISABLED", - value = "0" + text = "@LUA_MENU_DISABLED", + value = 0 }, { - text = "$_FPS ONLY", - value = "1" + text = "@LUA_MENU_FPS_ONLY", + value = 1 }, { - text = "$_FPS AND VIEWPOS", - value = "2" + text = "@LUA_MENU_FPS_AND_VIEWPOS", + value = 2 } - }, nil, nil, function(value) - Engine.SetDvarInt("cg_drawFps", tonumber(Engine.GetDvarString("ui_cg_drawFps"))) - end + } ) LUI.Options.CreateOptionButton( menu, - "ui_cg_drawSpeed", - "$_DRAW SPEED", + "cg_drawSpeed", + "@LUA_MENU_DRAW_SPEED", "Enable or disable drawing the player speed on screen.", { { - text = "$_DISABLED", - value = "0" + text = "@LUA_MENU_ENABLED", + value = true }, { - text = "$_ENABLED", - value = "1" + text = "@LUA_MENU_DISABLED", + value = false } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_drawSpeed", Engine.GetDvarString("ui_cg_drawSpeed") == "1") - end + } ) LUI.Options.CreateOptionButton( menu, - "ui_cg_speedGraph", - "$_DRAW SPEED GRAPH", - "Enable or disable the speed graph.", + "cg_speedGraph", + "@LUA_MENU_DRAW_SPEEDGRAPH", + "@LUA_MENU_DRAW_SPEEDGRAPH_DESC", { { - text = "$_DISABLED", - value = "0" + text = "@LUA_MENU_ENABLED", + value = true }, { - text = "$_ENABLED", - value = "1" + text = "@LUA_MENU_DISABLED", + value = false } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_speedGraph", Engine.GetDvarString("ui_cg_speedGraph") == "1") - end + } ) - createdivider(menu, "$_RENDERING") + createdivider(menu, "@LUA_MENU_RENDERING") LUI.Options.CreateOptionButton( menu, - "ui_r_fullbright", - "$_FULLBRIGHT", - "Change the fullbright mode.", + "r_fullbright", + "@LUA_MENU_R_FULLBRIGHT", + "@LUA_MENU_R_FULLBRIGHT_DESC", { { - text = "$_DISABLED", - value = "0" + text = "@LUA_MENU_DISABLED", + value = 0 }, { - text = "$_ENABLED", - value = "1" + text = "@LUA_MENU_ENABLED", + value = 1 }, { - text = "$_MODE 2", - value = "2" + text = "@LUA_MENU_MODE2", + value = 2 }, { - text = "$_MODE 3", - value = "3" + text = "@LUA_MENU_MODE3", + value = 3 } - }, nil, nil, function(value) - Engine.SetDvarInt("r_fullbright", tonumber(Engine.GetDvarString("ui_r_fullbright"))) - end + } ) LUI.Options.InitScrollingList(menu.list, nil) diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index 9700d72f..fe6ac7e4 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -352,7 +352,7 @@ namespace updater if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) { return; - }// + } scheduler::once([]() { diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index d1bd4245..304fb761 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -74,7 +74,7 @@ namespace ui_scripting::lua::engine get_scripts().clear(); load_code(lui_common); - // load_code(lui_updater); + load_code(lui_updater); for (const auto& path : filesystem::get_search_paths()) { diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua index 01d77360..7b32b7f8 100644 --- a/src/client/resources/ui_scripts/updater.lua +++ b/src/client/resources/ui_scripts/updater.lua @@ -89,11 +89,7 @@ function startupdatedownload(popup, autoclose) end }) else - if (LUI.mp_menus) then - Engine.Exec("lui_restart; lui_open mp_main_menu") - else - Engine.Exec("lui_restart") - end + Engine.Exec("lui_restart") end if (autoclose) then @@ -160,5 +156,5 @@ function tryautoupdate() end end -LUI.onmenuopen("mp_main_menu", tryautoupdate) +LUI.tryupdating = tryupdate LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file From 2f5eaa82988003e24f7d162d10e1bdd86187494a Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 00:57:07 +0100 Subject: [PATCH 33/52] Cleanup ui scripts --- data/ui_scripts/branding/__init__.lua | 130 +++++------ data/ui_scripts/mods/__init__.lua | 2 +- data/ui_scripts/mods/loading.lua | 165 +++++++------- data/ui_scripts/settings/__init__.lua | 6 +- src/client/resources/ui_scripts/updater.lua | 230 ++++++++++---------- 5 files changed, 267 insertions(+), 266 deletions(-) diff --git a/data/ui_scripts/branding/__init__.lua b/data/ui_scripts/branding/__init__.lua index f0338fbc..89368f2d 100644 --- a/data/ui_scripts/branding/__init__.lua +++ b/data/ui_scripts/branding/__init__.lua @@ -5,88 +5,88 @@ local extrawidth = 50 local extraheight = 40 LUI.MenuBuilder.m_types_build["SystemInfo"] = function (f6_arg0, f6_arg1) - local f6_local0 = LUI.MenuTemplate.spMenuOffset - local title = "LUA_MENU_SYSTEM_INFO_CAPS" + local f6_local0 = LUI.MenuTemplate.spMenuOffset + local title = "LUA_MENU_SYSTEM_INFO_CAPS" - local f6_local2 = false - local f6_local3 = 0 + local f6_local2 = false + local f6_local3 = 0 - local menu = LUI.MenuTemplate.new(f6_arg0, { - menu_title = title, - menu_top_indent = f6_local0 + f6_local3, - showSelectButton = false, - skipAnim = f6_local2 - }) + local menu = LUI.MenuTemplate.new(f6_arg0, { + menu_title = title, + menu_top_indent = f6_local0 + f6_local3, + showSelectButton = false, + skipAnim = f6_local2 + }) - menu:setClass(LUI.SystemInfo) - menu:PopulateMissingProps(f6_arg1) - menu:ValidateProps(f6_arg1) - menu.id = "systemInfo_id" + menu:setClass(LUI.SystemInfo) + menu:PopulateMissingProps(f6_arg1) + menu:ValidateProps(f6_arg1) + menu.id = "systemInfo_id" - local f6_local5 = 300 - local f6_local6 = LUI.MenuTemplate.ListTop + f6_local0 - local f6_local7 = f6_arg1.menu_height - if not f6_local7 then - f6_local7 = f6_local5 - end + local f6_local5 = 300 + local f6_local6 = LUI.MenuTemplate.ListTop + f6_local0 + local f6_local7 = f6_arg1.menu_height + if not f6_local7 then + f6_local7 = f6_local5 + end - f6_local7 = f6_local7 + f6_local6 - extraheight + f6_local7 = f6_local7 + f6_local6 - extraheight - local f6_local9 = luiglobals.GenericMenuDims.OptionMenuWidth + 100 - local f6_local10 = menu.properties - local topoffset2 = LUI.MenuTemplate.ListTop + LUI.MenuTemplate.spMenuOffset + local f6_local9 = luiglobals.GenericMenuDims.OptionMenuWidth + 100 + local f6_local10 = menu.properties + local topoffset2 = LUI.MenuTemplate.ListTop + LUI.MenuTemplate.spMenuOffset - local decobox = LUI.MenuBuilder.BuildRegisteredType("h1_box_deco", { - decoTopOffset = topoffset2 - topoffset + 15, - decoBottomOffset = -f6_local7, - decoRightOffset = -665 + extrawidth - }) + local decobox = LUI.MenuBuilder.BuildRegisteredType("h1_box_deco", { + decoTopOffset = topoffset2 - topoffset + 15, + decoBottomOffset = -f6_local7, + decoRightOffset = -665 + extrawidth + }) - menu:addElement(decobox) + menu:addElement(decobox) - local decoleft = CoD.CreateState(0, 0.5, 8, 0.5, CoD.AnchorTypes.TopLeft) - decoleft.color = luiglobals.Colors.h1.light_grey - decobox:addElement(LUI.UILine.new(decoleft)) + local decoleft = CoD.CreateState(0, 0.5, 8, 0.5, CoD.AnchorTypes.TopLeft) + decoleft.color = luiglobals.Colors.h1.light_grey + decobox:addElement(LUI.UILine.new(decoleft)) - local decoright = CoD.CreateState(0, 0.5, -8, 0.5, CoD.AnchorTypes.TopRight) - decoright.color = luiglobals.Colors.h1.light_grey - decobox:addElement(LUI.UILine.new(decoright)) + local decoright = CoD.CreateState(0, 0.5, -8, 0.5, CoD.AnchorTypes.TopRight) + decoright.color = luiglobals.Colors.h1.light_grey + decobox:addElement(LUI.UILine.new(decoright)) - local element = LUI.UIVerticalList.new({ - leftAnchor = true, - rightAnchor = true, - topAnchor = true, - bottomAnchor = true, - left = spacing, - right = 100, - top = topoffset2 + 15, - bottom = 0, - spacing = spacing * 0.8 - }) + local element = LUI.UIVerticalList.new({ + leftAnchor = true, + rightAnchor = true, + topAnchor = true, + bottomAnchor = true, + left = spacing, + right = 100, + top = topoffset2 + 15, + bottom = 0, + spacing = spacing * 0.8 + }) - element.id = "systemInfoList_id" - menu.vlist = element - menu:addElement(element) + element.id = "systemInfoList_id" + menu.vlist = element + menu:addElement(element) - local optionmenuwidth = luiglobals.GenericMenuDims.OptionMenuWidth - luiglobals.GenericMenuDims.OptionMenuWidth = optionmenuwidth + extrawidth + local optionmenuwidth = luiglobals.GenericMenuDims.OptionMenuWidth + luiglobals.GenericMenuDims.OptionMenuWidth = optionmenuwidth + extrawidth - menu:AddInfo(Engine.Localize("MENU_SYSINFO_VERSION"), function() - return Engine.GetBuildNumber() - end) + menu:AddInfo(Engine.Localize("MENU_SYSINFO_VERSION"), function() + return Engine.GetBuildNumber() + end) - menu:AddInfo(Engine.Localize("MENU_SYSINFO_CUSTOMER_SUPPORT_LINK"), function() - return Engine.Localize("MENU_SYSINFO_CUSTOMER_SUPPORT_URL") - end) + menu:AddInfo(Engine.Localize("MENU_SYSINFO_CUSTOMER_SUPPORT_LINK"), function() + return Engine.Localize("MENU_SYSINFO_CUSTOMER_SUPPORT_URL") + end) - menu:AddInfo(Engine.Localize("MENU_SYSINFO_DONATION_LINK"), function() - return Engine.Localize("MENU_SYSINFO_DONATION_URL") - end) + menu:AddInfo(Engine.Localize("MENU_SYSINFO_DONATION_LINK"), function() + return Engine.Localize("MENU_SYSINFO_DONATION_URL") + end) - luiglobals.GenericMenuDims.OptionMenuWidth = optionmenuwidth + luiglobals.GenericMenuDims.OptionMenuWidth = optionmenuwidth - menu:AddBackButton() - menu:registerEventHandler("menu_close", LUI.SystemInfo.LeaveMenu) + menu:AddBackButton() + menu:registerEventHandler("menu_close", LUI.SystemInfo.LeaveMenu) - return menu + return menu end \ No newline at end of file diff --git a/data/ui_scripts/mods/__init__.lua b/data/ui_scripts/mods/__init__.lua index e591a736..ca2d3da9 100644 --- a/data/ui_scripts/mods/__init__.lua +++ b/data/ui_scripts/mods/__init__.lua @@ -1 +1 @@ -require("loading") \ No newline at end of file +require("loading") diff --git a/data/ui_scripts/mods/loading.lua b/data/ui_scripts/mods/loading.lua index 18fab2c8..c83ea272 100644 --- a/data/ui_scripts/mods/loading.lua +++ b/data/ui_scripts/mods/loading.lua @@ -1,3 +1,14 @@ +game:addlocalizedstring("MENU_MODS", "MODS") +game:addlocalizedstring("MENU_MODS_DESC", "Load installed mods.") +game:addlocalizedstring("LUA_MENU_MOD_DESC_DEFAULT", "Load &&1.") +game:addlocalizedstring("LUA_MENU_MOD_DESC", "&&1\nAuthor: &&2\nVersion: &&3") +game:addlocalizedstring("LUA_MENU_OPEN_STORE", "Open store") +game:addlocalizedstring("LUA_MENU_OPEN_STORE_DESC", "Download and install mods.") +game:addlocalizedstring("LUA_MENU_LOADED_MOD", "Loaded mod: ^3&&1") +game:addlocalizedstring("LUA_MENU_AVAILABLE_MODS", "Available mods") +game:addlocalizedstring("LUA_MENU_UNLOAD", "Unload") +game:addlocalizedstring("LUA_MENU_UNLOAD_DESC", "Unload the currently loaded mod.") + function createdivider(menu, text) local element = LUI.UIElement.new( { leftAnchor = true, @@ -12,112 +23,102 @@ function createdivider(menu, text) element.scrollingToNext = true element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { - title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) + title_bar_text = Engine.ToUpperCase(text) })) menu.list:addElement(element) end function string:truncate(length) - if (#self <= length) then - return self - end + if (#self <= length) then + return self + end - return self:sub(1, length - 3) .. "..." + return self:sub(1, length - 3) .. "..." end LUI.addmenubutton("main_campaign", { - index = 6, - text = "$_MODS", - description = "Load installed mods.", - callback = function() - LUI.FlowManager.RequestAddMenu(nil, "mods_menu") - end + index = 6, + text = "@MENU_MODS", + description = Engine.Localize("@MENU_MODS_DESC"), + callback = function() + LUI.FlowManager.RequestAddMenu(nil, "mods_menu") + end }) function getmodname(path) - local name = path - local desc = "Load " .. name - local infofile = path .. "/info.json" + local name = path + local desc = Engine.Localize("@LUA_MENU_MOD_DESC_DEFAULT", name) + local infofile = path .. "/info.json" - if (io.fileexists(infofile)) then - pcall(function() - local data = json.decode(io.readfile(infofile)) - desc = string.format("%s\nAuthor: %s\nVersion: %s", - data.description, data.author, data.version) - name = data.name - end) - end + if (io.fileexists(infofile)) then + pcall(function() + local data = json.decode(io.readfile(infofile)) + desc = Engine.Localize("@LUA_MENU_MOD_DESC", + data.description, data.author, data.version) + name = data.name + end) + end - return name, desc + return name, desc end LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1) - local menu = LUI.MenuTemplate.new(a1, { - menu_title = "$_MODS", - exclusiveController = 0, - menu_width = 400, - menu_top_indent = LUI.MenuTemplate.spMenuOffset, - showTopRightSmallBar = true - }) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = "@MENU_MODS", + exclusiveController = 0, + menu_width = 400, + menu_top_indent = LUI.MenuTemplate.spMenuOffset, + showTopRightSmallBar = true + }) - menu:AddButton("$_OPEN STORE", function() - if (LUI.MenuBuilder.m_types_build["mod_store_menu"]) then - LUI.FlowManager.RequestAddMenu(nil, "mod_store_menu") - end - end, nil, true, nil, { - desc_text = "Download and install mods." - }) + menu:AddButton("@LUA_MENU_OPEN_STORE", function() + if (LUI.MenuBuilder.m_types_build["mod_store_menu"]) then + LUI.FlowManager.RequestAddMenu(nil, "mod_store_menu") + end + end, nil, true, nil, { + desc_text = Engine.Localize("@LUA_MENU_OPEN_STORE_DESC") + }) - local modfolder = game:getloadedmod() - if (modfolder ~= "") then - createdivider(menu, "$_Loaded mod: ^3" .. getmodname(modfolder):truncate(20)) + local modfolder = game:getloadedmod() + if (modfolder ~= "") then + createdivider(menu, Engine.Localize("@LUA_MENU_LOADED_MOD", getmodname(modfolder):truncate(24))) - menu:AddButton("$_UNLOAD", function() - game:executecommand("unloadmod") - end, nil, true, nil, { - desc_text = "Unload the currently loaded mod." - }) - end + menu:AddButton("@LUA_MENU_UNLOAD", function() + game:executecommand("unloadmod") + end, nil, true, nil, { + desc_text = Engine.Localize("@LUA_MENU_UNLOAD_DESC") + }) + end - createdivider(menu, "$_Available mods") + createdivider(menu, Engine.Localize("@LUA_MENU_AVAILABLE_MODS")) - if (io.directoryexists("mods")) then - local mods = io.listfiles("mods/") - for i = 1, #mods do - if (io.directoryexists(mods[i]) and not io.directoryisempty(mods[i])) then - local name, desc = getmodname(mods[i]) + if (io.directoryexists("mods")) then + local mods = io.listfiles("mods/") + for i = 1, #mods do + if (io.directoryexists(mods[i]) and not io.directoryisempty(mods[i])) then + local name, desc = getmodname(mods[i]) - if (mods[i] ~= modfolder) then - menu:AddButton("$_" .. name, function() - game:executecommand("loadmod " .. mods[i]) - end, nil, true, nil, { - desc_text = desc - }) - end - end - end - end - - menu:AddBackButton(function(a1) - Engine.PlaySound(CoD.SFX.MenuBack) - LUI.FlowManager.RequestLeaveMenu(a1) - end) + if (mods[i] ~= modfolder) then + game:addlocalizedstring(name, name) + menu:AddButton(name, function() + game:executecommand("loadmod " .. mods[i]) + end, nil, true, nil, { + desc_text = desc + }) + end + end + end + end + + menu:AddBackButton(function(a1) + Engine.PlaySound(CoD.SFX.MenuBack) + LUI.FlowManager.RequestLeaveMenu(a1) + end) - LUI.Options.InitScrollingList(menu.list, nil) - menu:CreateBottomDivider() - menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + LUI.Options.InitScrollingList(menu.list, nil) + menu:CreateBottomDivider() + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) - return menu + return menu end - -local localize = Engine.Localize -Engine.Localize = function(...) - local args = {...} - - if (type(args[1]) == "string" and args[1]:sub(1, 2) == "$_") then - return args[1]:sub(3, -1) - end - - return localize(table.unpack(args)) -end \ No newline at end of file diff --git a/data/ui_scripts/settings/__init__.lua b/data/ui_scripts/settings/__init__.lua index 4bd4beab..0facce7f 100644 --- a/data/ui_scripts/settings/__init__.lua +++ b/data/ui_scripts/settings/__init__.lua @@ -1,4 +1,4 @@ -game:addlocalizedstring("MENU_GENERAL", "General") +game:addlocalizedstring("MENU_GENERAL", "GENERAL") game:addlocalizedstring("MENU_GENERAL_DESC", "Set the client's settings.") game:addlocalizedstring("LUA_MENU_AUTO_UPDATE", "Automatic updates") game:addlocalizedstring("LUA_MENU_CHECK_UPDATES", "Check for updates") @@ -46,7 +46,7 @@ end LUI.addmenubutton("pc_controls", { index = 4, text = "@MENU_GENERAL", - description = "@MENU_GENERAL_DESC", + description = Engine.Localize("@MENU_GENERAL_DESC"), callback = function() LUI.FlowManager.RequestAddMenu(nil, "settings_menu") end @@ -174,4 +174,4 @@ LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) menu:AddBackButton() return menu -end \ No newline at end of file +end diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua index 7b32b7f8..329f83ef 100644 --- a/src/client/resources/ui_scripts/updater.lua +++ b/src/client/resources/ui_scripts/updater.lua @@ -4,157 +4,157 @@ taskinterval = 100 updater.cancelupdate() function startupdatecheck(popup, autoclose) - updatecancelled = false + updatecancelled = false - local callback = function() - if (not updater.getupdatecheckstatus()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end + local callback = function() + if (not updater.getupdatecheckstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end - popup.text:setText("Error: " .. updater.getlasterror()) - return - end + popup.text:setText("Error: " .. updater.getlasterror()) + return + end - if (not updater.isupdateavailable()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end + if (not updater.isupdateavailable()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end - popup.text:setText("No updates available") - return - end + popup.text:setText("No updates available") + return + end - LUI.yesnopopup({ - title = "NOTICE", - text = "An update is available, proceed with installation?", - callback = function(result) - if (result) then - startupdatedownload(popup, autoclose) - else - LUI.FlowManager.RequestLeaveMenu(popup) - end - end - }) - end + LUI.yesnopopup({ + title = "NOTICE", + text = "An update is available, proceed with installation?", + callback = function(result) + if (result) then + startupdatedownload(popup, autoclose) + else + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + }) + end - updater.startupdatecheck() - createtask({ - done = updater.isupdatecheckdone, - cancelled = isupdatecancelled, - callback = callback, - interval = taskinterval - }) + updater.startupdatecheck() + createtask({ + done = updater.isupdatecheckdone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) end function startupdatedownload(popup, autoclose) - updater.startupdatedownload() + updater.startupdatedownload() - local textupdate = nil - local previousfile = nil - textupdate = game:oninterval(function() - local file = updater.getcurrentfile() - if (file == previousfile) then - return - end + local textupdate = nil + local previousfile = nil + textupdate = game:oninterval(function() + local file = updater.getcurrentfile() + if (file == previousfile) then + return + end - file = previousfile - popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") - end, 10) + file = previousfile + popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") + end, 10) - local callback = function() - textupdate:clear() + local callback = function() + textupdate:clear() - if (not updater.getupdatedownloadstatus()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end + if (not updater.getupdatedownloadstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end - popup.text:setText("Error: " .. updater.getlasterror()) - return - end + popup.text:setText("Error: " .. updater.getlasterror()) + return + end - popup.text:setText("Update successful") + popup.text:setText("Update successful") - if (updater.isrestartrequired()) then - LUI.confirmationpopup({ - title = "RESTART REQUIRED", - text = "Update requires restart", - buttontext = "RESTART", - callback = function() - updater.relaunch() - end - }) - else - Engine.Exec("lui_restart") - end + if (updater.isrestartrequired()) then + LUI.confirmationpopup({ + title = "RESTART REQUIRED", + text = "Update requires restart", + buttontext = "RESTART", + callback = function() + updater.relaunch() + end + }) + else + Engine.Exec("lui_restart") + end - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - end - end + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + end + end - createtask({ - done = updater.isupdatedownloaddone, - cancelled = isupdatecancelled, - callback = callback, - interval = taskinterval - }) + createtask({ + done = updater.isupdatedownloaddone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) end function updaterpopup(oncancel) - return LUI.openpopupmenu("generic_waiting_popup_", { - oncancel = oncancel, - withcancel = true, - text = "Checking for updates..." - }) + return LUI.openpopupmenu("generic_waiting_popup_", { + oncancel = oncancel, + withcancel = true, + text = "Checking for updates..." + }) end function createtask(data) - local interval = nil - interval = game:oninterval(function() - if (data.cancelled()) then - interval:clear() - return - end + local interval = nil + interval = game:oninterval(function() + if (data.cancelled()) then + interval:clear() + return + end - if (data.done()) then - interval:clear() - data.callback() - end - end, data.interval) - return interval + if (data.done()) then + interval:clear() + data.callback() + end + end, data.interval) + return interval end function isupdatecancelled() - return updatecancelled + return updatecancelled end function tryupdate(autoclose) - updatecancelled = false - local popup = updaterpopup(function() - updater.cancelupdate() - updatecancelled = true - end) + updatecancelled = false + local popup = updaterpopup(function() + updater.cancelupdate() + updatecancelled = true + end) - startupdatecheck(popup, autoclose) + startupdatecheck(popup, autoclose) end function tryautoupdate() - if (not updater.autoupdatesenabled()) then - return - end + if (not updater.autoupdatesenabled()) then + return + end - if (not updater.gethastriedupdate()) then - game:ontimeout(function() - updater.sethastriedupdate(true) - tryupdate(true) - end, 100) - end + if (not updater.gethastriedupdate()) then + game:ontimeout(function() + updater.sethastriedupdate(true) + tryupdate(true) + end, 100) + end end LUI.tryupdating = tryupdate -LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file +LUI.onmenuopen("main_lockout", tryautoupdate) From 51d04f1cd304811a6b3d70b96561992cef9fe9e7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 01:26:41 +0100 Subject: [PATCH 34/52] Small fix --- data/ui_scripts/settings/__init__.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/ui_scripts/settings/__init__.lua b/data/ui_scripts/settings/__init__.lua index 0facce7f..00cd8125 100644 --- a/data/ui_scripts/settings/__init__.lua +++ b/data/ui_scripts/settings/__init__.lua @@ -63,7 +63,7 @@ LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) LUI.Options.CreateOptionButton( menu, - "cg_autoUpdate", + "cg_auto_update", "@LUA_MENU_AUTO_UPDATE", "Enable or disable automatic updates on startup.", { From 6b2cf9df0e3ac368cc6601ab3dc133c140aa93e6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 19:40:15 +0100 Subject: [PATCH 35/52] Don't always release custom assets --- src/client/component/mods.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index ae78b9e7..117cd3e7 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -19,10 +19,16 @@ namespace mods { utils::hook::detour db_release_xassets_hook; + bool release_assets = false; + void db_release_xassets_stub() { - materials::clear(); - fonts::clear(); + if (release_assets) + { + materials::clear(); + fonts::clear(); + } + db_release_xassets_hook.invoke(); } @@ -30,7 +36,9 @@ namespace mods { scheduler::once([]() { + release_assets = true; game::Com_Shutdown(""); + release_assets = false; }, scheduler::pipeline::main); } } From d6900f2af6906ed812a9b157f7049b58a4924b1c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 20 Mar 2022 19:51:29 +0100 Subject: [PATCH 36/52] Small scripting changes --- src/client/component/scripting.cpp | 32 +++++++++++++----------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index b876c479..491341d6 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -25,7 +25,8 @@ namespace scripting utils::hook::detour vm_notify_hook; utils::hook::detour g_shutdown_game_hook; - utils::hook::detour player_spawn_hook; + utils::hook::detour client_spawn_hook; + utils::hook::detour sv_check_load_level_hook; utils::hook::detour scr_add_class_field_hook; @@ -55,9 +56,9 @@ namespace scripting vm_notify_hook.invoke(notify_list_owner_id, string_value, top); } - void player_spawn_stub(const game::gentity_s* player) + void client_spawn_stub(const game::gentity_s* client) { - player_spawn_hook.invoke(player); + client_spawn_hook.invoke(client); lua::engine::start(); } @@ -67,16 +68,16 @@ namespace scripting g_shutdown_game_hook.invoke(free_scripts); } - void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) + void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t name, unsigned int canonicalString, unsigned int offset) { - const auto name = game::SL_ConvertToString(_name); + const auto name_ = game::SL_ConvertToString(name); - if (fields_table[classnum].find(name) == fields_table[classnum].end()) + if (fields_table[classnum].find(name_) == fields_table[classnum].end()) { - fields_table[classnum][name] = offset; + fields_table[classnum][name_] = offset; } - scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); + scr_add_class_field_hook.invoke(classnum, name, canonicalString, offset); } void process_script_stub(const char* filename) @@ -99,11 +100,10 @@ namespace scripting scr_set_thread_position_hook.invoke(threadName, codePos); } - utils::hook::detour sub_6B2940_hook; - char sub_6B2940_stub(void* a1) + char sv_check_load_level_stub(void* save_game) { - const auto result = sub_6B2940_hook.invoke(a1); - if (a1 != nullptr) + const auto result = sv_check_load_level_hook.invoke(save_game); + if (save_game != nullptr) { lua::engine::start(); } @@ -119,17 +119,13 @@ namespace scripting vm_notify_hook.create(0x1405CC450, vm_notify_stub); g_shutdown_game_hook.create(0x1404CBAD0, g_shutdown_game_stub); - player_spawn_hook.create(0x1404B0710, player_spawn_stub); + client_spawn_hook.create(0x1404B0710, client_spawn_stub); + sv_check_load_level_hook.create(0x1406B2940, sv_check_load_level_stub); scr_add_class_field_hook.create(0x1405C2C30, scr_add_class_field_stub); scr_set_thread_position_hook.create(0x1405BC7E0, scr_set_thread_position_stub); process_script_hook.create(0x1405C6160, process_script_stub); - // Loading last checkpoint doesn't call spawn player again (player_spawn_hook) - // Not sure what this function does but `a1` is != nullptr when loading - // the last checkpoint so we need to start lua in this context - sub_6B2940_hook.create(0x1406B2940, sub_6B2940_stub); - scheduler::loop([]() { lua::engine::run_frame(); From ca72522988217bcd946c61ef758037a43d01f059 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Mon, 21 Mar 2022 10:39:24 +0100 Subject: [PATCH 37/52] Re-add json script --- src/client/game/ui_scripting/lua/context.cpp | 10 + src/client/resource.hpp | 2 + src/client/resource.rc | 2 + src/client/resources/json.lua | 388 +++++++++++++++++++ 4 files changed, 402 insertions(+) create mode 100644 src/client/resources/json.lua diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index a146787a..7d9b73cf 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -27,6 +27,8 @@ namespace ui_scripting::lua { namespace { + const auto json_script = utils::nt::load_resource(LUA_JSON); + scripting::script_value script_convert(const sol::lua_value& value) { if (value.is()) @@ -95,6 +97,13 @@ namespace ui_scripting::lua state["io"]["readfile"] = static_cast(utils::io::read_file); } + void setup_json(sol::state& state) + { + const auto json = state.safe_script(json_script, &sol::script_pass_on_error); + handle_error(json); + state["json"] = json; + } + void setup_vector_type(sol::state& state) { auto vector_type = state.new_usertype("vector", sol::constructors()); @@ -600,6 +609,7 @@ namespace ui_scripting::lua sol::lib::table); setup_io(this->state_); + setup_json(this->state_); setup_vector_type(this->state_); setup_game_type(this->state_, this->event_handler_, this->scheduler_); setup_lui_types(this->state_, this->event_handler_, this->scheduler_); diff --git a/src/client/resource.hpp b/src/client/resource.hpp index 0a6f027a..b6a905e4 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -10,3 +10,5 @@ #define LUI_COMMON 303 #define LUI_UPDATER 304 + +#define LUA_JSON 305 diff --git a/src/client/resource.rc b/src/client/resource.rc index 1b9843d6..26d8709b 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -100,6 +100,8 @@ MENU_MAIN RCDATA "resources/main.html" LUI_COMMON RCDATA "resources/ui_scripts/common.lua" LUI_UPDATER RCDATA "resources/ui_scripts/updater.lua" +LUA_JSON RCDATA "resources/json.lua" + #ifdef _DEBUG TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll" #else diff --git a/src/client/resources/json.lua b/src/client/resources/json.lua new file mode 100644 index 00000000..711ef786 --- /dev/null +++ b/src/client/resources/json.lua @@ -0,0 +1,388 @@ +-- +-- json.lua +-- +-- Copyright (c) 2020 rxi +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. +-- + +local json = { _version = "0.1.2" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\", + [ "\"" ] = "\"", + [ "\b" ] = "b", + [ "\f" ] = "f", + [ "\n" ] = "n", + [ "\r" ] = "r", + [ "\t" ] = "t", +} + +local escape_char_map_inv = { [ "/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then + error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +------------------------------------------------------------------------------- +-- Decode +------------------------------------------------------------------------------- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do + res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do + if set[str:sub(i, i)] ~= negate then + return i + end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do + col_count = col_count + 1 + if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 + end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa + local f = math.floor + if n <= 0x7f then + return string.char(n) + elseif n <= 0x7ff then + return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0xffff then + return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10ffff then + return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, + f(n % 4096 / 64) + 128, n % 64 + 128) + end + error( string.format("invalid unicode codepoint '%x'", n) ) +end + + +local function parse_unicode_escape(s) + local n1 = tonumber( s:sub(1, 4), 16 ) + local n2 = tonumber( s:sub(7, 10), 16 ) + -- Surrogate pair? + if n2 then + return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) + else + return codepoint_to_utf8(n1) + end +end + + +local function parse_string(str, i) + local res = "" + local j = i + 1 + local k = j + + while j <= #str do + local x = str:byte(j) + + if x < 32 then + decode_error(str, j, "control character in string") + + elseif x == 92 then -- `\`: Escape + res = res .. str:sub(k, j - 1) + j = j + 1 + local c = str:sub(j, j) + if c == "u" then + local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") + res = res .. parse_unicode_escape(hex) + j = j + #hex + else + if not escape_chars[c] then + decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") + end + res = res .. escape_char_map_inv[c] + end + k = j + 1 + + elseif x == 34 then -- `"`: End of string + res = res .. str:sub(k, j - 1) + return res, j + 1 + end + + j = j + 1 + end + + decode_error(str, i, "expected closing quote for string") +end + + +local function parse_number(str, i) + local x = next_char(str, i, delim_chars) + local s = str:sub(i, x - 1) + local n = tonumber(s) + if not n then + decode_error(str, i, "invalid number '" .. s .. "'") + end + return n, x +end + + +local function parse_literal(str, i) + local x = next_char(str, i, delim_chars) + local word = str:sub(i, x - 1) + if not literals[word] then + decode_error(str, i, "invalid literal '" .. word .. "'") + end + return literal_map[word], x +end + + +local function parse_array(str, i) + local res = {} + local n = 1 + i = i + 1 + while 1 do + local x + i = next_char(str, i, space_chars, true) + -- Empty / end of array? + if str:sub(i, i) == "]" then + i = i + 1 + break + end + -- Read token + x, i = parse(str, i) + res[n] = x + n = n + 1 + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "]" then break end + if chr ~= "," then decode_error(str, i, "expected ']' or ','") end + end + return res, i +end + + +local function parse_object(str, i) + local res = {} + i = i + 1 + while 1 do + local key, val + i = next_char(str, i, space_chars, true) + -- Empty / end of object? + if str:sub(i, i) == "}" then + i = i + 1 + break + end + -- Read key + if str:sub(i, i) ~= '"' then + decode_error(str, i, "expected string for key") + end + key, i = parse(str, i) + -- Read ':' delimiter + i = next_char(str, i, space_chars, true) + if str:sub(i, i) ~= ":" then + decode_error(str, i, "expected ':' after key") + end + i = next_char(str, i + 1, space_chars, true) + -- Read value + val, i = parse(str, i) + -- Set + res[key] = val + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "}" then break end + if chr ~= "," then decode_error(str, i, "expected '}' or ','") end + end + return res, i +end + + +local char_func_map = { + [ '"' ] = parse_string, + [ "0" ] = parse_number, + [ "1" ] = parse_number, + [ "2" ] = parse_number, + [ "3" ] = parse_number, + [ "4" ] = parse_number, + [ "5" ] = parse_number, + [ "6" ] = parse_number, + [ "7" ] = parse_number, + [ "8" ] = parse_number, + [ "9" ] = parse_number, + [ "-" ] = parse_number, + [ "t" ] = parse_literal, + [ "f" ] = parse_literal, + [ "n" ] = parse_literal, + [ "[" ] = parse_array, + [ "{" ] = parse_object, +} + + +parse = function(str, idx) + local chr = str:sub(idx, idx) + local f = char_func_map[chr] + if f then + return f(str, idx) + end + decode_error(str, idx, "unexpected character '" .. chr .. "'") +end + + +function json.decode(str) + if type(str) ~= "string" then + error("expected argument of type string, got " .. type(str)) + end + local res, idx = parse(str, next_char(str, 1, space_chars, true)) + idx = next_char(str, idx, space_chars, true) + if idx <= #str then + decode_error(str, idx, "trailing garbage") + end + return res +end + + +return json From 0938e5450d6656a57b7bc9e61b6565e52c21f204 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Mon, 21 Mar 2022 10:41:59 +0100 Subject: [PATCH 38/52] Small fix --- src/client/component/gui.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client/component/gui.cpp b/src/client/component/gui.cpp index d4852c7c..f8187cbe 100644 --- a/src/client/component/gui.cpp +++ b/src/client/component/gui.cpp @@ -313,8 +313,11 @@ namespace gui void pre_destroy() override { - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); + if (initialized) + { + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + } } }; } From b1c69e74b7dec42411f63157c7e7faefaf4e34a6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 21 Mar 2022 18:39:51 +0100 Subject: [PATCH 39/52] Small fix + cleanup --- src/client/component/mods.cpp | 18 ++++++++++-------- src/client/component/mods.hpp | 6 ++++++ src/client/game/game.cpp | 2 -- src/client/game/game.hpp | 2 -- src/client/game/ui_scripting/lua/context.cpp | 3 ++- 5 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 src/client/component/mods.hpp diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index 117cd3e7..dd5404bb 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -9,16 +9,18 @@ #include "filesystem.hpp" #include "materials.hpp" #include "fonts.hpp" +#include "mods.hpp" #include #include namespace mods { + std::string mod_path{}; + namespace { utils::hook::detour db_release_xassets_hook; - bool release_assets = false; void db_release_xassets_stub() @@ -71,22 +73,22 @@ namespace mods } const auto path = params.get(1); - game_console::print(game_console::con_type_info, "Loading mod %s\n", path); - if (!utils::io::directory_exists(path)) { game_console::print(game_console::con_type_error, "Mod %s not found!\n", path); return; } + game_console::print(game_console::con_type_info, "Loading mod %s\n", path); + filesystem::get_search_paths().erase(mod_path); filesystem::get_search_paths().insert(path); - game::mod_folder = path; + mod_path = path; restart(); }); command::add("unloadmod", [](const command::params& params) { - if (game::mod_folder.empty()) + if (mod_path.empty()) { game_console::print(game_console::con_type_info, "No mod loaded\n"); return; @@ -99,9 +101,9 @@ namespace mods return; } - game_console::print(game_console::con_type_info, "Unloading mod %s\n", game::mod_folder.data()); - filesystem::get_search_paths().erase(game::mod_folder); - game::mod_folder.clear(); + game_console::print(game_console::con_type_info, "Unloading mod %s\n", mod_path.data()); + filesystem::get_search_paths().erase(mod_path); + mod_path.clear(); restart(); }); } diff --git a/src/client/component/mods.hpp b/src/client/component/mods.hpp new file mode 100644 index 00000000..364a2f11 --- /dev/null +++ b/src/client/component/mods.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace mods +{ + extern std::string mod_path; +} \ No newline at end of file diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index e4c8dccd..b94b6a23 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,8 +3,6 @@ namespace game { - std::string mod_folder{}; - namespace environment { launcher::mode mode = launcher::mode::none; diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 4da1c52d..cad966e5 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -5,8 +5,6 @@ namespace game { - extern std::string mod_folder; - namespace environment { launcher::mode get_mode(); diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 7d9b73cf..e568e674 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -12,6 +12,7 @@ #include "../../../component/fastfiles.hpp" #include "../../../component/updater.hpp" #include "../../../component/localized_strings.hpp" +#include "../../../component/mods.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -434,7 +435,7 @@ namespace ui_scripting::lua game_type["getloadedmod"] = [](const game&) { - return ::game::mod_folder; + return mods::mod_path; }; game_type["addlocalizedstring"] = [](const game&, const std::string& string, From 40f277abfd0186d996e732c450e137ff216c6366 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 21 Mar 2022 21:48:22 +0100 Subject: [PATCH 40/52] Hopefully fix event_handler --- .../game/scripting/lua/event_handler.cpp | 28 ++++++++++--------- .../game/scripting/lua/event_handler.hpp | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index b57b1250..d433fd18 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -33,29 +33,31 @@ namespace scripting::lua this->merge_callbacks(); this->handle_endon_conditions(event); - for (auto i = 0; i < tasks.size();) + for (auto i = tasks.begin(); i != tasks.end();) { - const auto task = tasks[i]; - if (task.event != event.name || task.entity != event.entity) + if (i->is_deleted) + { + i = tasks.erase(i); + continue; + } + + if (i->event != event.name || i->entity != event.entity) { ++i; continue; } - if (!task.is_deleted) + if (!has_built_arguments) { - if (!has_built_arguments) - { - has_built_arguments = true; - arguments = this->build_arguments(event); - } - - handle_error(task.callback(sol::as_args(arguments))); + has_built_arguments = true; + arguments = this->build_arguments(event); } - if (task.is_volatile || task.is_deleted) + handle_error(i->callback(sol::as_args(arguments))); + + if (i->is_volatile || i->is_deleted) { - tasks.erase(tasks.begin() + i); + i = tasks.erase(i); } else { diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp index 981392e7..99009017 100644 --- a/src/client/game/scripting/lua/event_handler.hpp +++ b/src/client/game/scripting/lua/event_handler.hpp @@ -44,7 +44,7 @@ namespace scripting::lua sol::state& state_; std::atomic_int64_t current_listener_id_ = 0; - using task_list = std::vector; + using task_list = std::list; utils::concurrency::container new_callbacks_; utils::concurrency::container callbacks_; From cc4c8b242d4fa6a9bf7f264fe5c23bb35db3ca37 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Mon, 21 Mar 2022 21:56:29 +0100 Subject: [PATCH 41/52] Update README [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 092913b2..9a5b352c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![open bugs](https://img.shields.io/github/issues/fedddddd/h2-mod/bug?label=bugs)](https://github.com/fedddddd/h2-mod/issues?q=is%3Aissue+is%3Aopen+label%3Abug) [![Build](https://github.com/fedddddd/h2-mod/workflows/Build/badge.svg)](https://github.com/fedddddd/h2-mod/actions) [![Build status](https://ci.appveyor.com/api/projects/status/0sh80kdnsvm53rno?svg=true)](https://ci.appveyor.com/project/fedddddd/h2-mod) - +[![Discord](https://img.shields.io/discord/955362057581129738?color=%237289DA&label=members&logo=discord&logoColor=%23FFFFFF)](https://discord.gg/dpnRn2tKT9) # H2: Mod

From 6f0c52a4316abf0e8a924a0c72454322b4b58a56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 22:26:21 +0000 Subject: [PATCH 42/52] Bump deps/protobuf from `46c3651` to `a69354f` Bumps [deps/protobuf](https://github.com/google/protobuf) from `46c3651` to `a69354f`. - [Release notes](https://github.com/google/protobuf/releases) - [Commits](https://github.com/google/protobuf/compare/46c3651c315cf77f1bcf5ad662074f04f095a04a...a69354f31b253856689ae765a9ea3217ec001873) --- updated-dependencies: - dependency-name: deps/protobuf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/protobuf b/deps/protobuf index 46c3651c..a69354f3 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 46c3651c315cf77f1bcf5ad662074f04f095a04a +Subproject commit a69354f31b253856689ae765a9ea3217ec001873 From c9542f38e63229a333b2fc0604551ea6d8a06ac7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 22:26:25 +0000 Subject: [PATCH 43/52] Bump deps/curl from `c20a516` to `bdc664a` Bumps [deps/curl](https://github.com/curl/curl) from `c20a516` to `bdc664a`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/c20a516d03165c4d047fd79edd109a07f8a3f543...bdc664a64002a7df66f34159454844e6b6f5515f) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index c20a516d..bdc664a6 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit c20a516d03165c4d047fd79edd109a07f8a3f543 +Subproject commit bdc664a64002a7df66f34159454844e6b6f5515f From 9be3eb5d1ac4d5c65cbb7d983649ab1dc10a903d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 22:26:27 +0000 Subject: [PATCH 44/52] Bump deps/asmjit from `f1a399c` to `21a31b8` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `f1a399c` to `21a31b8`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/f1a399c4fe74d1535a4190a2b8727c51045cc914...21a31b8a338da3341d2b423f85913597b8ec3d63) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index f1a399c4..21a31b8a 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit f1a399c4fe74d1535a4190a2b8727c51045cc914 +Subproject commit 21a31b8a338da3341d2b423f85913597b8ec3d63 From d88a48b6669af4e675f1e65547fe13b2f5c71e2d Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 22 Mar 2022 20:27:20 +0100 Subject: [PATCH 45/52] Use builtin LUI event handler + fixes --- generate.bat | 3 +- src/client/component/input.cpp | 14 +++- src/client/component/ui_scripting.cpp | 23 +++--- src/client/component/ui_scripting.hpp | 2 - src/client/game/symbols.hpp | 9 +++ src/client/game/ui_scripting/execution.cpp | 72 ++++++++++++++++--- src/client/game/ui_scripting/execution.hpp | 2 + src/client/game/ui_scripting/lua/context.cpp | 63 +++++----------- src/client/game/ui_scripting/lua/context.hpp | 1 - src/client/game/ui_scripting/lua/engine.cpp | 42 ----------- src/client/game/ui_scripting/lua/engine.hpp | 3 - src/client/game/ui_scripting/script_value.hpp | 1 + src/client/game/ui_scripting/types.cpp | 34 +++++++++ src/client/game/ui_scripting/types.hpp | 24 +++++++ 14 files changed, 173 insertions(+), 120 deletions(-) diff --git a/generate.bat b/generate.bat index 8d2b86a4..06c74119 100644 --- a/generate.bat +++ b/generate.bat @@ -1,4 +1,3 @@ @echo off git submodule update --init --recursive -tools\premake5 %* vs2022 -pause \ No newline at end of file +tools\premake5 %* vs2022 \ No newline at end of file diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index a890cf43..7b14cc46 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -6,6 +6,7 @@ #include "game_console.hpp" #include "gui.hpp" #include "game/ui_scripting/lua/engine.hpp" +#include "game/ui_scripting/execution.hpp" #include @@ -25,7 +26,11 @@ namespace input void cl_char_event_stub(const int local_client_num, const int key) { - ui_scripting::lua::engine::ui_event("char", {key}); + ui_scripting::notify("keypress", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); if (!game_console::console_char_event(local_client_num, key)) { @@ -42,7 +47,11 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { - ui_scripting::lua::engine::ui_event("key", {key, down}); + ui_scripting::notify(down ? "keydown" : "keyup", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); if (!game_console::console_key_event(local_client_num, key, down)) { @@ -64,7 +73,6 @@ namespace input return; } - ui_scripting::lua::engine::ui_event("mousemove", {x, y}); cl_mouse_move_hook.invoke(local_client_num, x, y); } } diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index f6cdba10..862277e7 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -30,8 +30,9 @@ namespace ui_scripting utils::hook::detour hks_allocator_hook; utils::hook::detour lui_error_hook; utils::hook::detour hksi_hks_error_hook; + utils::hook::detour hks_frame_hook; - bool error_hook_enabled = false; + int error_hook_enabled = 0; void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) { @@ -107,6 +108,15 @@ namespace ui_scripting return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); } + + void hks_frame_stub() + { + const auto state = *game::hks::lua_state; + if (state) + { + ui_scripting::lua::engine::run_frame(); + } + } } int main_function_handler(game::hks::lua_State* state) @@ -158,17 +168,12 @@ namespace ui_scripting void enable_error_hook() { - error_hook_enabled = true; + error_hook_enabled++; } void disable_error_hook() { - error_hook_enabled = false; - } - - void notify(const event& e) - { - lua::engine::notify(e); + error_hook_enabled--; } class component final : public component_interface @@ -177,7 +182,7 @@ namespace ui_scripting void post_unpack() override { - scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui); + hks_frame_hook.create(0x140327880, hks_frame_stub); hks_start_hook.create(0x140328BE0, hks_start_stub); hks_shutdown_hook.create(0x1403203B0, hks_shutdown_stub); hksi_lual_error_hook.create(0x1402E3E40, hksi_lual_error_stub); diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp index 8831d39d..417619fe 100644 --- a/src/client/component/ui_scripting.hpp +++ b/src/client/component/ui_scripting.hpp @@ -10,6 +10,4 @@ namespace ui_scripting void enable_error_hook(); void disable_error_hook(); - - void notify(const event& e); } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 920ab7d2..6a885aa0 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -86,6 +86,10 @@ namespace game WEAK symbol Key_KeynumToString{0x1403D32D0}; WEAK symbol LUI_OpenMenu{0x1405F0EE0}; + WEAK symbol LUI_BeginEvent{0x1403155E0}; + WEAK symbol LUI_EndEvent{0x140316890}; + WEAK symbol LUI_EnterCriticalSection{0x140316980}; + WEAK symbol LUI_LeaveCriticalSection{0x14031BC20}; WEAK symbol Menu_IsMenuOpenAndVisible{0x1405EE1A0}; WEAK symbol Material_RegisterHandle{0x140759BA0}; @@ -135,6 +139,8 @@ namespace game WEAK symbol Sys_IsDatabaseReady2{0x1405A9FE0}; WEAK symbol Sys_Milliseconds{0x140650720}; WEAK symbol Sys_IsMainThread{0x1405AA020}; + WEAK symbol Sys_EnterCriticalSection{0x140624240}; + WEAK symbol Sys_LeaveCriticalSection{0x1406242C0}; WEAK symbol UI_SafeTranslateString{0x1405A2930}; WEAK symbol UI_PlayLocalSoundAlias{0x140606080}; @@ -202,5 +208,8 @@ namespace game int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x1402C84B0}; WEAK symbol hksi_luaL_ref{0x1402E4520}; WEAK symbol hksi_luaL_unref{0x1402DCE50}; + WEAK symbol hksi_lua_setfield{0x1402DEA30}; + WEAK symbol hksi_lua_pcall{0x1402DDE50}; + WEAK symbol closePendingUpvalues{0x1402CBAD0}; } } \ No newline at end of file diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp index fff6b88e..fe6e3f7a 100644 --- a/src/client/game/ui_scripting/execution.cpp +++ b/src/client/game/ui_scripting/execution.cpp @@ -37,38 +37,79 @@ namespace ui_scripting return values; } + bool notify(const std::string& name, const event_arguments& arguments) + { + const auto state = *game::hks::lua_state; + if (!state) + { + return false; + } + + const auto _1 = gsl::finally(game::LUI_LeaveCriticalSection); + game::LUI_EnterCriticalSection(); + + try + { + const auto globals = table((*::game::hks::lua_state)->globals.v.table); + const auto engine = globals.get("Engine").as(); + const auto root = engine.get("GetLuiRoot").as().call({})[0].as(); + const auto process_event = root.get("processEvent").as(); + + table event{}; + event.set("name", name); + + for (const auto& arg : arguments) + { + event.set(arg.first, arg.second); + } + + process_event.call({root, event}); + return true; + } + catch (const std::exception& e) + { + printf("Error processing event '%s' %s\n", name.data(), e.what()); + return false; + } + } + arguments call_script_function(const function& function, const arguments& arguments) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(function); for (auto i = arguments.begin(); i != arguments.end(); ++i) { push_value(*i); } + const auto num_args = static_cast(arguments.size()); + stack.save(num_args + 1); + const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); try { - game::hks::vm_call_internal(state, static_cast(arguments.size()), -1, 0); + game::hks::vm_call_internal(state, num_args, -1, 0); const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); return get_return_values(count); } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error executing script function: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error executing script function: "s + e.what()); } } script_value get_field(const userdata& self, const script_value& key) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(key); + stack.save(1); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -85,16 +126,18 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error getting userdata field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error getting userdata field: "s + e.what()); } } script_value get_field(const table& self, const script_value& key) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(key); + stack.save(1); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -111,14 +154,17 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error getting table field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error getting table field: "s + e.what()); } } void set_field(const userdata& self, const script_value& key, const script_value& value) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + + stack stack; + stack.save(0); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -133,14 +179,17 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error setting userdata field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error setting userdata field: "s + e.what()); } } void set_field(const table& self, const script_value& key, const script_value& value) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + + stack stack; + stack.save(0); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -155,7 +204,8 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error setting table field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error setting table field: "s + e.what()); } } } diff --git a/src/client/game/ui_scripting/execution.hpp b/src/client/game/ui_scripting/execution.hpp index 24f4dd72..4a3d3562 100644 --- a/src/client/game/ui_scripting/execution.hpp +++ b/src/client/game/ui_scripting/execution.hpp @@ -9,6 +9,8 @@ namespace ui_scripting script_value get_return_value(int offset); arguments get_return_values(int count); + bool notify(const std::string& name, const event_arguments& arguments); + arguments call_script_function(const function& function, const arguments& arguments); script_value get_field(const userdata& self, const script_value& key); diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index e568e674..0e5d831c 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -210,7 +210,7 @@ namespace ui_scripting::lua }; } - void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler) + void setup_game_type(sol::state& state, scheduler& scheduler) { struct game { @@ -246,28 +246,6 @@ namespace ui_scripting::lua return scheduler.add(callback, milliseconds, false); }; - game_type["onnotify"] = [&handler](const game&, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.event = event; - listener.is_volatile = false; - - return handler.add_event_listener(std::move(listener)); - }; - - game_type["onnotifyonce"] = [&handler](const game&, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.event = event; - listener.is_volatile = true; - - return handler.add_event_listener(std::move(listener)); - }; - game_type["isingame"] = []() { return ::game::CL_IsCgameInitialized() && ::game::g_entities[0].client; @@ -478,7 +456,7 @@ namespace ui_scripting::lua }; } - void setup_lui_types(sol::state& state, event_handler& handler, scheduler& scheduler) + void setup_lui_types(sol::state& state) { auto userdata_type = state.new_usertype("userdata_"); @@ -494,15 +472,15 @@ namespace ui_scripting::lua ); userdata_type[sol::meta_function::index] = [](const userdata& userdata, const sol::this_state s, - const std::string& name) + const sol::lua_value& key) { - return convert(s, userdata.get(name)); + return convert(s, userdata.get(convert({s, key}))); }; userdata_type[sol::meta_function::new_index] = [](const userdata& userdata, const sol::this_state s, - const std::string& name, const sol::lua_value& value) + const sol::lua_value& key, const sol::lua_value& value) { - userdata.set(name, convert({s, value})); + userdata.set(convert({s, key}), convert({s, value})); }; auto table_type = state.new_usertype
("table_"); @@ -519,27 +497,27 @@ namespace ui_scripting::lua ); table_type["get"] = [](const table& table, const sol::this_state s, - const std::string& name) + const sol::lua_value& key) { - return convert(s, table.get(name)); + return convert(s, table.get(convert({s, key}))); }; table_type["set"] = [](const table& table, const sol::this_state s, - const std::string& name, const sol::lua_value& value) + const sol::lua_value& key, const sol::lua_value& value) { - table.set(name, convert({s, value})); + table.set(convert({s, key}), convert({s, value})); }; table_type[sol::meta_function::index] = [](const table& table, const sol::this_state s, - const std::string& name) + const sol::lua_value& key) { - return convert(s, table.get(name)); + return convert(s, table.get(convert({s, key}))); }; table_type[sol::meta_function::new_index] = [](const table& table, const sol::this_state s, - const std::string& name, const sol::lua_value& value) + const sol::lua_value& key, const sol::lua_value& value) { - table.set(name, convert({s, value})); + table.set(convert({s, key}), convert({s, value})); }; auto function_type = state.new_usertype("function_"); @@ -598,8 +576,6 @@ namespace ui_scripting::lua context::context(std::string data, script_type type) : scheduler_(state_) - , event_handler_(state_) - { this->state_.open_libraries(sol::lib::base, sol::lib::package, @@ -612,8 +588,8 @@ namespace ui_scripting::lua setup_io(this->state_); setup_json(this->state_); setup_vector_type(this->state_); - setup_game_type(this->state_, this->event_handler_, this->scheduler_); - setup_lui_types(this->state_, this->event_handler_, this->scheduler_); + setup_game_type(this->state_, this->scheduler_); + setup_lui_types(this->state_); if (type == script_type::file) { @@ -650,7 +626,6 @@ namespace ui_scripting::lua { this->state_.collect_garbage(); this->scheduler_.clear(); - this->event_handler_.clear(); this->state_ = {}; } @@ -660,12 +635,6 @@ namespace ui_scripting::lua this->state_.collect_garbage(); } - void context::notify(const event& e) - { - this->scheduler_.dispatch(e); - this->event_handler_.dispatch(e); - } - void context::load_script(const std::string& script) { if (!this->loaded_scripts_.emplace(script).second) diff --git a/src/client/game/ui_scripting/lua/context.hpp b/src/client/game/ui_scripting/lua/context.hpp index 22c27e35..5ad4fb7c 100644 --- a/src/client/game/ui_scripting/lua/context.hpp +++ b/src/client/game/ui_scripting/lua/context.hpp @@ -41,7 +41,6 @@ namespace ui_scripting::lua std::unordered_set loaded_scripts_; scheduler scheduler_; - event_handler event_handler_; void load_script(const std::string& script); }; diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 304fb761..d6dbfe8d 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -17,27 +17,6 @@ namespace ui_scripting::lua::engine const auto lui_common = utils::nt::load_resource(LUI_COMMON); const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); - void handle_key_event(const int key, const int down) - { - event event; - event.name = down - ? "keydown" - : "keyup"; - event.arguments = {key}; - - engine::notify(event); - } - - void handle_char_event(const int key) - { - std::string key_str = {(char)key}; - event event; - event.name = "keypress"; - event.arguments = {key_str}; - - engine::notify(event); - } - auto& get_scripts() { static std::vector> scripts{}; @@ -88,27 +67,6 @@ namespace ui_scripting::lua::engine get_scripts().clear(); } - void ui_event(const std::string& type, const std::vector& arguments) - { - if (type == "key") - { - handle_key_event(arguments[0], arguments[1]); - } - - if (type == "char") - { - handle_char_event(arguments[0]); - } - } - - void notify(const event& e) - { - for (auto& script : get_scripts()) - { - script->notify(e); - } - } - void run_frame() { for (auto& script : get_scripts()) diff --git a/src/client/game/ui_scripting/lua/engine.hpp b/src/client/game/ui_scripting/lua/engine.hpp index 27c5123e..e098f192 100644 --- a/src/client/game/ui_scripting/lua/engine.hpp +++ b/src/client/game/ui_scripting/lua/engine.hpp @@ -6,8 +6,5 @@ namespace ui_scripting::lua::engine { void start(); void stop(); - - void ui_event(const std::string&, const std::vector&); - void notify(const event& e); void run_frame(); } diff --git a/src/client/game/ui_scripting/script_value.hpp b/src/client/game/ui_scripting/script_value.hpp index 4d5dfcc9..f2c08cff 100644 --- a/src/client/game/ui_scripting/script_value.hpp +++ b/src/client/game/ui_scripting/script_value.hpp @@ -56,4 +56,5 @@ namespace ui_scripting }; using arguments = std::vector; + using event_arguments = std::unordered_map; } diff --git a/src/client/game/ui_scripting/types.cpp b/src/client/game/ui_scripting/types.cpp index 732c978a..273ffc9d 100644 --- a/src/client/game/ui_scripting/types.cpp +++ b/src/client/game/ui_scripting/types.cpp @@ -273,4 +273,38 @@ namespace ui_scripting { return call_script_function(*this, arguments); } + + /*************************************************************** + * Stack + **************************************************************/ + + stack::stack() + { + this->state = *game::hks::lua_state; + this->state->m_apistack.top = this->state->m_apistack.base; + } + + void stack::save(int num_args) + { + this->num_args_ = num_args; + this->num_calls_ = state->m_numberOfCCalls; + this->base_bottom_ = state->m_apistack.base - state->m_apistack.bottom; + this->top_bottom_ = state->m_apistack.top - state->m_apistack.bottom; + this->callstack_ = state->m_callStack.m_current - state->m_callStack.m_records; + } + + void stack::fix() + { + this->state->m_numberOfCCalls = this->num_calls_; + + game::hks::closePendingUpvalues(this->state, &this->state->m_apistack.bottom[this->top_bottom_ - this->num_args_]); + this->state->m_callStack.m_current = &this->state->m_callStack.m_records[this->callstack_]; + + this->state->m_apistack.base = &this->state->m_apistack.bottom[this->base_bottom_]; + this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ - static_cast(this->num_args_ + 1)]; + + this->state->m_apistack.bottom[this->top_bottom_].t = this->state->m_apistack.top[-1].t; + this->state->m_apistack.bottom[this->top_bottom_].v.ptr = this->state->m_apistack.top[-1].v.ptr; + this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ + 1]; + } } \ No newline at end of file diff --git a/src/client/game/ui_scripting/types.hpp b/src/client/game/ui_scripting/types.hpp index 10f452f8..afb28fbd 100644 --- a/src/client/game/ui_scripting/types.hpp +++ b/src/client/game/ui_scripting/types.hpp @@ -86,4 +86,28 @@ namespace ui_scripting int ref{}; }; + + class stack final + { + public: + stack(); + + void save(int num_args); + void fix(); + + stack(stack&&) = delete; + stack(const stack&) = delete; + stack& operator=(stack&&) = delete; + stack& operator=(const stack&) = delete; + + private: + game::hks::lua_State* state; + + int num_args_; + int num_calls_; + + uint64_t base_bottom_; + uint64_t top_bottom_; + uint64_t callstack_; + }; } \ No newline at end of file From e649483ebd95331981d66a2a2c5a1bd1c304c70e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 22:19:13 +0000 Subject: [PATCH 46/52] Bump deps/GSL from `4377f6e` to `3837236` Bumps [deps/GSL](https://github.com/Microsoft/GSL) from `4377f6e` to `3837236`. - [Release notes](https://github.com/Microsoft/GSL/releases) - [Commits](https://github.com/Microsoft/GSL/compare/4377f6e603c64a86c934f1546aa9db482f2e1a4e...383723676cd548d615159701ac3d050f8dd1e128) --- updated-dependencies: - dependency-name: deps/GSL dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/GSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GSL b/deps/GSL index 4377f6e6..38372367 160000 --- a/deps/GSL +++ b/deps/GSL @@ -1 +1 @@ -Subproject commit 4377f6e603c64a86c934f1546aa9db482f2e1a4e +Subproject commit 383723676cd548d615159701ac3d050f8dd1e128 From 1a8b9fba61f121b196dda6b99919c071fa232f84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Mar 2022 22:33:01 +0000 Subject: [PATCH 47/52] Bump deps/imgui from `fc84214` to `22e9093` Bumps [deps/imgui](https://github.com/fedddddd/imgui) from `fc84214` to `22e9093`. - [Release notes](https://github.com/fedddddd/imgui/releases) - [Commits](https://github.com/fedddddd/imgui/compare/fc84214988b74179b3941d35393c24ee8ba7a794...22e9093da37f0443f008b947caa6221724e760d6) --- updated-dependencies: - dependency-name: deps/imgui dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/imgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/imgui b/deps/imgui index fc842149..22e9093d 160000 --- a/deps/imgui +++ b/deps/imgui @@ -1 +1 @@ -Subproject commit fc84214988b74179b3941d35393c24ee8ba7a794 +Subproject commit 22e9093da37f0443f008b947caa6221724e760d6 From 66522d08977a20e7456d728cab744c02f45d56f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Mar 2022 22:33:13 +0000 Subject: [PATCH 48/52] Bump deps/curl from `bdc664a` to `8e22fc6` Bumps [deps/curl](https://github.com/curl/curl) from `bdc664a` to `8e22fc6`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/bdc664a64002a7df66f34159454844e6b6f5515f...8e22fc68e7dda43e9f0b6857b1057d0e9131a4b2) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index bdc664a6..8e22fc68 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit bdc664a64002a7df66f34159454844e6b6f5515f +Subproject commit 8e22fc68e7dda43e9f0b6857b1057d0e9131a4b2 From 85f1b38e81c155ac27195a83d4dd2026260d1dac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Mar 2022 22:19:05 +0000 Subject: [PATCH 49/52] Bump deps/curl from `8e22fc6` to `47048e0` Bumps [deps/curl](https://github.com/curl/curl) from `8e22fc6` to `47048e0`. - [Release notes](https://github.com/curl/curl/releases) - [Commits](https://github.com/curl/curl/compare/8e22fc68e7dda43e9f0b6857b1057d0e9131a4b2...47048e02878c59367db1d42813f32dcce543eed3) --- updated-dependencies: - dependency-name: deps/curl dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/curl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/curl b/deps/curl index 8e22fc68..47048e02 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 8e22fc68e7dda43e9f0b6857b1057d0e9131a4b2 +Subproject commit 47048e02878c59367db1d42813f32dcce543eed3 From 59ee7caf427f20adbac45428604d3584e516e466 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 27 Mar 2022 19:29:28 +0200 Subject: [PATCH 50/52] Cleanup --- src/client/component/chat.cpp | 95 --------------------- src/client/component/chat.hpp | 6 -- src/client/component/command.cpp | 10 +-- src/client/component/config.cpp | 24 ------ src/client/component/fps.cpp | 1 - src/client/component/gui_asset_list.cpp | 31 ++++--- src/client/component/gui_console.cpp | 17 ++-- src/client/component/gui_debug.cpp | 9 +- src/client/component/gui_entity_list.cpp | 10 ++- src/client/component/gui_script_console.cpp | 4 +- src/client/component/ui_scripting.cpp | 1 - src/client/component/updater.cpp | 10 --- src/client/game/scripting/lua/context.cpp | 4 +- 13 files changed, 41 insertions(+), 181 deletions(-) delete mode 100644 src/client/component/chat.cpp delete mode 100644 src/client/component/chat.hpp delete mode 100644 src/client/component/config.cpp diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp deleted file mode 100644 index 4520436a..00000000 --- a/src/client/component/chat.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "chat.hpp" -#include "scheduler.hpp" - -#include -#include - -#define chat_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25) - -namespace chat -{ - namespace - { - struct message - { - std::string text; - std::chrono::steady_clock::time_point time; - }; - - std::deque history; - - float color_white[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - float screen_max[2]; - - void check_resize() - { - screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0]; - screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1]; - } - - float relative(float value) - { - const auto ratio = screen_max[0] / 2560.f; - - return value * ratio; - } - - void draw_chat() - { - check_resize(); - - const auto now = std::chrono::high_resolution_clock::now(); - - for (auto i = 0; i < std::min(15, (int)history.size()); i++) - { - if (now - history[i].time > 11s) - { - return; - } - - const auto diff = now - history[i].time; - - float color[4] = { color_white[0], color_white[1], color_white[2], 1.f }; - - if (diff > 10.5s) - { - const auto milliseconds = (float)(11000 - std::chrono::duration_cast(diff).count()); - - color[3] = (float)(milliseconds / 500.f); - } - - game::R_AddCmdDrawText(history[i].text.data(), 0x7FFFFFFF, chat_font, relative(15.f), relative(600.f + i * 25), 1.f, 1.f, 0.f, color, 0); - } - } - } - - void print(const std::string& msg) - { - message m; - m.text = msg; - m.time = std::chrono::high_resolution_clock::now(); - - history.push_front(m); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - scheduler::loop([]() - { - draw_chat(); - }, scheduler::pipeline::renderer); - } - }; -} - -REGISTER_COMPONENT(chat::component) diff --git a/src/client/component/chat.hpp b/src/client/component/chat.hpp deleted file mode 100644 index d1428459..00000000 --- a/src/client/component/chat.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace chat -{ - void print(const std::string& msg); -} \ No newline at end of file diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index d5737946..6fba69f6 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -9,7 +9,6 @@ #include "command.hpp" #include "scheduler.hpp" #include "game_console.hpp" -#include "chat.hpp" #include "fastfiles.hpp" #include @@ -116,7 +115,9 @@ namespace command const auto command = utils::string::to_lower(name); if (handlers.find(command) == handlers.end()) + { add_raw(name, main_handler); + } handlers[command] = callback; } @@ -168,11 +169,6 @@ namespace command utils::hook::invoke(0x1406B3AA0, map, 0, 0, 0, 0); }); - add("say", [](const params& params) - { - chat::print(params.join(1)); - }); - add("listassetpool", [](const params& params) { if (params.size() < 2) @@ -408,7 +404,7 @@ namespace command try { - const scripting::entity player = scripting::call("getentbynum", {0}).as(); + const auto player = scripting::call("getentbynum", {0}).as(); if (weapon == "all"s) { player.call("takeallweapons"); diff --git a/src/client/component/config.cpp b/src/client/component/config.cpp deleted file mode 100644 index 26ecc7b6..00000000 --- a/src/client/component/config.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "command.hpp" -#include "game_console.hpp" - -#include - -namespace config -{ - class component final : public component_interface - { - public: - void post_unpack() override - { - dvars::register_bool("cg_autoUpdate", true, game::DvarFlags::DVAR_FLAG_SAVED); - } - }; -} - -REGISTER_COMPONENT(config::component) diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index e2761b29..8233908e 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -4,7 +4,6 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "chat.hpp" #include "scheduler.hpp" #include "command.hpp" diff --git a/src/client/component/gui_asset_list.cpp b/src/client/component/gui_asset_list.cpp index b8a02ef3..c4989191 100644 --- a/src/client/component/gui_asset_list.cpp +++ b/src/client/component/gui_asset_list.cpp @@ -22,32 +22,31 @@ namespace asset_list void on_frame() { - if (!gui::enabled_menus["asset_list"]) + static auto* enabled = &gui::enabled_menus["asset_list"]; + if (!*enabled) { return; } + ImGui::Begin("Asset list", enabled); + + ImGui::InputText("asset type", &asset_type_filter); + ImGui::BeginChild("asset type list"); + + for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) { - ImGui::Begin("Asset list", &gui::enabled_menus["asset_list"]); + const auto name = game::g_assetNames[i]; + const auto type = static_cast(i); - ImGui::InputText("asset type", &asset_type_filter); - ImGui::BeginChild("asset type list"); - - for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) + if (utils::string::find_lower(name, asset_type_filter)) { - const auto name = game::g_assetNames[i]; - const auto type = static_cast(i); - - if (utils::string::find_lower(name, asset_type_filter)) - { - ImGui::Checkbox(name, &shown_assets[type]); - } + ImGui::Checkbox(name, &shown_assets[type]); } - - ImGui::EndChild(); - ImGui::End(); } + ImGui::EndChild(); + ImGui::End(); + for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) { const auto name = game::g_assetNames[i]; diff --git a/src/client/component/gui_console.cpp b/src/client/component/gui_console.cpp index 452bf557..13943c7a 100644 --- a/src/client/component/gui_console.cpp +++ b/src/client/component/gui_console.cpp @@ -13,7 +13,7 @@ #include #include -namespace gui_console +namespace gui::console { namespace { @@ -52,7 +52,7 @@ namespace gui_console } case ImGuiInputTextFlags_CallbackHistory: { - const auto history = game_console::get_history(); + const auto& history = game_console::get_history(); if (data->EventKey == ImGuiKey_UpArrow) { @@ -96,7 +96,7 @@ namespace gui_console { std::string text{}; - const auto output = game_console::get_output(); + const auto& output = game_console::get_output(); for (const auto& line : output) { if (utils::string::find_lower(line, filter)) @@ -116,7 +116,8 @@ namespace gui_console void on_frame() { - if (!gui::enabled_menus["console"]) + static auto* enabled = &gui::enabled_menus["console"]; + if (!*enabled) { return; } @@ -126,7 +127,7 @@ namespace gui_console static const auto input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; - ImGui::Begin("Console", &gui::enabled_menus["console"]); + ImGui::Begin("Console", enabled); if (ImGui::BeginPopup("Options")) { @@ -159,7 +160,7 @@ namespace gui_console ImGui::BeginChild("console_scroll", ImVec2(0, -footer_height_to_reserve), false); - const auto output = game_console::get_output(); + const auto& output = game_console::get_output(); for (const auto& line : output) { if (utils::string::find_lower(line, filter)) @@ -177,7 +178,7 @@ namespace gui_console if (ImGui::InputText("Input", &input, input_text_flags, input_text_edit)) { - auto history = game_console::get_history(); + auto& history = game_console::get_history(); if (history_index != -1) { @@ -209,4 +210,4 @@ namespace gui_console }; } -REGISTER_COMPONENT(gui_console::component) +REGISTER_COMPONENT(gui::console::component) diff --git a/src/client/component/gui_debug.cpp b/src/client/component/gui_debug.cpp index 18062b8a..80233264 100644 --- a/src/client/component/gui_debug.cpp +++ b/src/client/component/gui_debug.cpp @@ -16,7 +16,7 @@ #include #include -namespace gui_debug +namespace gui::debug { namespace { @@ -403,12 +403,13 @@ namespace gui_debug void draw_window() { - if (!gui::enabled_menus["debug"]) + static auto* enabled = &gui::enabled_menus["debug"]; + if (!*enabled) { return; } - ImGui::Begin("Debug", &gui::enabled_menus["debug"]); + ImGui::Begin("Debug", enabled); if (ImGui::TreeNode("Path nodes")) { @@ -724,4 +725,4 @@ namespace gui_debug }; } -REGISTER_COMPONENT(gui_debug::component) +REGISTER_COMPONENT(gui::debug::component) diff --git a/src/client/component/gui_entity_list.cpp b/src/client/component/gui_entity_list.cpp index 40eddb62..cd991e8c 100644 --- a/src/client/component/gui_entity_list.cpp +++ b/src/client/component/gui_entity_list.cpp @@ -15,7 +15,7 @@ #include #include -namespace entity_list +namespace gui::entity_list { namespace { @@ -593,8 +593,9 @@ namespace entity_list void show_entity_list_window(data_t& data) { + static auto* enabled = &gui::enabled_menus["entity_list"]; ImGui::SetNextWindowSizeConstraints(ImVec2(500, 500), ImVec2(1000, 1000)); - ImGui::Begin("Entity list", &gui::enabled_menus["entity_list"]); + ImGui::Begin("Entity list", enabled); if (ImGui::Button("Update list")) { @@ -808,7 +809,8 @@ namespace entity_list void on_frame() { - if (!gui::enabled_menus["entity_list"]) + static auto* enabled = &gui::enabled_menus["entity_list"]; + if (!*enabled) { return; } @@ -858,4 +860,4 @@ namespace entity_list }; } -REGISTER_COMPONENT(entity_list::component) +REGISTER_COMPONENT(gui::entity_list::component) diff --git a/src/client/component/gui_script_console.cpp b/src/client/component/gui_script_console.cpp index ca4442ce..4d667de5 100644 --- a/src/client/component/gui_script_console.cpp +++ b/src/client/component/gui_script_console.cpp @@ -15,7 +15,7 @@ #include #include -namespace gui_script_console +namespace gui::script_console { namespace { @@ -228,4 +228,4 @@ namespace gui_script_console }; } -REGISTER_COMPONENT(gui_script_console::component) +REGISTER_COMPONENT(gui::script_console::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 862277e7..ee6d4831 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -4,7 +4,6 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include "chat.hpp" #include "scheduler.hpp" #include "command.hpp" diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index fe6ac7e4..2bb6e19e 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -70,16 +70,6 @@ namespace updater return main; } - std::string get_data_path() - { - if (GIT_BRANCH == "develop"s) - { - return DATA_PATH_DEV; - } - - return DATA_PATH; - } - void set_update_check_status(bool done, bool success, const std::string& error = {}) { update_data.access([done, success, error](update_data_t& data_) diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 06b61680..f35bf522 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -9,7 +9,6 @@ #include "../../../component/notifies.hpp" #include "../../../component/scripting.hpp" #include "../../../component/command.hpp" -#include "../../../component/chat.hpp" #include "../../../component/fastfiles.hpp" #include @@ -377,9 +376,8 @@ namespace scripting::lua command::execute(utils::string::va("setdiscordstate %s", state.data()), false); }; - game_type["say"] = [](const game&, const std::string& msg) + game_type["say"] = [](const game&) { - chat::print(msg); }; game_type["detour"] = [](const game&, const sol::this_state s, const std::string& filename, From 2c14dc15e6f19e1b516cbbd2792f1575e5d9c70e Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 29 Mar 2022 19:57:49 +0200 Subject: [PATCH 51/52] Remove protobuf --- .gitmodules | 3 -- deps/premake/protobuf.lua | 60 -------------------------------------- deps/protobuf | 1 - src/client/std_include.hpp | 2 -- 4 files changed, 66 deletions(-) delete mode 100644 deps/premake/protobuf.lua delete mode 160000 deps/protobuf diff --git a/.gitmodules b/.gitmodules index a8f01577..3fa56e25 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,9 +22,6 @@ [submodule "deps/asmjit"] path = deps/asmjit url = https://github.com/asmjit/asmjit.git -[submodule "deps/protobuf"] - path = deps/protobuf - url = https://github.com/google/protobuf.git [submodule "deps/udis86"] path = deps/udis86 url = https://github.com/vmt/udis86.git diff --git a/deps/premake/protobuf.lua b/deps/premake/protobuf.lua deleted file mode 100644 index 1c58972c..00000000 --- a/deps/premake/protobuf.lua +++ /dev/null @@ -1,60 +0,0 @@ -protobuf = { - source = path.join(dependencies.basePath, "protobuf"), -} - -function protobuf.import() - links { - "protobuf" - } - - protobuf.includes() -end - -function protobuf.includes() - includedirs { - path.join(protobuf.source, "src"), - } -end - -function protobuf.project() - project "protobuf" - language "C++" - - protobuf.includes() - - files { - path.join(protobuf.source, "src/**.cc"), - "./src/**.proto", - } - - removefiles { - path.join(protobuf.source, "src/**/*test.cc"), - path.join(protobuf.source, "src/google/protobuf/*test*.cc"), - - path.join(protobuf.source, "src/google/protobuf/testing/**.cc"), - path.join(protobuf.source, "src/google/protobuf/compiler/**.cc"), - - path.join(protobuf.source, "src/google/protobuf/arena_nc.cc"), - path.join(protobuf.source, "src/google/protobuf/util/internal/error_listener.cc"), - path.join(protobuf.source, "**/*_gcc.cc"), - } - - rules { - "ProtobufCompiler" - } - - defines { - "_SCL_SECURE_NO_WARNINGS", - "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS", - "_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS", - } - - linkoptions { - "-IGNORE:4221" - } - - warnings "Off" - kind "StaticLib" -end - -table.insert(dependencies, protobuf) diff --git a/deps/protobuf b/deps/protobuf deleted file mode 160000 index a69354f3..00000000 --- a/deps/protobuf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a69354f31b253856689ae765a9ea3217ec001873 diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index b426086a..ea9613ee 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -86,8 +86,6 @@ #include #include -#include - #include #include #include From 9b2190cd4af88901fef0c0e7343935a7f6fa8739 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 29 Mar 2022 23:59:07 +0200 Subject: [PATCH 52/52] Small fix --- src/client/component/notifies.cpp | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/client/component/notifies.cpp b/src/client/component/notifies.cpp index 4d8b6fa9..d2ecb7f3 100644 --- a/src/client/component/notifies.cpp +++ b/src/client/component/notifies.cpp @@ -32,20 +32,20 @@ namespace notifies { if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) { + hook_enabled = true; return false; } - if (!hook_enabled && pos > (char*)vm_execute_hooks.size()) + if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) { hook_enabled = true; return false; } - const auto hook = vm_execute_hooks[pos]; + const auto& hook = vm_execute_hooks[pos]; const auto state = hook.lua_state(); - const auto self_id = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); - const auto self = scripting::entity(self_id); + const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); std::vector args; @@ -59,16 +59,6 @@ namespace notifies const auto result = hook(self, sol::as_args(args)); scripting::lua::handle_error(result); - const auto value = scripting::lua::convert({state, result}); - const auto type = value.get_raw().type; - - game::Scr_ClearOutParams(); - - if (result.valid() && type && type < game::SCRIPT_END) - { - scripting::push_value(value); - } - return true; } @@ -99,7 +89,7 @@ namespace notifies a.bind(replace); a.popad64(); - a.mov(r14, (char*)empty_function); + a.mov(r14, reinterpret_cast(empty_function)); a.jmp(end); }