diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d7a1aad..2274b55f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ on: jobs: build: name: Build binaries - runs-on: windows-latest + runs-on: windows-2022 strategy: matrix: configuration: @@ -38,8 +38,8 @@ jobs: uses: microsoft/setup-msbuild@v1.0.2 - name: Generate project files - #run: tools/premake5 vs2019 --ci-build - run: tools/premake5 vs2019 + #run: tools/premake5 vs2022 --ci-build + run: tools/premake5 vs2022 - name: Set up problem matching uses: ammaraskar/msvc-problem-matcher@master diff --git a/README.md b/README.md index ddb1458a..3ff4538a 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,10 @@ This software has been created purely for the purposes of academic research. It is not intended to be used to attack other systems. Project maintainers are not responsible or liable for misuse of the software. Use responsibly. + +## Credits + +This project is based on [IW6x](https://github.com/XLabsProject/iw6x-client) and [S1x](https://github.com/XLabsProject/s1x-client) +* [momo5502](https://github.com/momo5502) +* [JariKCoding](https://github.com/JariKCoding/CoDLuaDecompiler) +* [xensik](https://github.com/xensik/gsc-tool/) diff --git a/appveyor.yml b/appveyor.yml index 0b851994..400aa2b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,8 +4,8 @@ version: "#{build} ({branch})" environment: matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - PREMAKE_ACTION: vs2019 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + PREMAKE_ACTION: vs2022 CI: 1 branches: diff --git a/data/ui_scripts/mods/loading.lua b/data/ui_scripts/mods/loading.lua index 85acffb1..18fab2c8 100644 --- a/data/ui_scripts/mods/loading.lua +++ b/data/ui_scripts/mods/loading.lua @@ -85,14 +85,16 @@ LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1) if (io.directoryexists("mods")) then local mods = io.listfiles("mods/") for i = 1, #mods do - local name, desc = getmodname(mods[i]) + 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 - }) + 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 diff --git a/deps/asmjit b/deps/asmjit index 9a92d2f9..28c4d8c5 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 9a92d2f97260749f6f29dc93e53c743448f0137a +Subproject commit 28c4d8c528527141955006f09124ce672ddfbe3f diff --git a/deps/curl b/deps/curl index 9f1d29ec..049f3765 160000 --- a/deps/curl +++ b/deps/curl @@ -1 +1 @@ -Subproject commit 9f1d29ecacffe3e94349bcef6e9fafa62b1cc431 +Subproject commit 049f3765c7016a3f7a92b7f88aae6405c49b84fb diff --git a/deps/imgui b/deps/imgui index f07df317..fc842149 160000 --- a/deps/imgui +++ b/deps/imgui @@ -1 +1 @@ -Subproject commit f07df31745296090ac7ecc01811f88c85766028a +Subproject commit fc84214988b74179b3941d35393c24ee8ba7a794 diff --git a/deps/libtommath b/deps/libtommath index bea92706..04e9d1e7 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit bea9270646303baf683f4ba2ddf0d70721f0e55d +Subproject commit 04e9d1e7a0493910b2eb5e757d623870692ada04 diff --git a/deps/protobuf b/deps/protobuf index 3ea30d80..2f7ee91e 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 3ea30d80847cd9561db570ae7f673afc15523545 +Subproject commit 2f7ee91e326d95915b63918f968244cfefbc022a diff --git a/deps/rapidjson b/deps/rapidjson index fd3dc29a..e4bde977 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit fd3dc29a5c2852df569e1ea81dbde2c412ac5051 +Subproject commit e4bde977440d4a00f820b6586899e48a972d2493 diff --git a/generate.bat b/generate.bat index b9ffdf6f..8d2b86a4 100644 --- a/generate.bat +++ b/generate.bat @@ -1,3 +1,4 @@ @echo off git submodule update --init --recursive -tools\premake5 %* vs2019 \ No newline at end of file +tools\premake5 %* vs2022 +pause \ No newline at end of file diff --git a/premake5.lua b/premake5.lua index eb07c0f6..1818c93c 100644 --- a/premake5.lua +++ b/premake5.lua @@ -248,25 +248,23 @@ end flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"} +filter "platforms:x64" + defines {"_WINDOWS", "WIN32"} +filter {} -configuration "windows" -defines {"_WINDOWS", "WIN32"} +filter "configurations:Release" + optimize "Size" + buildoptions {"/GL"} + linkoptions { "/IGNORE:4702", "/LTCG" } + defines {"NDEBUG"} + flags {"FatalCompileWarnings"} +filter {} -configuration "Release" -optimize "Size" -buildoptions {"/GL"} -linkoptions { "/IGNORE:4702", "/LTCG" } - -defines {"NDEBUG"} - -flags {"FatalCompileWarnings"} - -configuration "Debug" -optimize "Debug" -buildoptions {"/bigobj"} -defines {"DEBUG", "_DEBUG"} - -configuration {} +filter "configurations:Debug" + optimize "Debug" + buildoptions {"/bigobj"} + defines {"DEBUG", "_DEBUG"} +filter {} project "common" kind "StaticLib" @@ -280,20 +278,6 @@ resincludedirs {"$(ProjectDir)src"} dependencies.imports() -project "runner" -kind "WindowedApp" -language "C++" - -files {"./src/runner/**.rc", "./src/runner/**.hpp", "./src/runner/**.cpp", "./src/runner/resources/**.*"} - -includedirs {"./src/runner", "./src/common", "%{prj.location}/src"} - -resincludedirs {"$(ProjectDir)src"} - -links {"common"} - -dependencies.imports() - project "client" kind "ConsoleApp" language "C++" @@ -311,7 +295,7 @@ includedirs {"./src/client", "./src/common", "%{prj.location}/src"} resincludedirs {"$(ProjectDir)src"} -dependson {"tlsdll", "runner"} +dependson {"tlsdll"} links {"common"} @@ -335,22 +319,6 @@ links {"common"} resincludedirs {"$(ProjectDir)src"} -project "runner" -kind "WindowedApp" -language "C++" - -files {"./src/runner/**.rc", "./src/runner/**.hpp", "./src/runner/**.cpp", "./src/runner/resources/**.*"} - -includedirs {"./src/runner", "./src/common", "%{prj.location}/src"} - -links {"common"} - -resincludedirs {"$(ProjectDir)src"} - -links {"common"} - -dependencies.imports() - group "Dependencies" dependencies.projects() diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp index 36f9e06c..0eb88f30 100644 --- a/src/client/component/binding.cpp +++ b/src/client/component/binding.cpp @@ -5,6 +5,8 @@ #include #include +#define ORIGINAL_BIND_COUNT 110 + namespace binding { namespace @@ -24,7 +26,7 @@ namespace binding const auto* const key_button = game::Key_KeynumToString(key_index, 0, 1); auto value = game::playerKeys->keys[key_index].binding; - if (value && value < 100) + if (value && value < ORIGINAL_BIND_COUNT) { const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), "bind %s \"%s\"\n", key_button, game::command_whitelist[value]); @@ -36,9 +38,9 @@ namespace binding bytes_used += len; } - else if (value >= 100) + else if (value >= ORIGINAL_BIND_COUNT) { - value -= 100; + value -= ORIGINAL_BIND_COUNT; if (static_cast(value) < custom_binds.size() && !custom_binds[value].empty()) { const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), @@ -80,7 +82,7 @@ namespace binding int key_get_binding_for_cmd_stub(const char* command) { // original binds - for (auto i = 0; i <= 100; i++) + for (auto i = 0; i <= ORIGINAL_BIND_COUNT; i++) { if (game::command_whitelist[i] && !strcmp(command, game::command_whitelist[i])) { @@ -89,14 +91,14 @@ namespace binding } // custom binds - return 100 + get_binding_for_custom_command(command); + return ORIGINAL_BIND_COUNT + get_binding_for_custom_command(command); } void cl_execute_key_stub(const int local_client_num, int key, const int down, const unsigned int time) { - if (key >= 100) + if (key >= ORIGINAL_BIND_COUNT) { - key -= 100; + key -= ORIGINAL_BIND_COUNT; if (static_cast(key) < custom_binds.size() && !custom_binds[key].empty()) { diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 9e285dab..46f0ad7f 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -22,14 +22,14 @@ namespace branding ui_scripting::push_value(VERSION); return 1; } - } - void draw() - { - const auto font = game::R_RegisterFont("fonts/defaultBold.otf", 22); - game::R_AddCmdDrawText("h2-mod", 0x7FFFFFFF, font, 15.f, - 15.f + static_cast(font->pixelHeight), - 1.f, 1.f, 0.f, color, 0); + void draw() + { + const auto font = game::R_RegisterFont("fonts/defaultBold.otf", 22); + game::R_AddCmdDrawText("h2-mod", 0x7FFFFFFF, font, 15.f, + 15.f + static_cast(font->pixelHeight), + 1.f, 1.f, 0.f, color, 0); + } } class component final : public component_interface @@ -37,6 +37,8 @@ namespace branding public: void post_unpack() override { + scheduler::loop(draw, scheduler::pipeline::renderer); + localized_strings::override("MENU_SP_CAMPAIGN", "H2-MOD"); localized_strings::override("MENU_SYSINFO_CUSTOMER_SUPPORT_LINK", "Github Page:"); localized_strings::override("MENU_SYSINFO_CUSTOMER_SUPPORT_URL", "https://github.com/fedddddd/h2-mod"); diff --git a/src/client/component/branding.hpp b/src/client/component/branding.hpp deleted file mode 100644 index d3ef860d..00000000 --- a/src/client/component/branding.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace branding -{ - void draw(); -} \ No newline at end of file diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index 793a255d..ff522f5d 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -279,21 +279,21 @@ namespace fps game::R_AddCmdDrawText(pos_string, 0x7FFFFFFF, font, x, 60.f, 1.0f, 1.0f, 0.0f, fps_color_ok, 0); } - } - void draw() - { - check_resize(); - draw_fps(); - - if (!game::CL_IsCgameInitialized() || !game::g_entities[0].client) + void draw() { - return; - } + check_resize(); + draw_fps(); - draw_pos(); - draw_speed(); - draw_speed_graph(); + if (!game::CL_IsCgameInitialized() || !game::g_entities[0].client) + { + return; + } + + draw_pos(); + draw_speed(); + draw_speed_graph(); + } } class component final : public component_interface @@ -301,6 +301,8 @@ namespace fps public: void post_unpack() override { + scheduler::loop(draw, scheduler::pipeline::renderer); + sub_7C55D0_hook.create(0x7C55D0_b, perf_update); cg_drawSpeed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED); diff --git a/src/client/component/fps.hpp b/src/client/component/fps.hpp deleted file mode 100644 index 6edceb69..00000000 --- a/src/client/component/fps.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace fps -{ - void draw(); -} \ No newline at end of file diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index f517e3d2..78d8f401 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -354,25 +354,25 @@ namespace game_console draw_output_scrollbar(x, y, width, height); draw_output_text(x, y); } - } - void draw_console() - { - check_resize(); - - if (*game::keyCatchers & 1) + void draw_console() { - if (!(*game::keyCatchers & 1)) - { - con.output_visible = false; - } + check_resize(); - if (con.output_visible) + if (*game::keyCatchers & 1) { - draw_output_window(); - } + if (!(*game::keyCatchers & 1)) + { + con.output_visible = false; + } - draw_input(); + if (con.output_visible) + { + draw_output_window(); + } + + draw_input(); + } } } @@ -719,6 +719,8 @@ namespace game_console public: void post_unpack() override { + scheduler::loop(draw_console, scheduler::pipeline::renderer); + con.cursor = 0; con.visible_line_count = 0; con.output_visible = false; diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index 3a3b2c6d..9506da40 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -9,8 +9,6 @@ namespace game_console con_type_info = 7 }; - void draw_console(); - void print(int type, const char* fmt, ...); bool console_char_event(int local_client_num, int key); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 8d890529..8465f83d 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -37,14 +37,22 @@ namespace patches gscr_set_save_dvar_hook.invoke(); } + game::dvar_t* cg_fov = nullptr; + game::dvar_t* cg_fovScale = nullptr; + game::dvar_t* dvar_register_float_stub(int hash, const char* dvarName, float value, float min, float max, unsigned int flags) { static const auto cg_fov_hash = game::generateHashValue("cg_fov"); static const auto cg_fov_scale_hash = game::generateHashValue("cg_fovscale"); - if (hash == cg_fov_hash || hash == cg_fov_scale_hash) + if (hash == cg_fov_hash) { - flags = game::DvarFlags::DVAR_FLAG_SAVED; + return cg_fov; + } + + if (hash == cg_fov_scale_hash) + { + return cg_fovScale; } return dvar_register_float_hook.invoke(hash, dvarName, value, min, max, flags); @@ -75,7 +83,12 @@ namespace patches // Prevent game from overriding cg_fov and cg_fovscale values gscr_set_save_dvar_hook.create(0x504C60_b, &gscr_set_save_dvar_stub); + // Make cg_fov and cg_fovscale saved dvars + + cg_fov = dvars::register_float("cg_fov", 65.f, 40.f, 200.f, game::DvarFlags::DVAR_FLAG_SAVED); + cg_fovScale = dvars::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DvarFlags::DVAR_FLAG_SAVED); + dvar_register_float_hook.create(game::Dvar_RegisterFloat.get(), dvar_register_float_stub); } }; diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 5c33bfa1..a266a693 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -97,6 +97,11 @@ namespace scheduler void r_end_frame_stub() { execute(pipeline::renderer); + if (game::Sys_IsMainThread()) + { + execute(pipeline::lui); + } + r_end_frame_hook.invoke(); } diff --git a/src/client/component/scheduler.hpp b/src/client/component/scheduler.hpp index f674475e..7e0a2e21 100644 --- a/src/client/component/scheduler.hpp +++ b/src/client/component/scheduler.hpp @@ -10,6 +10,8 @@ namespace scheduler // The game's rendering pipeline renderer, + lui, + // The game's server thread server, diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index aee1a555..a810606c 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -8,10 +8,6 @@ #include "scheduler.hpp" #include "command.hpp" -#include "game_console.hpp" -#include "fps.hpp" -#include "branding.hpp" - #include "ui_scripting.hpp" #include "game/ui_scripting/lua/engine.hpp" @@ -23,41 +19,17 @@ namespace ui_scripting { - std::unordered_map functions; - std::unordered_map methods; - namespace { std::unordered_map converted_functions; - utils::hook::detour hksi_open_lib_hook; utils::hook::detour hksi_lual_error_hook; utils::hook::detour hksi_lual_error_hook2; - utils::hook::detour hksi_add_function_hook; utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; bool error_hook_enabled = false; - void* hksi_open_lib_stub(game::hks::lua_State* s, const char* libname, game::hks::luaL_Reg* l) - { - for (auto i = l; i->name; ++i) - { - if (i->name == "__gc"s) - { - continue; - } - - const auto lower = utils::string::to_lower(i->name); - - libname - ? functions[lower] = i->function - : methods[lower] = i->function; - } - - return hksi_open_lib_hook.invoke(s, libname, l); - } - void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) { char va_buffer[2048] = {0}; @@ -86,8 +58,6 @@ namespace ui_scripting ui_scripting::lua::engine::start(); }); - functions = {}; - methods = {}; return hks_start_hook.invoke(a1); } @@ -96,18 +66,6 @@ namespace ui_scripting ui_scripting::lua::engine::stop(); hks_shutdown_hook.invoke(); } - - void hksi_add_function_stub(game::hks::lua_State* s, game::hks::lua_function f, int a3, const char* name, int a5) - { - if (name != "( lua_CFunction )LUI_CoD_LuaCall_UIExpression"s) - { - std::string name_ = name; - const auto sub = utils::string::to_lower(name_.substr(13, name_.size() - 14)); - functions[sub] = f; - } - - hksi_add_function_hook.invoke(s, f, a3, name, a5); - } } int main_function_handler(game::hks::lua_State* state) @@ -167,26 +125,6 @@ namespace ui_scripting error_hook_enabled = false; } - game::hks::lua_function find_function(const std::string& name) - { - const auto lower = utils::string::to_lower(name); - if (functions.find(lower) == functions.end()) - { - return 0; - } - return functions[lower]; - } - - game::hks::lua_function find_method(const std::string& name) - { - const auto lower = utils::string::to_lower(name); - if (methods.find(lower) == methods.end()) - { - return 0; - } - return methods[lower]; - } - void notify(const event& e) { lua::engine::notify(e); @@ -198,47 +136,12 @@ namespace ui_scripting void post_unpack() override { - scheduler::loop([]() - { - if (game::Sys_IsMainThread()) - { - ui_scripting::lua::engine::run_frame(); - } - - fps::draw(); - branding::draw(); - game_console::draw_console(); - }, scheduler::pipeline::renderer); - - command::add("reloadmenus", []() - { - scheduler::once(ui_scripting::lua::engine::start, scheduler::pipeline::renderer); - }); - - command::add("openluamenu", [](const command::params& params) - { - const std::string name = params.get(1); - scheduler::once([name]() - { - ui_scripting::lua::engine::open_menu(name); - }, scheduler::pipeline::renderer); - }); - - command::add("closeluamenu", [](const command::params& params) - { - const std::string name = params.get(1); - scheduler::once([name]() - { - ui_scripting::lua::engine::close_menu(name); - }, scheduler::pipeline::renderer); - }); + 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_open_lib_hook.create(0x2E4530_b, hksi_open_lib_stub); hksi_lual_error_hook.create(0x2E3E40_b, hksi_lual_error_stub); hksi_lual_error_hook2.create(0x2DCB40_b, hksi_lual_error_stub); - hksi_add_function_hook.create(0x2DB570_b, hksi_add_function_stub); } }; } diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp index ad5792af..8831d39d 100644 --- a/src/client/component/ui_scripting.hpp +++ b/src/client/component/ui_scripting.hpp @@ -1,13 +1,9 @@ #pragma once #include "game/ui_scripting/lua/value_conversion.hpp" -#include "game/ui_scripting/menu.hpp" #include "game/ui_scripting/event.hpp" namespace ui_scripting { - extern std::unordered_map functions; - extern std::unordered_map methods; - int main_function_handler(game::hks::lua_State* state); void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function); void clear_converted_functions(); @@ -15,8 +11,5 @@ namespace ui_scripting void enable_error_hook(); void disable_error_hook(); - game::hks::lua_function find_function(const std::string& name); - game::hks::lua_function find_method(const std::string& name); - void notify(const event& e); } diff --git a/src/client/game/scripting/array.cpp b/src/client/game/scripting/array.cpp index 79eda843..92fe975b 100644 --- a/src/client/game/scripting/array.cpp +++ b/src/client/game/scripting/array.cpp @@ -264,8 +264,6 @@ namespace scripting void array::set(const std::string& key, const script_value& _value) const { const auto value = _value.get_raw(); - - const auto string_value = game::SL_GetString(key.data(), 0); const auto variable_id = this->get_value_id(key); if (!variable_id) diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index ef6e15b1..0bee5fba 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -30,7 +30,20 @@ namespace scripting::lua ); } - void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) + void setup_io(sol::state& state) + { + 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); + } + + void setup_vector_type(sol::state& state) { state["level"] = entity{*::game::levelEntityId}; state["player"] = call("getentbynum", {0}).as(); @@ -181,6 +194,12 @@ namespace scripting::lua { return call("anglestoforward", {a}).as(); }; + } + + void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) + { + state["level"] = entity{ *::game::levelEntityId }; + state["player"] = call("getentbynum", { 0 }).as(); auto entity_type = state.new_usertype("entity"); @@ -307,7 +326,10 @@ namespace scripting::lua std::vector returns = {entref.entnum, entref.classnum}; return sol::as_returns(returns); }; + } + void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler) + { struct game { }; @@ -407,7 +429,7 @@ namespace scripting::lua return detour; }; - game_type["getfunctions"] = [entity_type](const game&, const sol::this_state s, const std::string& filename) + game_type["getfunctions"] = [](const game&, const sol::this_state s, const std::string& filename) { if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) { @@ -611,7 +633,10 @@ namespace scripting::lua return this->folder_; }; + setup_io(this->state_); + setup_vector_type(this->state_); setup_entity_type(this->state_, this->event_handler_, this->scheduler_); + setup_game_type(this->state_, this->event_handler_, this->scheduler_); printf("Loading script '%s'\n", this->folder_.data()); this->load_script("__init__"); diff --git a/src/client/game/ui_scripting/element.cpp b/src/client/game/ui_scripting/element.cpp deleted file mode 100644 index aca81b3f..00000000 --- a/src/client/game/ui_scripting/element.cpp +++ /dev/null @@ -1,409 +0,0 @@ -#include -#include "element.hpp" - -#include - -#define fps_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25) - -namespace ui_scripting -{ - namespace - { - uint64_t next_id; - float screen_max[2]; - - struct point - { - float x; - float y; - float f2; - float f3; - }; - - struct rectangle - { - point p0; - point p1; - point p2; - point p3; - }; - - std::unordered_map font_map = - { - {"bank", "fonts/bank.ttf"}, - {"fira_mono_bold", "fonts/fira_mono_bold.ttf"}, - {"fira_mono_regular", "fonts/fira_mono_regular.ttf"}, - {"defaultbold", "fonts/defaultbold.otf"}, - {"objective", "fonts/defaultbold.otf"}, - {"default", "fonts/default.otf"}, - }; - - std::unordered_map alignment_map = - { - {"left", alignment::start}, - {"top", alignment::start}, - {"center", alignment::middle}, - {"right", alignment::end}, - {"bottom", alignment::end}, - }; - - float get_align_value(alignment align, float text_width, float w) - { - switch (align) - { - case (alignment::start): - return 0.f; - case (alignment::middle): - return (w / 2.f) - (text_width / 2.f); - case (alignment::end): - return w - text_width; - default: - return 0.f; - } - } - - void draw_image(float x, float y, float w, float h, float* transform, float* color, game::Material* material) - { - game::rectangle rect; - - rect.p0.x = x; - rect.p0.y = y; - rect.p0.f2 = 0.f; - rect.p0.f3 = 1.f; - - rect.p1.x = x + w; - rect.p1.y = y; - rect.p1.f2 = 0.f; - rect.p1.f3 = 1.f; - - rect.p2.x = x + w; - rect.p2.y = y + h; - rect.p2.f2 = 0.f; - rect.p2.f3 = 1.f; - - rect.p3.x = x; - rect.p3.y = y + h; - rect.p3.f2 = 0.f; - rect.p3.f3 = 1.f; - - game::R_DrawRectangle(&rect, transform[0], transform[1], transform[2], transform[3], color, material); - } - - void check_resize() - { - screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0]; - screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1]; - } - - float relative(float value) - { - return ceil((value / 1920.f) * screen_max[0]); - } - - int relative(int value) - { - return (int)ceil(((float)value / 1920.f) * screen_max[0]); - } - - game::rgba float_to_rgba(const float* color) - { - game::rgba rgba; - rgba.r = (uint8_t)(color[0] * 255.f); - rgba.g = (uint8_t)(color[1] * 255.f); - rgba.b = (uint8_t)(color[2] * 255.f); - rgba.a = (uint8_t)(color[3] * 255.f); - return rgba; - } - - void draw_text(const char* text, game::Font_s* font, float x, float y, float x_scale, float y_scale, float rotation, - int style, float* color, float* second_color, float* glow_color) - { - const auto result = (uint64_t)game::R_AddCmdDrawText(text, 0x7FFFFFFF, font, x, y, x_scale, y_scale, rotation, color, style); - if (result) - { - *reinterpret_cast(result + 188) = glow_color[0]; - *reinterpret_cast(result + 192) = glow_color[1]; - *reinterpret_cast(result + 196) = glow_color[2]; - *reinterpret_cast(result + 200) = glow_color[3]; - *reinterpret_cast(result + 228) = float_to_rgba(second_color); - } - } - } - - element::element() - : id(next_id++) - { - } - - void element::set_horzalign(const std::string& value) - { - const auto lower = utils::string::to_lower(value); - if (alignment_map.find(lower) == alignment_map.end()) - { - this->horzalign = alignment::start; - return; - } - - const auto align = alignment_map[lower]; - this->horzalign = align; - } - - void element::set_vertalign(const std::string& value) - { - const auto lower = utils::string::to_lower(value); - if (alignment_map.find(lower) == alignment_map.end()) - { - this->vertalign = alignment::start; - return; - } - - const auto align = alignment_map[lower]; - this->vertalign = align; - } - - void element::set_text(const std::string& _text) - { - this->text = _text; - } - - void element::set_font(const std::string& _font, const int _fontsize) - { - this->fontsize = _fontsize; - const auto lowercase = utils::string::to_lower(_font); - - if (font_map.find(lowercase) == font_map.end()) - { - this->font = "default"; - } - else - { - this->font = lowercase; - } - } - - void element::set_font(const std::string& _font) - { - const auto lowercase = utils::string::to_lower(_font); - - if (font_map.find(lowercase) == font_map.end()) - { - this->font = "default"; - } - else - { - this->font = lowercase; - } - } - - void element::set_text_offset(float _x, float _y) - { - this->text_offset[0] = _x; - this->text_offset[1] = _y; - } - - void element::set_scale(float _x, float _y) - { - this->x_scale = _x; - this->y_scale = _y; - } - - void element::set_rotation(float _rotation) - { - this->rotation = _rotation; - } - - void element::set_style(int _style) - { - this->style = _style; - } - - void element::set_background_color(float r, float g, float b, float a) - { - this->background_color[0] = r; - this->background_color[1] = g; - this->background_color[2] = b; - this->background_color[3] = a; - } - - void element::set_color(float r, float g, float b, float a) - { - this->color[0] = r; - this->color[1] = g; - this->color[2] = b; - this->color[3] = a; - } - - void element::set_second_color(float r, float g, float b, float a) - { - this->use_gradient = true; - this->second_color[0] = r; - this->second_color[1] = g; - this->second_color[2] = b; - this->second_color[3] = a; - } - - void element::set_glow_color(float r, float g, float b, float a) - { - this->glow_color[0] = r; - this->glow_color[1] = g; - this->glow_color[2] = b; - this->glow_color[3] = a; - } - - void element::set_border_material(const std::string& _material) - { - this->border_material = _material; - } - - void element::set_border_color(float r, float g, float b, float a) - { - this->border_color[0] = r; - this->border_color[1] = g; - this->border_color[2] = b; - this->border_color[3] = a; - } - - void element::set_border_width(float top) - { - this->border_width[0] = top; - this->border_width[1] = top; - this->border_width[2] = top; - this->border_width[3] = top; - } - - void element::set_border_width(float top, float right) - { - this->border_width[0] = top; - this->border_width[1] = right; - this->border_width[2] = top; - this->border_width[3] = right; - } - - void element::set_border_width(float top, float right, float bottom) - { - this->border_width[0] = top; - this->border_width[1] = right; - this->border_width[2] = bottom; - this->border_width[3] = bottom; - } - - void element::set_border_width(float top, float right, float bottom, float left) - { - this->border_width[0] = top; - this->border_width[1] = right; - this->border_width[2] = bottom; - this->border_width[3] = left; - } - - void element::set_slice(float left_percent, float top_percent, float right_percent, float bottom_percent) - { - this->slice[0] = left_percent; - this->slice[1] = top_percent; - this->slice[2] = right_percent; - this->slice[3] = bottom_percent; - } - - void element::set_material(const std::string& _material) - { - this->material = _material; - } - - void element::set_rect(const float _x, const float _y, const float _w, const float _h) - { - this->x = _x; - this->y = _y; - this->w = _w; - this->h = _h; - } - - void element::render() const - { - check_resize(); - - if (this->background_color[3] > 0) - { - const auto background_material = game::Material_RegisterHandle(this->material.data()); - - draw_image( - relative(this->x) + relative(this->border_width[3]), - relative(this->y) + relative(this->border_width[0]), - relative(this->w) - relative(this->border_width[1]) - relative(this->border_width[3]), - relative(this->h) - relative(this->border_width[0]) - relative(this->border_width[2]), - (float*)this->slice, - (float*)this->background_color, - background_material - ); - } - - if (this->border_color[3] > 0) - { - const auto _border_material = game::Material_RegisterHandle(this->border_material.data()); - - draw_image( - relative(this->x), - relative(this->y), - relative(this->w), - relative(this->border_width[0]), - (float*)this->slice, - (float*)this->border_color, - _border_material - ); - - draw_image( - relative(this->x) + relative(this->w) - relative(this->border_width[1]), - relative(this->y) + relative(this->border_width[0]), - relative(this->border_width[1]), - relative(this->h) - relative(this->border_width[0]) - relative(this->border_width[2]), - (float*)this->slice, - (float*)this->border_color, - _border_material - ); - - draw_image( - relative(this->x), - relative(this->y) + relative(this->h) - relative(this->border_width[2]), - relative(this->w), - relative(this->border_width[2]), - (float*)this->slice, - (float*)this->border_color, - _border_material - ); - - draw_image( - relative(this->x), - relative(this->y) + relative(this->border_width[0]), - relative(this->border_width[3]), - relative(this->h) - relative(this->border_width[0]) - relative(this->border_width[2]), - (float*)this->slice, - (float*)this->border_color, - _border_material - ); - } - - if (!this->text.empty()) - { - const auto fontname = font_map[this->font]; - const auto _font = game::R_RegisterFont(fontname.data(), relative(this->fontsize)); - const auto text_width = game::R_TextWidth(this->text.data(), 0x7FFFFFFF, _font); - - const auto _horzalign = get_align_value(this->horzalign, (float)text_width, relative(this->w)); - const auto _vertalign = get_align_value(this->vertalign, (float)relative(this->fontsize), relative(this->h)); - - const auto _x = relative(this->x) + relative(this->text_offset[0]) + _horzalign + relative(this->border_width[3]); - const auto _y = relative(this->y) + relative(this->text_offset[1]) + _vertalign + relative(this->fontsize) + relative(this->border_width[0]); - - draw_text( - this->text.data(), - _font, - _x, _y, - this->x_scale, - this->y_scale, - this->rotation, - this->style, - (float*)this->color, - (float*)(this->use_gradient ? this->second_color : this->color), - (float*)this->glow_color - ); - } - } -} diff --git a/src/client/game/ui_scripting/element.hpp b/src/client/game/ui_scripting/element.hpp deleted file mode 100644 index 539b418b..00000000 --- a/src/client/game/ui_scripting/element.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "script_value.hpp" - -namespace ui_scripting -{ - enum alignment - { - start, - middle, - end, - }; - - class element final - { - public: - element(); - - void set_horzalign(const std::string& value); - void set_vertalign(const std::string& value); - - void set_text(const std::string& text); - void set_font(const std::string& _font); - void set_font(const std::string& _font, const int _fontsize); - void set_color(float r, float g, float b, float a); - void set_second_color(float r, float g, float b, float a); - void set_glow_color(float r, float g, float b, float a); - void set_text_offset(float x, float y); - - void set_scale(float x, float y); - void set_rotation(float rotation); - void set_style(int style); - - void set_background_color(float r, float g, float b, float a); - void set_material(const std::string& material); - - void set_border_material(const std::string& material); - void set_border_color(float r, float g, float b, float a); - void set_border_width(float top); - void set_border_width(float top, float right); - void set_border_width(float top, float right, float bottom); - void set_border_width(float top, float right, float bottom, float left); - - void set_slice(float left_percent, float top_percent, float right_percent, float bottom_percent); - - void set_rect(const float _x, const float _y, const float _w, const float _h); - - uint64_t id; - - void render() const; - - bool hidden = false; - bool use_gradient = false; - - float x = 0.f; - float y = 0.f; - float w = 0.f; - float h = 0.f; - - float rotation = 0; - float x_scale = 1.f; - float y_scale = 1.f; - - int style = 0; - int fontsize = 20; - - float text_offset[2] = {0.f, 0.f}; - float color[4] = {1.f, 1.f, 1.f, 1.f}; - float second_color[4] = {1.f, 1.f, 1.f, 1.f}; - float glow_color[4] = {0.f, 0.f, 0.f, 0.f}; - float background_color[4] = {0.f, 0.f, 0.f, 0.f}; - float border_color[4] = {0.f, 0.f, 0.f, 0.f}; - float border_width[4] = {0.f, 0.f, 0.f, 0.f}; - float slice[4] = {0.f, 0.f, 1.f, 1.f}; - - alignment horzalign = alignment::start; - alignment vertalign = alignment::start; - - std::unordered_map attributes = {}; - std::string font = "default"; - std::string material = "white"; - std::string border_material = "white"; - std::string text{}; - }; -} diff --git a/src/client/game/ui_scripting/event.hpp b/src/client/game/ui_scripting/event.hpp index 4655ea77..f82c8a79 100644 --- a/src/client/game/ui_scripting/event.hpp +++ b/src/client/game/ui_scripting/event.hpp @@ -6,7 +6,6 @@ namespace ui_scripting struct event { std::string name; - const void* element{}; arguments arguments; }; } diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp index 84efbce8..fff6b88e 100644 --- a/src/client/game/ui_scripting/execution.cpp +++ b/src/client/game/ui_scripting/execution.cpp @@ -158,71 +158,4 @@ namespace ui_scripting throw std::runtime_error(std::string("Error setting table field: ") + e.what()); } } - - arguments call_method(const userdata& self, const std::string& name, const arguments& arguments) - { - const auto function = ui_scripting::find_method(name); - if (!function) - { - throw std::runtime_error("Function " + name + " not found"); - } - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(self); - for (auto i = arguments.begin(); i != arguments.end(); ++i) - { - push_value(*i); - } - - enable_error_hook(); - const auto __ = gsl::finally([]() - { - disable_error_hook(); - }); - - try - { - const auto count = function(*game::hks::lua_state); - return get_return_values(count); - } - catch (const std::exception& e) - { - throw std::runtime_error("Error executing method " + name + ": " + e.what()); - } - } - - arguments call(const std::string& name, const arguments& arguments) - { - const auto function = ui_scripting::find_function(name); - if (!function) - { - throw std::runtime_error("Function " + name + " not found"); - } - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - for (auto i = arguments.begin(); i != arguments.end(); ++i) - { - push_value(*i); - } - - enable_error_hook(); - const auto __ = gsl::finally([]() - { - disable_error_hook(); - }); - - try - { - const auto count = function(*game::hks::lua_state); - return get_return_values(count); - } - catch (const std::exception& e) - { - throw std::runtime_error("Error executing function " + name + ": " + e.what()); - } - } } diff --git a/src/client/game/ui_scripting/execution.hpp b/src/client/game/ui_scripting/execution.hpp index 1ec7c8bf..24f4dd72 100644 --- a/src/client/game/ui_scripting/execution.hpp +++ b/src/client/game/ui_scripting/execution.hpp @@ -15,7 +15,4 @@ namespace ui_scripting script_value get_field(const table& self, const script_value& key); void set_field(const userdata& self, const script_value& key, const script_value& value); void set_field(const table& self, const script_value& key, const script_value& value); - - arguments call_method(const userdata& self, const std::string& name, const arguments& arguments); - arguments call(const std::string& name, const arguments& arguments); } diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index d5dadd90..8c422965 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -23,14 +23,8 @@ namespace ui_scripting::lua { - std::unordered_map menus; - std::vector elements; - element ui_element; - int mouse[2]; - namespace { - const auto animation_script = utils::nt::load_resource(LUA_ANIMATION_SCRIPT); const auto json_script = utils::nt::load_resource(LUA_JSON_SCRIPT); scripting::script_value script_convert(const sol::lua_value& value) @@ -213,506 +207,6 @@ namespace ui_scripting::lua }; } - void setup_element_type(sol::state& state, event_handler& handler, scheduler& scheduler) - { - auto element_type = state.new_usertype("element", "new", []() - { - const auto el = new element(); - elements.push_back(el); - return el; - }); - - element_type["setvertalign"] = &element::set_vertalign; - element_type["sethorzalign"] = &element::set_horzalign; - element_type["setrect"] = &element::set_rect; - element_type["setfont"] = sol::overload( - static_cast(&element::set_font), - static_cast(&element::set_font) - ); - element_type["settext"] = &element::set_text; - element_type["setmaterial"] = &element::set_material; - element_type["setcolor"] = &element::set_color; - element_type["setsecondcolor"] = &element::set_second_color; - element_type["setglowcolor"] = &element::set_glow_color; - element_type["setbackcolor"] = &element::set_background_color; - element_type["setbordercolor"] = &element::set_border_color; - element_type["setborderwidth"] = sol::overload( - static_cast(&element::set_border_width), - static_cast(&element::set_border_width), - static_cast(&element::set_border_width), - static_cast(&element::set_border_width) - ); - element_type["settextoffset"] = &element::set_text_offset; - element_type["setscale"] = &element::set_scale; - element_type["setrotation"] = &element::set_rotation; - element_type["setyle"] = &element::set_style; - element_type["setslice"] = &element::set_slice; - - element_type["getrect"] = [](const sol::this_state s, element& element) - { - auto rect = sol::table::create(s.lua_state()); - rect["x"] = element.x; - rect["y"] = element.y; - rect["w"] = element.w + element.border_width[1] + element.border_width[3]; - rect["h"] = element.h + element.border_width[0] + element.border_width[2]; - - return rect; - }; - - element_type["x"] = sol::property( - [](element& element) - { - return element.x; - }, - [](element& element, float x) - { - element.x = x; - } - ); - - element_type["y"] = sol::property( - [](element& element) - { - return element.y; - }, - [](element& element, float y) - { - element.y = y; - } - ); - - element_type["w"] = sol::property( - [](element& element) - { - return element.w; - }, - [](element& element, float w) - { - element.w = w; - } - ); - - element_type["h"] = sol::property( - [](element& element) - { - return element.h; - }, - [](element& element, float h) - { - element.h = h; - } - ); - - element_type["scalex"] = sol::property( - [](element& element) - { - return element.x_scale; - }, - [](element& element, float x_scale) - { - element.x_scale = x_scale; - } - ); - - element_type["scaley"] = sol::property( - [](element& element) - { - return element.y_scale; - }, - [](element& element, float y_scale) - { - element.y_scale = y_scale; - } - ); - - element_type["rotation"] = sol::property( - [](element& element) - { - return element.rotation; - }, - [](element& element, float rotation) - { - element.rotation = rotation; - } - ); - - element_type["style"] = sol::property( - [](element& element) - { - return element.style; - }, - [](element& element, int style) - { - element.style = style; - } - ); - - element_type["color"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["r"] = element.color[0]; - color["g"] = element.color[1]; - color["b"] = element.color[2]; - color["a"] = element.color[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; - element.color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; - element.color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; - element.color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; - } - ); - - element_type["secondcolor"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["r"] = element.second_color[0]; - color["g"] = element.second_color[1]; - color["b"] = element.second_color[2]; - color["a"] = element.second_color[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.use_gradient = true; - element.second_color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; - element.second_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; - element.second_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; - element.second_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; - } - ); - - element_type["usegradient"] = sol::property( - [](element& element, const sol::this_state s) - { - return element.use_gradient; - }, - [](element& element, bool use_gradient) - { - element.use_gradient = use_gradient; - } - ); - - element_type["glowcolor"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["r"] = element.glow_color[0]; - color["g"] = element.glow_color[1]; - color["b"] = element.glow_color[2]; - color["a"] = element.glow_color[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.glow_color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; - element.glow_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; - element.glow_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; - element.glow_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; - } - ); - - element_type["backcolor"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["r"] = element.background_color[0]; - color["g"] = element.background_color[1]; - color["b"] = element.background_color[2]; - color["a"] = element.background_color[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.background_color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; - element.background_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; - element.background_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; - element.background_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; - } - ); - - element_type["bordercolor"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["r"] = element.border_color[0]; - color["g"] = element.border_color[1]; - color["b"] = element.border_color[2]; - color["a"] = element.border_color[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.border_color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; - element.border_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; - element.border_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; - element.border_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; - } - ); - - element_type["borderwidth"] = sol::property( - [](element& element, const sol::this_state s) - { - auto color = sol::table::create(s.lua_state()); - color["top"] = element.border_width[0]; - color["right"] = element.border_width[1]; - color["bottom"] = element.border_width[2]; - color["left"] = element.border_width[3]; - return color; - }, - [](element& element, const sol::lua_table color) - { - element.border_width[0] = color["top"].get_type() == sol::type::number ? color["top"].get() : 0.f; - element.border_width[1] = color["right"].get_type() == sol::type::number ? color["right"].get() : element.border_width[1]; - element.border_width[2] = color["bottom"].get_type() == sol::type::number ? color["bottom"].get() : element.border_width[2]; - element.border_width[3] = color["left"].get_type() == sol::type::number ? color["left"].get() : element.border_width[3]; - } - ); - - element_type["font"] = sol::property( - [](element& element) - { - return element.font; - }, - [](element& element, const std::string& font) - { - element.set_font(font); - } - ); - - element_type["fontsize"] = sol::property( - [](element& element) - { - return element.fontsize; - }, - [](element& element, float fontsize) - { - element.fontsize = (int)fontsize; - } - ); - - element_type["onnotify"] = [&handler](element& element, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.element = &element; - listener.event = event; - listener.is_volatile = false; - - return handler.add_event_listener(std::move(listener)); - }; - - element_type["onnotifyonce"] = [&handler](element& element, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.element = &element; - listener.event = event; - listener.is_volatile = true; - - return handler.add_event_listener(std::move(listener)); - }; - - element_type["notify"] = [&handler](element& element, const sol::this_state s, const std::string& _event, - sol::variadic_args va) - { - event event; - event.element = &element; - event.name = _event; - - for (auto arg : va) - { - event.arguments.push_back(convert({s, arg})); - } - - notify(event); - }; - - element_type["hidden"] = sol::property( - [](element& element) - { - return element.hidden; - }, - [](element& element, bool hidden) - { - element.hidden = hidden; - } - ); - - element_type[sol::meta_function::new_index] = [](element& element, const sol::this_state s, const std::string& attribute, const sol::lua_value& value) - { - element.attributes[attribute] = convert({s, value}); - }; - - element_type[sol::meta_function::index] = [](element& element, const sol::this_state s, const std::string& attribute) - { - if (element.attributes.find(attribute) == element.attributes.end()) - { - return sol::lua_value{s, sol::lua_nil}; - } - - return sol::lua_value{s, convert(s, element.attributes[attribute])}; - }; - } - - void setup_menu_type(sol::state& state, event_handler& handler, scheduler& scheduler) - { - auto menu_type = state.new_usertype("menu"); - - menu_type["onnotify"] = [&handler](menu& menu, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.element = &menu; - listener.event = event; - listener.is_volatile = false; - - return handler.add_event_listener(std::move(listener)); - }; - - menu_type["onnotifyonce"] = [&handler](menu& menu, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.element = &menu; - listener.event = event; - listener.is_volatile = true; - - return handler.add_event_listener(std::move(listener)); - }; - - menu_type["notify"] = [&handler](menu& element, const sol::this_state s, const std::string& _event, - sol::variadic_args va) - { - event event; - event.element = &element; - event.name = _event; - - for (auto arg : va) - { - event.arguments.push_back(convert({s, arg})); - } - - notify(event); - }; - - menu_type["addchild"] = [](const sol::this_state s, menu& menu, element& element) - { - menu.add_child(&element); - }; - - menu_type["cursor"] = sol::property( - [](menu& menu) - { - return menu.cursor; - }, - [](menu& menu, bool cursor) - { - menu.cursor = cursor; - } - ); - - menu_type["hidden"] = sol::property( - [](menu& menu) - { - return menu.hidden; - }, - [](menu& menu, bool hidden) - { - menu.hidden = hidden; - } - ); - - menu_type["ignoreevents"] = sol::property( - [](menu& menu) - { - return menu.ignoreevents; - }, - [](menu& menu, bool ignoreevents) - { - menu.ignoreevents = ignoreevents; - } - ); - - menu_type["isopen"] = [](menu& menu) - { - return menu.visible || (menu.type == menu_type::overlay && game::Menu_IsMenuOpenAndVisible(0, menu.overlay_menu.data())); - }; - - menu_type["open"] = [&handler](menu& menu) - { - event event; - event.element = &menu; - event.name = "close"; - notify(event); - - menu.open(); - }; - - menu_type["close"] = [&handler](menu& menu) - { - event event; - event.element = &menu; - event.name = "close"; - notify(event); - - menu.close(); - }; - - menu_type["getelement"] = [](menu& menu, const sol::this_state s, const sol::lua_value& value, const std::string& attribute) - { - const auto value_ = convert({s, value}); - - for (const auto& element : menu.children) - { - if (element->attributes.find(attribute) != element->attributes.end() && element->attributes[attribute] == value_) - { - return sol::lua_value{s, element}; - } - } - - return sol::lua_value{s, sol::lua_nil}; - }; - - menu_type["getelements"] = sol::overload - ( - [](menu& menu, const sol::this_state s, const sol::lua_value& value, const std::string& attribute) - { - const auto value_ = convert({s, value}); - auto result = sol::table::create(s.lua_state()); - - for (const auto& element : menu.children) - { - if (element->attributes.find(attribute) != element->attributes.end() && element->attributes[attribute] == value_) - { - result.add(element); - } - } - - return result; - }, - [](menu& menu, const sol::this_state s) - { - auto result = sol::table::create(s.lua_state()); - - for (const auto& element : menu.children) - { - result.add(element); - } - - return result; - } - ); - } - void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler) { struct game @@ -721,137 +215,17 @@ namespace ui_scripting::lua auto game_type = state.new_usertype("game_"); state["game"] = game(); - game_type["getmenu"] = [](const game&, const sol::this_state s, const std::string& name) - { - if (menus.find(name) == menus.end()) - { - return sol::lua_value{s, sol::lua_nil}; - } - - return sol::lua_value{s, &menus[name]}; - }; - - game_type["getelement"] = [](const game&, const sol::this_state s, const sol::lua_value& value, const std::string& attribute) - { - const auto value_ = convert({s, value}); - - for (const auto& element : elements) - { - if (element->attributes.find(attribute) != element->attributes.end() && element->attributes[attribute] == value_) - { - return sol::lua_value{s, element}; - } - } - - return sol::lua_value{s, sol::lua_nil}; - }; - - game_type["getelements"] = sol::overload - ( - [](const game&, const sol::this_state s, const sol::lua_value& value, const std::string& attribute) - { - const auto value_ = convert({s, value}); - auto result = sol::table::create(s.lua_state()); - - for (const auto& element : elements) - { - if (element->attributes.find(attribute) != element->attributes.end() && element->attributes[attribute] == value_) - { - result.add(element); - } - } - - return result; - }, - [](const game&, const sol::this_state s) - { - auto result = sol::table::create(s.lua_state()); - - for (const auto& element : elements) - { - result.add(element); - } - - return result; - } - ); - game_type["time"] = []() { const auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); return now.count(); }; - game_type["newmenu"] = [](const game&, const std::string& name) - { - menus[name] = {}; - return &menus[name]; - }; - game_type["executecommand"] = [](const game&, const std::string& command) { command::execute(command, false); }; - game_type["luiopen"] = [](const game&, const std::string& menu) - { - ::scheduler::once([menu]() - { - ::game::LUI_OpenMenu(0, menu.data(), 0, 0, 0); - }, ::scheduler::pipeline::renderer); - }; - - game_type["newmenuoverlay"] = [](const game&, const std::string& name, const std::string& menu_name) - { - menus[name] = {}; - menus[name].type = menu_type::overlay; - menus[name].overlay_menu = menu_name; - return &menus[name]; - }; - - game_type["getmouseposition"] = [](const sol::this_state s, const game&) - { - auto pos = sol::table::create(s.lua_state()); - pos["x"] = mouse[0]; - pos["y"] = mouse[1]; - - return pos; - }; - - game_type["openmenu"] = [&handler](const game&, const std::string& name) - { - if (menus.find(name) == menus.end()) - { - return; - } - - const auto menu = &menus[name]; - - event event; - event.element = menu; - event.name = "open"; - notify(event); - - menu->open(); - }; - - game_type["closemenu"] = [&handler](const game&, const std::string& name) - { - if (menus.find(name) == menus.end()) - { - return; - } - - const auto menu = &menus[name]; - - event event; - event.element = menu; - event.name = "close"; - notify(event); - - menu->close(); - }; - game_type["onframe"] = [&scheduler](const game&, const sol::protected_function& callback) { return scheduler.add(callback, 0, false); @@ -874,7 +248,6 @@ namespace ui_scripting::lua { event_listener listener{}; listener.callback = callback; - listener.element = &ui_element; listener.event = event; listener.is_volatile = false; @@ -886,7 +259,6 @@ namespace ui_scripting::lua { event_listener listener{}; listener.callback = callback; - listener.element = &ui_element; listener.event = event; listener.is_volatile = true; @@ -991,49 +363,6 @@ namespace ui_scripting::lua (0x71B970_b)(video.data(), 64, 0); }; - game_type[sol::meta_function::index] = [](const game&, const std::string& name) - { - return [name](const game&, const sol::this_state s, sol::variadic_args va) - { - arguments arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - const auto values = call(name, arguments); - std::vector returns; - - for (const auto& value : values) - { - returns.push_back(convert(s, value)); - } - - return sol::as_returns(returns); - }; - }; - - game_type["call"] = [](const game&, const sol::this_state s, const std::string& name, sol::variadic_args va) - { - arguments arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - const auto values = call(name, arguments); - std::vector returns; - - for (const auto& value : values) - { - returns.push_back(convert(s, value)); - } - - return sol::as_returns(returns); - }; - game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value) { scripting::shared_table.access([key, value](scripting::shared_table_t& table) @@ -1116,7 +445,6 @@ namespace ui_scripting::lua ::scheduler::once([result, id] { event event; - event.element = &ui_element; event.name = "http_request_done"; if (result.has_value()) @@ -1129,7 +457,7 @@ namespace ui_scripting::lua } notify(event); - }, ::scheduler::pipeline::renderer); + }, ::scheduler::pipeline::lui); }, ::scheduler::pipeline::async); return id; }; @@ -1140,25 +468,55 @@ namespace ui_scripting::lua const auto id = request_id++; ::scheduler::once([url, id, dest]() { - const auto result = utils::http::get_data(url); - ::scheduler::once([result, 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) { - event event; - event.element = &ui_element; - event.name = "http_request_done"; - - if (result.has_value()) + const auto now = std::chrono::high_resolution_clock::now(); + if (now - last_report < 100ms && progress < total) { - const auto write = utils::io::write_file(dest, result.value(), false); + 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}; - } - else - { - event.arguments = {id, false}; - } - notify(event); - }, ::scheduler::pipeline::renderer); + 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; }; @@ -1243,31 +601,6 @@ namespace ui_scripting::lua } ); - for (const auto method : methods) - { - const auto name = method.first; - - userdata_type[name] = [name](const userdata& userdata, const sol::this_state s, sol::variadic_args va) - { - arguments arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - const auto values = call_method(userdata, name, arguments); - std::vector returns; - - for (const auto& value : values) - { - returns.push_back(convert(s, value)); - } - - return sol::as_returns(returns); - }; - } - userdata_type[sol::meta_function::index] = [](const userdata& userdata, const sol::this_state s, const std::string& name) { @@ -1344,8 +677,6 @@ namespace ui_scripting::lua state["LUI"] = state["luiglobals"]["LUI"]; state["Engine"] = state["luiglobals"]["Engine"]; state["Game"] = state["luiglobals"]["Game"]; - - state.script(animation_script); } } @@ -1365,8 +696,6 @@ namespace ui_scripting::lua setup_io(this->state_); setup_json(this->state_); setup_vector_type(this->state_); - setup_element_type(this->state_, this->event_handler_, this->scheduler_); - setup_menu_type(this->state_, this->event_handler_, this->scheduler_); 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/context.hpp b/src/client/game/ui_scripting/lua/context.hpp index 6b05116c..22c27e35 100644 --- a/src/client/game/ui_scripting/lua/context.hpp +++ b/src/client/game/ui_scripting/lua/context.hpp @@ -1,7 +1,6 @@ #pragma once #include "../event.hpp" -#include "../menu.hpp" #pragma warning(push) #pragma warning(disable: 4702) @@ -21,11 +20,6 @@ namespace ui_scripting::lua code }; - extern std::unordered_map menus; - extern std::vector elements; - extern element ui_element; - extern int mouse[2]; - class context { public: diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index e7450a72..b204a78b 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -15,290 +15,27 @@ namespace ui_scripting::lua::engine { const auto updater_script = utils::nt::load_resource(LUI_UPDATER_MENU); - float screen_max[2]; - - void check_resize() - { - screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0]; - screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1]; - } - - int relative_mouse(int value) - { - return (int)ceil(((float)value / screen_max[0]) * 1920.f); - } - - int relative(int value) - { - return (int)ceil(((float)value / 1920.f) * screen_max[0]); - } - - float relative(float value) - { - return ceil((value / 1920.f) * screen_max[0]); - } - - bool point_in_rect(int px, int py, int x, int y, int w, int h) - { - return (px > x && px < x + w && py > y && py < y + h); - } - - bool is_menu_visible(const menu& menu) - { - return menu.visible && !menu.hidden || (!menu.hidden && menu.type == menu_type::overlay && game::Menu_IsMenuOpenAndVisible(0, menu.overlay_menu.data())); - } - - std::vector elements_in_point(int x, int y) - { - std::vector result; - - for (const auto& menu : menus) - { - if (!is_menu_visible(menu.second) || menu.second.ignoreevents) - { - continue; - } - - for (const auto& child : menu.second.children) - { - if (child->hidden) - { - continue; - } - - const auto in_rect = point_in_rect( - x, y, - (int)child->x, - (int)child->y, - (int)child->w + (int)child->border_width[1] + (int)child->border_width[3], - (int)child->h + (int)child->border_width[0] + (int)child->border_width[2] - ); - - if (in_rect) - { - result.push_back(child); - } - } - } - - return result; - } - void handle_key_event(const int key, const int down) { - const auto _elements = elements_in_point(mouse[0], mouse[1]); + event event; + event.name = down + ? "keydown" + : "keyup"; + event.arguments = {key}; - switch (key) - { - case game::K_MOUSE2: - case game::K_MOUSE1: - { - const auto click_name = key == game::K_MOUSE1 - ? "click" - : "rightclick"; - - const auto key_name = key == game::K_MOUSE1 - ? "mouse" - : "rightmouse"; - - { - event main_event; - main_event.element = &ui_element; - main_event.name = utils::string::va("%s%s", key_name, down ? "down" : "up"); - main_event.arguments = - { - mouse[0], - mouse[1], - }; - - engine::notify(main_event); - - for (const auto& element : _elements) - { - event event; - event.element = element; - event.name = utils::string::va("%s%s", key_name, down ? "down" : "up"); - event.arguments = - { - mouse[0], - mouse[1], - }; - - engine::notify(event); - } - } - - if (!down) - { - event main_event; - main_event.element = &ui_element; - main_event.name = click_name; - main_event.arguments = - { - mouse[0], - mouse[1], - }; - - engine::notify(main_event); - - for (const auto& element : _elements) - { - event event; - event.element = element; - event.name = click_name; - event.arguments = - { - mouse[0], - mouse[1], - }; - - engine::notify(event); - } - } - - break; - } - case game::K_MWHEELUP: - case game::K_MWHEELDOWN: - { - const auto key_name = key == game::K_MWHEELUP - ? "scrollup" - : "scrolldown"; - - if (!down) - { - break; - } - - { - event main_event; - main_event.element = &ui_element; - main_event.name = key_name; - main_event.arguments = - { - mouse[0], - mouse[1], - }; - - engine::notify(main_event); - - for (const auto& element : _elements) - { - event event; - event.element = element; - event.name = key_name; - event.arguments = {mouse[0], mouse[1]}; - - engine::notify(event); - } - } - - break; - } - default: - { - event event; - event.element = &ui_element; - event.name = down - ? "keydown" - : "keyup"; - event.arguments = {key}; - - engine::notify(event); - - break; - } - } + engine::notify(event); } void handle_char_event(const int key) { std::string key_str = {(char)key}; event event; - event.element = &ui_element; event.name = "keypress"; event.arguments = {key_str}; engine::notify(event); } - std::vector previous_elements; - void handle_mousemove_event(const int x, const int y) - { - if (mouse[0] == x && mouse[1] == y) - { - return; - } - - mouse[0] = x; - mouse[1] = y; - - { - event event; - event.element = &ui_element; - event.name = "mousemove"; - event.arguments = {x, y}; - - engine::notify(event); - } - - const auto _elements = elements_in_point(x, y); - for (const auto& element : _elements) - { - event event; - event.element = element; - event.name = "mouseover"; - - engine::notify(event); - } - - for (const auto& element : previous_elements) - { - auto found = false; - - for (const auto& _element : _elements) - { - if (element == _element) - { - found = true; - } - } - - if (!found) - { - event event; - event.element = element; - event.name = "mouseleave"; - - engine::notify(event); - } - } - - for (const auto& element : _elements) - { - auto found = false; - - for (const auto& _element : previous_elements) - { - if (element == _element) - { - found = true; - } - } - - if (!found) - { - event event; - event.element = element; - event.name = "mouseenter"; - - engine::notify(event); - } - } - - previous_elements = _elements; - } - auto& get_scripts() { static std::vector> scripts{}; @@ -327,91 +64,12 @@ namespace ui_scripting::lua::engine { get_scripts().push_back(std::make_unique(code, script_type::code)); } - - void render_menus() - { - check_resize(); - - for (auto& menu : menus) - { - if (is_menu_visible(menu.second)) - { - menu.second.render(); - } - } - } - - void close_all_menus() - { - for (auto& menu : menus) - { - if (!is_menu_visible(menu.second)) - { - continue; - } - - event event; - event.element = &menu.second; - event.name = "close"; - engine::notify(event); - - menu.second.close(); - } - } - - void clear_menus() - { - menus.clear(); - - for (const auto element : elements) - { - delete element; - } - - elements.clear(); - } - } - - void open_menu(const std::string& name) - { - if (menus.find(name) == menus.end()) - { - return; - } - - const auto menu = &menus[name]; - - event event; - event.element = menu; - event.name = "open"; - engine::notify(event); - - menu->open(); - } - - void close_menu(const std::string& name) - { - if (menus.find(name) == menus.end()) - { - return; - } - - const auto menu = &menus[name]; - - event event; - event.element = menu; - event.name = "close"; - engine::notify(event); - - menu->close(); } void start() { clear_converted_functions(); - close_all_menus(); get_scripts().clear(); - clear_menus(); load_code(updater_script); @@ -428,9 +86,7 @@ namespace ui_scripting::lua::engine void stop() { clear_converted_functions(); - close_all_menus(); get_scripts().clear(); - clear_menus(); } void ui_event(const std::string& type, const std::vector& arguments) @@ -444,11 +100,6 @@ namespace ui_scripting::lua::engine { handle_char_event(arguments[0]); } - - if (type == "mousemove") - { - handle_mousemove_event(relative_mouse(arguments[0]), relative_mouse(arguments[1])); - } } void notify(const event& e) @@ -461,9 +112,6 @@ namespace ui_scripting::lua::engine void run_frame() { - check_resize(); - render_menus(); - for (auto& script : get_scripts()) { script->run_frame(); diff --git a/src/client/game/ui_scripting/lua/engine.hpp b/src/client/game/ui_scripting/lua/engine.hpp index 8616d6f5..27c5123e 100644 --- a/src/client/game/ui_scripting/lua/engine.hpp +++ b/src/client/game/ui_scripting/lua/engine.hpp @@ -7,9 +7,6 @@ namespace ui_scripting::lua::engine void start(); void stop(); - void close_menu(const std::string& name); - void open_menu(const std::string& name); - 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/lua/event_handler.cpp b/src/client/game/ui_scripting/lua/event_handler.cpp index b215fef1..8d123f29 100644 --- a/src/client/game/ui_scripting/lua/event_handler.cpp +++ b/src/client/game/ui_scripting/lua/event_handler.cpp @@ -17,9 +17,9 @@ namespace ui_scripting::lua this->remove(handle); }; - event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const element* entity, const std::string& event) + event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const std::string& event) { - this->add_endon_condition(handle, entity, event); + this->add_endon_condition(handle, event); }; } @@ -35,7 +35,7 @@ namespace ui_scripting::lua for (auto i = tasks.begin(); i != tasks.end();) { - if (i->event != event.name || i->element != event.element) + if (i->event != event.name) { ++i; continue; @@ -78,8 +78,7 @@ namespace ui_scripting::lua return {id}; } - void event_handler::add_endon_condition(const event_listener_handle& handle, const element* element, - const std::string& event) + void event_handler::add_endon_condition(const event_listener_handle& handle, const std::string& event) { auto merger = [&](task_list& tasks) { @@ -87,7 +86,7 @@ namespace ui_scripting::lua { if (task.id == handle.id) { - task.endon_conditions.emplace_back((uint64_t)element, event); + task.endon_conditions.emplace_back(event); } } }; @@ -150,7 +149,7 @@ namespace ui_scripting::lua { for (auto& condition : task.endon_conditions) { - if (condition.first == (uint64_t)event.element && condition.second == event.name) + if (condition == event.name) { task.is_deleted = true; break; diff --git a/src/client/game/ui_scripting/lua/event_handler.hpp b/src/client/game/ui_scripting/lua/event_handler.hpp index a203a23a..abf1415e 100644 --- a/src/client/game/ui_scripting/lua/event_handler.hpp +++ b/src/client/game/ui_scripting/lua/event_handler.hpp @@ -16,11 +16,10 @@ namespace ui_scripting::lua { public: std::string event = {}; - void* element{}; event_callback callback = {}; bool is_volatile = false; bool is_deleted = false; - std::vector> endon_conditions{}; + std::vector endon_conditions{}; }; class event_handler final @@ -52,7 +51,7 @@ namespace ui_scripting::lua void merge_callbacks(); void handle_endon_conditions(const event& event); - void add_endon_condition(const event_listener_handle& handle, const element* element, const std::string& event); + void add_endon_condition(const event_listener_handle& handle, const std::string& event); event_arguments build_arguments(const event& event) const; }; diff --git a/src/client/game/ui_scripting/lua/scheduler.cpp b/src/client/game/ui_scripting/lua/scheduler.cpp index 8ecb930a..99cac9a5 100644 --- a/src/client/game/ui_scripting/lua/scheduler.cpp +++ b/src/client/game/ui_scripting/lua/scheduler.cpp @@ -13,9 +13,9 @@ namespace ui_scripting::lua this->remove(handle); }; - task_handle_type["endon"] = [this](const task_handle& handle, const element* element, const std::string& event) + task_handle_type["endon"] = [this](const task_handle& handle, const std::string& event) { - this->add_endon_condition(handle, element, event); + this->add_endon_condition(handle, event); }; } @@ -27,7 +27,7 @@ namespace ui_scripting::lua { for (auto& condition : task.endon_conditions) { - if (condition.first == (uint64_t)event.element && condition.second == event.name) + if (condition == event.name) { task.is_deleted = true; break; @@ -118,7 +118,7 @@ namespace ui_scripting::lua return {id}; } - void scheduler::add_endon_condition(const task_handle& handle, const element* element, const std::string& event) + void scheduler::add_endon_condition(const task_handle& handle, const std::string& event) { auto merger = [&](task_list& tasks) { @@ -126,7 +126,7 @@ namespace ui_scripting::lua { if (task.id == handle.id) { - task.endon_conditions.emplace_back(element->id, event); + task.endon_conditions.emplace_back(event); } } }; diff --git a/src/client/game/ui_scripting/lua/scheduler.hpp b/src/client/game/ui_scripting/lua/scheduler.hpp index ac730a03..26ab9c32 100644 --- a/src/client/game/ui_scripting/lua/scheduler.hpp +++ b/src/client/game/ui_scripting/lua/scheduler.hpp @@ -19,7 +19,7 @@ namespace ui_scripting::lua std::chrono::milliseconds delay{}; bool is_volatile = false; bool is_deleted = false; - std::vector> endon_conditions{}; + std::vector endon_conditions{}; }; class scheduler final @@ -46,7 +46,7 @@ namespace ui_scripting::lua utils::concurrency::container callbacks_; std::atomic_int64_t current_task_id_ = 0; - void add_endon_condition(const task_handle& handle, const element* element, const std::string& event); + void add_endon_condition(const task_handle& handle, const std::string& event); void remove(const task_handle& handle); void merge_callbacks(); diff --git a/src/client/game/ui_scripting/menu.cpp b/src/client/game/ui_scripting/menu.cpp deleted file mode 100644 index 900c244f..00000000 --- a/src/client/game/ui_scripting/menu.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include "menu.hpp" -#include "lua/engine.hpp" -#include "component/ui_scripting.hpp" - -namespace ui_scripting -{ - menu::menu() - { - } - - void menu::add_child(element* el) - { - this->children.push_back(el); - } - - void menu::open() - { - if (this->visible) - { - return; - } - - this->cursor_was_enabled = *game::keyCatchers & 0x40; - if (this->cursor) - { - *game::keyCatchers |= 0x40; - } - - this->visible = true; - } - - void menu::close() - { - if (!this->visible) - { - return; - } - - if (this->cursor && !this->cursor_was_enabled) - { - *game::keyCatchers &= ~0x40; - } - - this->visible = false; - } - - void menu::render() - { - if (this->cursor && !(*game::keyCatchers & 0x40)) - { - this->visible = false; - return; - } - - for (auto& element : this->children) - { - if (element->hidden) - { - continue; - } - - element->render(); - } - } -} diff --git a/src/client/game/ui_scripting/menu.hpp b/src/client/game/ui_scripting/menu.hpp deleted file mode 100644 index cd975c46..00000000 --- a/src/client/game/ui_scripting/menu.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "element.hpp" - -namespace ui_scripting -{ - enum menu_type - { - normal, - overlay - }; - - class menu final - { - public: - menu(); - - bool visible = false; - bool hidden = false; - bool cursor = false; - bool ignoreevents = false; - bool cursor_was_enabled = false; - - void open(); - void close(); - - void add_child(element* el); - void render(); - - menu_type type = normal; - - std::string overlay_menu; - std::vector children{}; - }; -} diff --git a/src/client/resource.hpp b/src/client/resource.hpp index 2005d4f1..a5a6b649 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -17,10 +17,8 @@ #define MENU_MAIN 310 #define TLS_DLL 311 -#define RUNNER 312 -#define ICON_IMAGE 313 +#define ICON_IMAGE 312 -#define LUA_ANIMATION_SCRIPT 314 -#define LUA_JSON_SCRIPT 315 -#define LUI_UPDATER_MENU 316 +#define LUA_JSON_SCRIPT 313 +#define LUI_UPDATER_MENU 314 diff --git a/src/client/resource.rc b/src/client/resource.rc index 65467a1d..b42a1e0c 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -97,9 +97,7 @@ ID_ICON ICON "resources/icon.ico" MENU_MAIN RCDATA "resources/main.html" -LUA_ANIMATION_SCRIPT RCDATA "resources/animation.lua" LUA_JSON_SCRIPT RCDATA "resources/json.lua" - LUI_UPDATER_MENU RCDATA "resources/updater.lua" #ifdef _DEBUG @@ -108,12 +106,6 @@ TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll" TLS_DLL RCDATA "../../build/bin/x64/Release/tlsdll.dll" #endif -#ifdef _DEBUG -RUNNER RCDATA "../../build/bin/x64/Debug/runner.exe" -#else -RUNNER RCDATA "../../build/bin/x64/Release/runner.exe" -#endif - ICON_IMAGE RCDATA "resources/icon.png" #endif // English (United States) resources diff --git a/src/client/resources/animation.lua b/src/client/resources/animation.lua deleted file mode 100644 index 0294c264..00000000 --- a/src/client/resources/animation.lua +++ /dev/null @@ -1,92 +0,0 @@ -function element:animate(name, state, animationtime) - local start = { - x = self.x, - y = self.y, - w = self.w, - h = self.h, - color = self.color, - backcolor = self.backcolor, - bordercolor = self.bordercolor, - borderwidth = self.borderwidth, - fontsize = self.fontsize - } - - local _end = {} - for k, v in pairs(start) do - _end[k] = state[k] or v - end - - local diffs = {} - for k, v in pairs(_end) do - if (type(v) == "table") then - local value = {} - local different = false - - for _k, _v in pairs(v) do - value[_k] = _v - start[k][_k] - if (value[_k] ~= 0) then - different = true - end - end - - if (different) then - diffs[k] = value - end - else - local value = v - start[k] - if (value ~= 0) then - diffs[k] = v - start[k] - end - end - end - - local timeout = nil - local interval = nil - local starttime = game:time() - - interval = game:onframe(function() - local time = game:time() - local percentage = (time - starttime) / animationtime - - if (percentage >= 1) then - for k, v in pairs(diffs) do - self[k] = _end[k] - end - else - for k, v in pairs(diffs) do - if (type(v) == "table") then - local value = {} - - for _k, _v in pairs(v) do - value[_k] = start[k][_k] + _v * percentage - end - - self[k] = value - else - self[k] = start[k] + v * percentage - end - end - end - end) - - timeout = game:ontimeout(function() - interval:clear() - for k, v in pairs(diffs) do - self[k] = _end[k] - end - end, animationtime) - - self:onnotifyonce("cancel_animation", function(_name) - if (name == _name) then - timeout:clear() - interval:clear() - end - end) -end - -function element:cancelanimations(name, callback) - self:notify("cancel_animation", name) - if (type(callback) == "function") then - game:ontimeout(callback, 0) - end -end \ No newline at end of file diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 4a095e80..b426086a 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -10,6 +10,7 @@ #pragma warning(disable: 4702) #pragma warning(disable: 4996) #pragma warning(disable: 5054) +#pragma warning(disable: 5056) #pragma warning(disable: 6011) #pragma warning(disable: 6297) #pragma warning(disable: 6385) diff --git a/src/common/utils/http.cpp b/src/common/utils/http.cpp index 6a167260..fca7d8f3 100644 --- a/src/common/utils/http.cpp +++ b/src/common/utils/http.cpp @@ -10,19 +10,25 @@ namespace utils::http { struct progress_helper { - const std::function* callback{}; + const std::function* callback{}; std::exception_ptr exception{}; + std::chrono::high_resolution_clock::time_point start{}; }; - int progress_callback(void *clientp, const curl_off_t /*dltotal*/, const curl_off_t dlnow, const curl_off_t /*ultotal*/, const curl_off_t /*ulnow*/) + int progress_callback(void *clientp, const curl_off_t dltotal, const curl_off_t dlnow, const curl_off_t /*ultotal*/, const curl_off_t /*ulnow*/) { auto* helper = static_cast(clientp); 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 speed = dlnow / count; + if (*helper->callback) { - (*helper->callback)(dlnow); + (*helper->callback)(dlnow, dltotal, speed); } } catch(...) @@ -44,7 +50,8 @@ namespace utils::http } } - std::optional get_data(const std::string& url, const headers& headers, const std::function& callback) + std::optional get_data(const std::string& url, const headers& headers, + const std::function& callback) { curl_slist* header_list = nullptr; auto* curl = curl_easy_init(); @@ -68,6 +75,7 @@ namespace utils::http std::string buffer{}; progress_helper helper{}; helper.callback = &callback; + helper.start = std::chrono::high_resolution_clock::now(); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); curl_easy_setopt(curl, CURLOPT_URL, url.data()); @@ -82,7 +90,7 @@ namespace utils::http return {std::move(buffer)}; } - if(helper.exception) + if (helper.exception) { std::rethrow_exception(helper.exception); } diff --git a/src/common/utils/http.hpp b/src/common/utils/http.hpp index b5248bc9..9ff30737 100644 --- a/src/common/utils/http.hpp +++ b/src/common/utils/http.hpp @@ -8,6 +8,7 @@ namespace utils::http { using headers = std::unordered_map; - std::optional get_data(const std::string& url, const headers& headers = {}, const std::function& callback = {}); + std::optional get_data(const std::string& url, const headers& headers = {}, + const std::function& callback = {}); std::future> get_data_async(const std::string& url, const headers& headers = {}); } diff --git a/src/runner/debugger.cpp b/src/runner/debugger.cpp deleted file mode 100644 index d58149b7..00000000 --- a/src/runner/debugger.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#define WIN32_LEAN_AND_MEAN -#include -#include "debugger.hpp" - -namespace -{ - bool acquire_debug_privilege() - { - TOKEN_PRIVILEGES token_privileges; - ZeroMemory(&token_privileges, sizeof(token_privileges)); - token_privileges.PrivilegeCount = 1; - - HANDLE token; - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) - { - return false; - } - - if (!LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, &token_privileges.Privileges[0].Luid)) - { - CloseHandle(token); - return false; - } - - token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - DWORD size; - if (!AdjustTokenPrivileges(token, FALSE, &token_privileges, 0, nullptr, &size)) - { - CloseHandle(token); - return false; - } - - return CloseHandle(token) != FALSE; - } -} - -debugger::debugger(const unsigned long process_id, const bool start) -{ - if (!start) - { - return; - } - - this->runner_ = std::thread([this, process_id]() - { - this->terminate_ = false; - this->run(process_id); - }); -} - -debugger::~debugger() -{ - this->terminate_ = true; - if (this->runner_.joinable()) - { - this->runner_.join(); - } -} - -void debugger::run(const unsigned long process_id) const -{ - acquire_debug_privilege(); - if (!DebugActiveProcess(process_id)) - { - return; - } - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); - - DEBUG_EVENT event; - while (!this->terminate_ && WaitForDebugEvent(&event,INFINITE)) - { - if (event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) - { - ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_EXCEPTION_NOT_HANDLED); - continue; - } - - if (event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) - { - ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); - break; - } - -#ifdef DEV_BUILD - if (event.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) - { - OutputDebugStringA("Debugger attached!\n"); - } -#endif - - ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); - } -} diff --git a/src/runner/debugger.hpp b/src/runner/debugger.hpp deleted file mode 100644 index 99d1073e..00000000 --- a/src/runner/debugger.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -class debugger -{ -public: - debugger(unsigned long process_id, bool start); - ~debugger(); - -private: - volatile bool terminate_ = false; - std::thread runner_; - - void run(unsigned long process_id) const; -}; diff --git a/src/runner/resource.rc b/src/runner/resource.rc deleted file mode 100644 index ba86c6f4..00000000 --- a/src/runner/resource.rc +++ /dev/null @@ -1,100 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "#include ""windows.h""\r\n" - "\0" -END - -2 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE VFT_DLL - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "X Labs" - VALUE "FileDescription", "Steam mod runner" - VALUE "FileVersion", "1.0.0.0" - VALUE "InternalName", "Runner" - VALUE "LegalCopyright", "All rights reserved." - VALUE "OriginalFilename", "runner.exe" - VALUE "ProductName", "runner" - VALUE "ProductVersion", "1.0.0.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -///////////////////////////////////////////////////////////////////////////// -// -// Binary Data -// - -102 ICON "../client/resources/icon.ico" - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/runner/runner.cpp b/src/runner/runner.cpp deleted file mode 100644 index 01c32d2e..00000000 --- a/src/runner/runner.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "debugger.hpp" - -int __stdcall WinMain(HINSTANCE, HINSTANCE, PSTR, int) -{ - const auto* const command = "-proc "; - const char* parent_proc = strstr(GetCommandLineA(), command); - - if (parent_proc) - { - const auto pid = DWORD(atoi(parent_proc + strlen(command))); - auto* const process_handle = OpenProcess(SYNCHRONIZE, FALSE, pid); - if (process_handle) - { - //debugger _(pid, strstr(GetCommandLineA(), "-debug ") != nullptr); - WaitForSingleObject(process_handle, INFINITE); - CloseHandle(process_handle); - return 0; - } - } - - return 1; -} diff --git a/tools/premake5.exe b/tools/premake5.exe index 0e4954fd..c73da1fb 100644 Binary files a/tools/premake5.exe and b/tools/premake5.exe differ