commit
886bd3f714
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -11,7 +11,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build binaries
|
name: Build binaries
|
||||||
runs-on: windows-latest
|
runs-on: windows-2022
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
configuration:
|
configuration:
|
||||||
@ -38,8 +38,8 @@ jobs:
|
|||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
|
|
||||||
- name: Generate project files
|
- name: Generate project files
|
||||||
#run: tools/premake5 vs2019 --ci-build
|
#run: tools/premake5 vs2022 --ci-build
|
||||||
run: tools/premake5 vs2019
|
run: tools/premake5 vs2022
|
||||||
|
|
||||||
- name: Set up problem matching
|
- name: Set up problem matching
|
||||||
uses: ammaraskar/msvc-problem-matcher@master
|
uses: ammaraskar/msvc-problem-matcher@master
|
||||||
|
@ -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
|
academic research. It is not intended to be used to attack
|
||||||
other systems. Project maintainers are not responsible or
|
other systems. Project maintainers are not responsible or
|
||||||
liable for misuse of the software. Use responsibly.
|
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/)
|
||||||
|
@ -4,8 +4,8 @@ version: "#{build} ({branch})"
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
PREMAKE_ACTION: vs2019
|
PREMAKE_ACTION: vs2022
|
||||||
CI: 1
|
CI: 1
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
|
@ -85,6 +85,7 @@ LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1)
|
|||||||
if (io.directoryexists("mods")) then
|
if (io.directoryexists("mods")) then
|
||||||
local mods = io.listfiles("mods/")
|
local mods = io.listfiles("mods/")
|
||||||
for i = 1, #mods do
|
for i = 1, #mods do
|
||||||
|
if (io.directoryexists(mods[i]) and not io.directoryisempty(mods[i])) then
|
||||||
local name, desc = getmodname(mods[i])
|
local name, desc = getmodname(mods[i])
|
||||||
|
|
||||||
if (mods[i] ~= modfolder) then
|
if (mods[i] ~= modfolder) then
|
||||||
@ -96,6 +97,7 @@ LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
menu:AddBackButton(function(a1)
|
menu:AddBackButton(function(a1)
|
||||||
Engine.PlaySound(CoD.SFX.MenuBack)
|
Engine.PlaySound(CoD.SFX.MenuBack)
|
||||||
|
2
deps/asmjit
vendored
2
deps/asmjit
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9a92d2f97260749f6f29dc93e53c743448f0137a
|
Subproject commit 28c4d8c528527141955006f09124ce672ddfbe3f
|
2
deps/curl
vendored
2
deps/curl
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9f1d29ecacffe3e94349bcef6e9fafa62b1cc431
|
Subproject commit 049f3765c7016a3f7a92b7f88aae6405c49b84fb
|
2
deps/imgui
vendored
2
deps/imgui
vendored
@ -1 +1 @@
|
|||||||
Subproject commit f07df31745296090ac7ecc01811f88c85766028a
|
Subproject commit fc84214988b74179b3941d35393c24ee8ba7a794
|
2
deps/libtommath
vendored
2
deps/libtommath
vendored
@ -1 +1 @@
|
|||||||
Subproject commit bea9270646303baf683f4ba2ddf0d70721f0e55d
|
Subproject commit 04e9d1e7a0493910b2eb5e757d623870692ada04
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 3ea30d80847cd9561db570ae7f673afc15523545
|
Subproject commit 2f7ee91e326d95915b63918f968244cfefbc022a
|
2
deps/rapidjson
vendored
2
deps/rapidjson
vendored
@ -1 +1 @@
|
|||||||
Subproject commit fd3dc29a5c2852df569e1ea81dbde2c412ac5051
|
Subproject commit e4bde977440d4a00f820b6586899e48a972d2493
|
@ -1,3 +1,4 @@
|
|||||||
@echo off
|
@echo off
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
tools\premake5 %* vs2019
|
tools\premake5 %* vs2022
|
||||||
|
pause
|
46
premake5.lua
46
premake5.lua
@ -248,25 +248,23 @@ end
|
|||||||
|
|
||||||
flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"}
|
flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"}
|
||||||
|
|
||||||
|
filter "platforms:x64"
|
||||||
configuration "windows"
|
|
||||||
defines {"_WINDOWS", "WIN32"}
|
defines {"_WINDOWS", "WIN32"}
|
||||||
|
filter {}
|
||||||
|
|
||||||
configuration "Release"
|
filter "configurations:Release"
|
||||||
optimize "Size"
|
optimize "Size"
|
||||||
buildoptions {"/GL"}
|
buildoptions {"/GL"}
|
||||||
linkoptions { "/IGNORE:4702", "/LTCG" }
|
linkoptions { "/IGNORE:4702", "/LTCG" }
|
||||||
|
|
||||||
defines {"NDEBUG"}
|
defines {"NDEBUG"}
|
||||||
|
|
||||||
flags {"FatalCompileWarnings"}
|
flags {"FatalCompileWarnings"}
|
||||||
|
filter {}
|
||||||
|
|
||||||
configuration "Debug"
|
filter "configurations:Debug"
|
||||||
optimize "Debug"
|
optimize "Debug"
|
||||||
buildoptions {"/bigobj"}
|
buildoptions {"/bigobj"}
|
||||||
defines {"DEBUG", "_DEBUG"}
|
defines {"DEBUG", "_DEBUG"}
|
||||||
|
filter {}
|
||||||
configuration {}
|
|
||||||
|
|
||||||
project "common"
|
project "common"
|
||||||
kind "StaticLib"
|
kind "StaticLib"
|
||||||
@ -280,20 +278,6 @@ resincludedirs {"$(ProjectDir)src"}
|
|||||||
|
|
||||||
dependencies.imports()
|
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"
|
project "client"
|
||||||
kind "ConsoleApp"
|
kind "ConsoleApp"
|
||||||
language "C++"
|
language "C++"
|
||||||
@ -311,7 +295,7 @@ includedirs {"./src/client", "./src/common", "%{prj.location}/src"}
|
|||||||
|
|
||||||
resincludedirs {"$(ProjectDir)src"}
|
resincludedirs {"$(ProjectDir)src"}
|
||||||
|
|
||||||
dependson {"tlsdll", "runner"}
|
dependson {"tlsdll"}
|
||||||
|
|
||||||
links {"common"}
|
links {"common"}
|
||||||
|
|
||||||
@ -335,22 +319,6 @@ links {"common"}
|
|||||||
|
|
||||||
resincludedirs {"$(ProjectDir)src"}
|
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"
|
group "Dependencies"
|
||||||
dependencies.projects()
|
dependencies.projects()
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
|
#define ORIGINAL_BIND_COUNT 110
|
||||||
|
|
||||||
namespace binding
|
namespace binding
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
@ -24,7 +26,7 @@ namespace binding
|
|||||||
const auto* const key_button = game::Key_KeynumToString(key_index, 0, 1);
|
const auto* const key_button = game::Key_KeynumToString(key_index, 0, 1);
|
||||||
auto value = game::playerKeys->keys[key_index].binding;
|
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),
|
const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used),
|
||||||
"bind %s \"%s\"\n", key_button, game::command_whitelist[value]);
|
"bind %s \"%s\"\n", key_button, game::command_whitelist[value]);
|
||||||
@ -36,9 +38,9 @@ namespace binding
|
|||||||
|
|
||||||
bytes_used += len;
|
bytes_used += len;
|
||||||
}
|
}
|
||||||
else if (value >= 100)
|
else if (value >= ORIGINAL_BIND_COUNT)
|
||||||
{
|
{
|
||||||
value -= 100;
|
value -= ORIGINAL_BIND_COUNT;
|
||||||
if (static_cast<size_t>(value) < custom_binds.size() && !custom_binds[value].empty())
|
if (static_cast<size_t>(value) < custom_binds.size() && !custom_binds[value].empty())
|
||||||
{
|
{
|
||||||
const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used),
|
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)
|
int key_get_binding_for_cmd_stub(const char* command)
|
||||||
{
|
{
|
||||||
// original binds
|
// 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]))
|
if (game::command_whitelist[i] && !strcmp(command, game::command_whitelist[i]))
|
||||||
{
|
{
|
||||||
@ -89,14 +91,14 @@ namespace binding
|
|||||||
}
|
}
|
||||||
|
|
||||||
// custom binds
|
// 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)
|
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<size_t>(key) < custom_binds.size() && !custom_binds[key].empty())
|
if (static_cast<size_t>(key) < custom_binds.size() && !custom_binds[key].empty())
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,6 @@ namespace branding
|
|||||||
ui_scripting::push_value(VERSION);
|
ui_scripting::push_value(VERSION);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
@ -31,12 +30,15 @@ namespace branding
|
|||||||
15.f + static_cast<float>(font->pixelHeight),
|
15.f + static_cast<float>(font->pixelHeight),
|
||||||
1.f, 1.f, 0.f, color, 0);
|
1.f, 1.f, 0.f, color, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
|
scheduler::loop(draw, scheduler::pipeline::renderer);
|
||||||
|
|
||||||
localized_strings::override("MENU_SP_CAMPAIGN", "H2-MOD");
|
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_LINK", "Github Page:");
|
||||||
localized_strings::override("MENU_SYSINFO_CUSTOMER_SUPPORT_URL", "https://github.com/fedddddd/h2-mod");
|
localized_strings::override("MENU_SYSINFO_CUSTOMER_SUPPORT_URL", "https://github.com/fedddddd/h2-mod");
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace branding
|
|
||||||
{
|
|
||||||
void draw();
|
|
||||||
}
|
|
@ -279,7 +279,6 @@ namespace fps
|
|||||||
game::R_AddCmdDrawText(pos_string, 0x7FFFFFFF, font, x,
|
game::R_AddCmdDrawText(pos_string, 0x7FFFFFFF, font, x,
|
||||||
60.f, 1.0f, 1.0f, 0.0f, fps_color_ok, 0);
|
60.f, 1.0f, 1.0f, 0.0f, fps_color_ok, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
@ -295,12 +294,15 @@ namespace fps
|
|||||||
draw_speed();
|
draw_speed();
|
||||||
draw_speed_graph();
|
draw_speed_graph();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
|
scheduler::loop(draw, scheduler::pipeline::renderer);
|
||||||
|
|
||||||
sub_7C55D0_hook.create(0x7C55D0_b, perf_update);
|
sub_7C55D0_hook.create(0x7C55D0_b, perf_update);
|
||||||
|
|
||||||
cg_drawSpeed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED);
|
cg_drawSpeed = dvars::register_bool("cg_drawSpeed", 0, game::DVAR_FLAG_SAVED);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace fps
|
|
||||||
{
|
|
||||||
void draw();
|
|
||||||
}
|
|
@ -354,7 +354,6 @@ namespace game_console
|
|||||||
draw_output_scrollbar(x, y, width, height);
|
draw_output_scrollbar(x, y, width, height);
|
||||||
draw_output_text(x, y);
|
draw_output_text(x, y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void draw_console()
|
void draw_console()
|
||||||
{
|
{
|
||||||
@ -375,6 +374,7 @@ namespace game_console
|
|||||||
draw_input();
|
draw_input();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print(const int type, const char* fmt, ...)
|
void print(const int type, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
@ -719,6 +719,8 @@ namespace game_console
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
|
scheduler::loop(draw_console, scheduler::pipeline::renderer);
|
||||||
|
|
||||||
con.cursor = 0;
|
con.cursor = 0;
|
||||||
con.visible_line_count = 0;
|
con.visible_line_count = 0;
|
||||||
con.output_visible = false;
|
con.output_visible = false;
|
||||||
|
@ -9,8 +9,6 @@ namespace game_console
|
|||||||
con_type_info = 7
|
con_type_info = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw_console();
|
|
||||||
|
|
||||||
void print(int type, const char* fmt, ...);
|
void print(int type, const char* fmt, ...);
|
||||||
|
|
||||||
bool console_char_event(int local_client_num, int key);
|
bool console_char_event(int local_client_num, int key);
|
||||||
|
@ -37,14 +37,22 @@ namespace patches
|
|||||||
gscr_set_save_dvar_hook.invoke<void>();
|
gscr_set_save_dvar_hook.invoke<void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
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_hash = game::generateHashValue("cg_fov");
|
||||||
static const auto cg_fov_scale_hash = game::generateHashValue("cg_fovscale");
|
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<game::dvar_t*>(hash, dvarName, value, min, max, flags);
|
return dvar_register_float_hook.invoke<game::dvar_t*>(hash, dvarName, value, min, max, flags);
|
||||||
@ -75,7 +83,12 @@ namespace patches
|
|||||||
|
|
||||||
// Prevent game from overriding cg_fov and cg_fovscale values
|
// 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(0x504C60_b, &gscr_set_save_dvar_stub);
|
||||||
|
|
||||||
// Make cg_fov and cg_fovscale saved dvars
|
// 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);
|
dvar_register_float_hook.create(game::Dvar_RegisterFloat.get(), dvar_register_float_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -97,6 +97,11 @@ namespace scheduler
|
|||||||
void r_end_frame_stub()
|
void r_end_frame_stub()
|
||||||
{
|
{
|
||||||
execute(pipeline::renderer);
|
execute(pipeline::renderer);
|
||||||
|
if (game::Sys_IsMainThread())
|
||||||
|
{
|
||||||
|
execute(pipeline::lui);
|
||||||
|
}
|
||||||
|
|
||||||
r_end_frame_hook.invoke<void>();
|
r_end_frame_hook.invoke<void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ namespace scheduler
|
|||||||
// The game's rendering pipeline
|
// The game's rendering pipeline
|
||||||
renderer,
|
renderer,
|
||||||
|
|
||||||
|
lui,
|
||||||
|
|
||||||
// The game's server thread
|
// The game's server thread
|
||||||
server,
|
server,
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@
|
|||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
|
|
||||||
#include "game_console.hpp"
|
|
||||||
#include "fps.hpp"
|
|
||||||
#include "branding.hpp"
|
|
||||||
|
|
||||||
#include "ui_scripting.hpp"
|
#include "ui_scripting.hpp"
|
||||||
|
|
||||||
#include "game/ui_scripting/lua/engine.hpp"
|
#include "game/ui_scripting/lua/engine.hpp"
|
||||||
@ -23,41 +19,17 @@
|
|||||||
|
|
||||||
namespace ui_scripting
|
namespace ui_scripting
|
||||||
{
|
{
|
||||||
std::unordered_map<std::string, game::hks::lua_function> functions;
|
|
||||||
std::unordered_map<std::string, game::hks::lua_function> methods;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::unordered_map<game::hks::cclosure*, sol::protected_function> converted_functions;
|
std::unordered_map<game::hks::cclosure*, sol::protected_function> converted_functions;
|
||||||
|
|
||||||
utils::hook::detour hksi_open_lib_hook;
|
|
||||||
utils::hook::detour hksi_lual_error_hook;
|
utils::hook::detour hksi_lual_error_hook;
|
||||||
utils::hook::detour hksi_lual_error_hook2;
|
utils::hook::detour hksi_lual_error_hook2;
|
||||||
utils::hook::detour hksi_add_function_hook;
|
|
||||||
utils::hook::detour hks_start_hook;
|
utils::hook::detour hks_start_hook;
|
||||||
utils::hook::detour hks_shutdown_hook;
|
utils::hook::detour hks_shutdown_hook;
|
||||||
|
|
||||||
bool error_hook_enabled = false;
|
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<void*>(s, libname, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...)
|
void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
char va_buffer[2048] = {0};
|
char va_buffer[2048] = {0};
|
||||||
@ -86,8 +58,6 @@ namespace ui_scripting
|
|||||||
ui_scripting::lua::engine::start();
|
ui_scripting::lua::engine::start();
|
||||||
});
|
});
|
||||||
|
|
||||||
functions = {};
|
|
||||||
methods = {};
|
|
||||||
return hks_start_hook.invoke<void*>(a1);
|
return hks_start_hook.invoke<void*>(a1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,18 +66,6 @@ namespace ui_scripting
|
|||||||
ui_scripting::lua::engine::stop();
|
ui_scripting::lua::engine::stop();
|
||||||
hks_shutdown_hook.invoke<void*>();
|
hks_shutdown_hook.invoke<void*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
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<void>(s, f, a3, name, a5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main_function_handler(game::hks::lua_State* state)
|
int main_function_handler(game::hks::lua_State* state)
|
||||||
@ -167,26 +125,6 @@ namespace ui_scripting
|
|||||||
error_hook_enabled = false;
|
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)
|
void notify(const event& e)
|
||||||
{
|
{
|
||||||
lua::engine::notify(e);
|
lua::engine::notify(e);
|
||||||
@ -198,47 +136,12 @@ namespace ui_scripting
|
|||||||
|
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
scheduler::loop([]()
|
scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui);
|
||||||
{
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
hks_start_hook.create(0x328BE0_b, hks_start_stub);
|
hks_start_hook.create(0x328BE0_b, hks_start_stub);
|
||||||
hks_shutdown_hook.create(0x3203B0_b, hks_shutdown_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_hook.create(0x2E3E40_b, hksi_lual_error_stub);
|
||||||
hksi_lual_error_hook2.create(0x2DCB40_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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "game/ui_scripting/lua/value_conversion.hpp"
|
#include "game/ui_scripting/lua/value_conversion.hpp"
|
||||||
#include "game/ui_scripting/menu.hpp"
|
|
||||||
#include "game/ui_scripting/event.hpp"
|
#include "game/ui_scripting/event.hpp"
|
||||||
|
|
||||||
namespace ui_scripting
|
namespace ui_scripting
|
||||||
{
|
{
|
||||||
extern std::unordered_map<std::string, game::hks::lua_function> functions;
|
|
||||||
extern std::unordered_map<std::string, game::hks::lua_function> methods;
|
|
||||||
|
|
||||||
int main_function_handler(game::hks::lua_State* state);
|
int main_function_handler(game::hks::lua_State* state);
|
||||||
void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function);
|
void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function);
|
||||||
void clear_converted_functions();
|
void clear_converted_functions();
|
||||||
@ -15,8 +11,5 @@ namespace ui_scripting
|
|||||||
void enable_error_hook();
|
void enable_error_hook();
|
||||||
void disable_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);
|
void notify(const event& e);
|
||||||
}
|
}
|
||||||
|
@ -264,8 +264,6 @@ namespace scripting
|
|||||||
void array::set(const std::string& key, const script_value& _value) const
|
void array::set(const std::string& key, const script_value& _value) const
|
||||||
{
|
{
|
||||||
const auto value = _value.get_raw();
|
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);
|
const auto variable_id = this->get_value_id(key);
|
||||||
|
|
||||||
if (!variable_id)
|
if (!variable_id)
|
||||||
|
@ -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<std::string(*)(const std::string&)>(utils::io::read_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_vector_type(sol::state& state)
|
||||||
{
|
{
|
||||||
state["level"] = entity{*::game::levelEntityId};
|
state["level"] = entity{*::game::levelEntityId};
|
||||||
state["player"] = call("getentbynum", {0}).as<entity>();
|
state["player"] = call("getentbynum", {0}).as<entity>();
|
||||||
@ -181,6 +194,12 @@ namespace scripting::lua
|
|||||||
{
|
{
|
||||||
return call("anglestoforward", {a}).as<vector>();
|
return call("anglestoforward", {a}).as<vector>();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler)
|
||||||
|
{
|
||||||
|
state["level"] = entity{ *::game::levelEntityId };
|
||||||
|
state["player"] = call("getentbynum", { 0 }).as<entity>();
|
||||||
|
|
||||||
auto entity_type = state.new_usertype<entity>("entity");
|
auto entity_type = state.new_usertype<entity>("entity");
|
||||||
|
|
||||||
@ -307,7 +326,10 @@ namespace scripting::lua
|
|||||||
std::vector<unsigned int> returns = {entref.entnum, entref.classnum};
|
std::vector<unsigned int> returns = {entref.entnum, entref.classnum};
|
||||||
return sol::as_returns(returns);
|
return sol::as_returns(returns);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler)
|
||||||
|
{
|
||||||
struct game
|
struct game
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -407,7 +429,7 @@ namespace scripting::lua
|
|||||||
return detour;
|
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())
|
if (scripting::script_function_table.find(filename) == scripting::script_function_table.end())
|
||||||
{
|
{
|
||||||
@ -611,7 +633,10 @@ namespace scripting::lua
|
|||||||
return this->folder_;
|
return this->folder_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setup_io(this->state_);
|
||||||
|
setup_vector_type(this->state_);
|
||||||
setup_entity_type(this->state_, this->event_handler_, this->scheduler_);
|
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());
|
printf("Loading script '%s'\n", this->folder_.data());
|
||||||
this->load_script("__init__");
|
this->load_script("__init__");
|
||||||
|
@ -1,409 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#include "element.hpp"
|
|
||||||
|
|
||||||
#include <utils/string.hpp>
|
|
||||||
|
|
||||||
#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<std::string, std::string> 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<std::string, alignment> 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<float*>(result + 188) = glow_color[0];
|
|
||||||
*reinterpret_cast<float*>(result + 192) = glow_color[1];
|
|
||||||
*reinterpret_cast<float*>(result + 196) = glow_color[2];
|
|
||||||
*reinterpret_cast<float*>(result + 200) = glow_color[3];
|
|
||||||
*reinterpret_cast<game::rgba*>(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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<std::string, script_value> attributes = {};
|
|
||||||
std::string font = "default";
|
|
||||||
std::string material = "white";
|
|
||||||
std::string border_material = "white";
|
|
||||||
std::string text{};
|
|
||||||
};
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ namespace ui_scripting
|
|||||||
struct event
|
struct event
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
const void* element{};
|
|
||||||
arguments arguments;
|
arguments arguments;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -158,71 +158,4 @@ namespace ui_scripting
|
|||||||
throw std::runtime_error(std::string("Error setting table field: ") + e.what());
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,4 @@ namespace ui_scripting
|
|||||||
script_value get_field(const table& self, const script_value& key);
|
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 userdata& self, const script_value& key, const script_value& value);
|
||||||
void set_field(const table& 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);
|
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,8 @@
|
|||||||
|
|
||||||
namespace ui_scripting::lua
|
namespace ui_scripting::lua
|
||||||
{
|
{
|
||||||
std::unordered_map<std::string, menu> menus;
|
|
||||||
std::vector<element*> elements;
|
|
||||||
element ui_element;
|
|
||||||
int mouse[2];
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const auto animation_script = utils::nt::load_resource(LUA_ANIMATION_SCRIPT);
|
|
||||||
const auto json_script = utils::nt::load_resource(LUA_JSON_SCRIPT);
|
const auto json_script = utils::nt::load_resource(LUA_JSON_SCRIPT);
|
||||||
|
|
||||||
scripting::script_value script_convert(const sol::lua_value& value)
|
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>("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<void(element::*)(const std::string&)>(&element::set_font),
|
|
||||||
static_cast<void(element::*)(const std::string&, int)>(&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<void(element::*)(float)>(&element::set_border_width),
|
|
||||||
static_cast<void(element::*)(float, float)>(&element::set_border_width),
|
|
||||||
static_cast<void(element::*)(float, float, float)>(&element::set_border_width),
|
|
||||||
static_cast<void(element::*)(float, float, float, float)>(&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<float>() : 0.f;
|
|
||||||
element.color[1] = color["g"].get_type() == sol::type::number ? color["g"].get<float>() : 0.f;
|
|
||||||
element.color[2] = color["b"].get_type() == sol::type::number ? color["b"].get<float>() : 0.f;
|
|
||||||
element.color[3] = color["a"].get_type() == sol::type::number ? color["a"].get<float>() : 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<float>() : 0.f;
|
|
||||||
element.second_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get<float>() : 0.f;
|
|
||||||
element.second_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get<float>() : 0.f;
|
|
||||||
element.second_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get<float>() : 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<float>() : 0.f;
|
|
||||||
element.glow_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get<float>() : 0.f;
|
|
||||||
element.glow_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get<float>() : 0.f;
|
|
||||||
element.glow_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get<float>() : 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<float>() : 0.f;
|
|
||||||
element.background_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get<float>() : 0.f;
|
|
||||||
element.background_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get<float>() : 0.f;
|
|
||||||
element.background_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get<float>() : 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<float>() : 0.f;
|
|
||||||
element.border_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get<float>() : 0.f;
|
|
||||||
element.border_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get<float>() : 0.f;
|
|
||||||
element.border_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get<float>() : 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<float>() : 0.f;
|
|
||||||
element.border_width[1] = color["right"].get_type() == sol::type::number ? color["right"].get<float>() : element.border_width[1];
|
|
||||||
element.border_width[2] = color["bottom"].get_type() == sol::type::number ? color["bottom"].get<float>() : element.border_width[2];
|
|
||||||
element.border_width[3] = color["left"].get_type() == sol::type::number ? color["left"].get<float>() : 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");
|
|
||||||
|
|
||||||
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)
|
void setup_game_type(sol::state& state, event_handler& handler, scheduler& scheduler)
|
||||||
{
|
{
|
||||||
struct game
|
struct game
|
||||||
@ -721,137 +215,17 @@ namespace ui_scripting::lua
|
|||||||
auto game_type = state.new_usertype<game>("game_");
|
auto game_type = state.new_usertype<game>("game_");
|
||||||
state["game"] = 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"] = []()
|
game_type["time"] = []()
|
||||||
{
|
{
|
||||||
const auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
const auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||||
return now.count();
|
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)
|
game_type["executecommand"] = [](const game&, const std::string& command)
|
||||||
{
|
{
|
||||||
command::execute(command, false);
|
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)
|
game_type["onframe"] = [&scheduler](const game&, const sol::protected_function& callback)
|
||||||
{
|
{
|
||||||
return scheduler.add(callback, 0, false);
|
return scheduler.add(callback, 0, false);
|
||||||
@ -874,7 +248,6 @@ namespace ui_scripting::lua
|
|||||||
{
|
{
|
||||||
event_listener listener{};
|
event_listener listener{};
|
||||||
listener.callback = callback;
|
listener.callback = callback;
|
||||||
listener.element = &ui_element;
|
|
||||||
listener.event = event;
|
listener.event = event;
|
||||||
listener.is_volatile = false;
|
listener.is_volatile = false;
|
||||||
|
|
||||||
@ -886,7 +259,6 @@ namespace ui_scripting::lua
|
|||||||
{
|
{
|
||||||
event_listener listener{};
|
event_listener listener{};
|
||||||
listener.callback = callback;
|
listener.callback = callback;
|
||||||
listener.element = &ui_element;
|
|
||||||
listener.event = event;
|
listener.event = event;
|
||||||
listener.is_volatile = true;
|
listener.is_volatile = true;
|
||||||
|
|
||||||
@ -991,49 +363,6 @@ namespace ui_scripting::lua
|
|||||||
(0x71B970_b)(video.data(), 64, 0);
|
(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<sol::lua_value> 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<sol::lua_value> 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)
|
game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
scripting::shared_table.access([key, value](scripting::shared_table_t& table)
|
scripting::shared_table.access([key, value](scripting::shared_table_t& table)
|
||||||
@ -1116,7 +445,6 @@ namespace ui_scripting::lua
|
|||||||
::scheduler::once([result, id]
|
::scheduler::once([result, id]
|
||||||
{
|
{
|
||||||
event event;
|
event event;
|
||||||
event.element = &ui_element;
|
|
||||||
event.name = "http_request_done";
|
event.name = "http_request_done";
|
||||||
|
|
||||||
if (result.has_value())
|
if (result.has_value())
|
||||||
@ -1129,7 +457,7 @@ namespace ui_scripting::lua
|
|||||||
}
|
}
|
||||||
|
|
||||||
notify(event);
|
notify(event);
|
||||||
}, ::scheduler::pipeline::renderer);
|
}, ::scheduler::pipeline::lui);
|
||||||
}, ::scheduler::pipeline::async);
|
}, ::scheduler::pipeline::async);
|
||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
@ -1140,25 +468,55 @@ namespace ui_scripting::lua
|
|||||||
const auto id = request_id++;
|
const auto id = request_id++;
|
||||||
::scheduler::once([url, id, dest]()
|
::scheduler::once([url, id, dest]()
|
||||||
{
|
{
|
||||||
const auto result = utils::http::get_data(url);
|
auto last_report = std::chrono::high_resolution_clock::now();
|
||||||
::scheduler::once([result, id, dest]
|
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 event;
|
||||||
event.element = &ui_element;
|
event.name = "http_request_progress";
|
||||||
event.name = "http_request_done";
|
event.arguments = {
|
||||||
|
id,
|
||||||
|
static_cast<int>(progress),
|
||||||
|
static_cast<int>(total),
|
||||||
|
static_cast<int>(speed)
|
||||||
|
};
|
||||||
|
|
||||||
|
notify(event);
|
||||||
|
}, ::scheduler::pipeline::lui);
|
||||||
|
});
|
||||||
|
|
||||||
if (result.has_value())
|
if (result.has_value())
|
||||||
{
|
{
|
||||||
const auto write = utils::io::write_file(dest, result.value(), false);
|
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};
|
event.arguments = {id, true, write};
|
||||||
|
|
||||||
|
notify(event);
|
||||||
|
}, ::scheduler::pipeline::lui);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
::scheduler::once([result, id]()
|
||||||
|
{
|
||||||
|
event event;
|
||||||
|
event.name = "http_request_done";
|
||||||
event.arguments = {id, false};
|
event.arguments = {id, false};
|
||||||
}
|
|
||||||
|
|
||||||
notify(event);
|
notify(event);
|
||||||
}, ::scheduler::pipeline::renderer);
|
}, ::scheduler::pipeline::lui);
|
||||||
|
}
|
||||||
}, ::scheduler::pipeline::async);
|
}, ::scheduler::pipeline::async);
|
||||||
return id;
|
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<sol::lua_value> 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,
|
userdata_type[sol::meta_function::index] = [](const userdata& userdata, const sol::this_state s,
|
||||||
const std::string& name)
|
const std::string& name)
|
||||||
{
|
{
|
||||||
@ -1344,8 +677,6 @@ namespace ui_scripting::lua
|
|||||||
state["LUI"] = state["luiglobals"]["LUI"];
|
state["LUI"] = state["luiglobals"]["LUI"];
|
||||||
state["Engine"] = state["luiglobals"]["Engine"];
|
state["Engine"] = state["luiglobals"]["Engine"];
|
||||||
state["Game"] = state["luiglobals"]["Game"];
|
state["Game"] = state["luiglobals"]["Game"];
|
||||||
|
|
||||||
state.script(animation_script);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,8 +696,6 @@ namespace ui_scripting::lua
|
|||||||
setup_io(this->state_);
|
setup_io(this->state_);
|
||||||
setup_json(this->state_);
|
setup_json(this->state_);
|
||||||
setup_vector_type(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_game_type(this->state_, this->event_handler_, this->scheduler_);
|
||||||
setup_lui_types(this->state_, this->event_handler_, this->scheduler_);
|
setup_lui_types(this->state_, this->event_handler_, this->scheduler_);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../event.hpp"
|
#include "../event.hpp"
|
||||||
#include "../menu.hpp"
|
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4702)
|
#pragma warning(disable: 4702)
|
||||||
@ -21,11 +20,6 @@ namespace ui_scripting::lua
|
|||||||
code
|
code
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unordered_map<std::string, menu> menus;
|
|
||||||
extern std::vector<element*> elements;
|
|
||||||
extern element ui_element;
|
|
||||||
extern int mouse[2];
|
|
||||||
|
|
||||||
class context
|
class context
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -15,290 +15,27 @@ namespace ui_scripting::lua::engine
|
|||||||
{
|
{
|
||||||
const auto updater_script = utils::nt::load_resource(LUI_UPDATER_MENU);
|
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<element*> elements_in_point(int x, int y)
|
|
||||||
{
|
|
||||||
std::vector<element*> 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)
|
void handle_key_event(const int key, const int down)
|
||||||
{
|
|
||||||
const auto _elements = elements_in_point(mouse[0], mouse[1]);
|
|
||||||
|
|
||||||
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 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
|
event.name = down
|
||||||
? "keydown"
|
? "keydown"
|
||||||
: "keyup";
|
: "keyup";
|
||||||
event.arguments = {key};
|
event.arguments = {key};
|
||||||
|
|
||||||
engine::notify(event);
|
engine::notify(event);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_char_event(const int key)
|
void handle_char_event(const int key)
|
||||||
{
|
{
|
||||||
std::string key_str = {(char)key};
|
std::string key_str = {(char)key};
|
||||||
event event;
|
event event;
|
||||||
event.element = &ui_element;
|
|
||||||
event.name = "keypress";
|
event.name = "keypress";
|
||||||
event.arguments = {key_str};
|
event.arguments = {key_str};
|
||||||
|
|
||||||
engine::notify(event);
|
engine::notify(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<element*> 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()
|
auto& get_scripts()
|
||||||
{
|
{
|
||||||
static std::vector<std::unique_ptr<context>> scripts{};
|
static std::vector<std::unique_ptr<context>> scripts{};
|
||||||
@ -327,91 +64,12 @@ namespace ui_scripting::lua::engine
|
|||||||
{
|
{
|
||||||
get_scripts().push_back(std::make_unique<context>(code, script_type::code));
|
get_scripts().push_back(std::make_unique<context>(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()
|
void start()
|
||||||
{
|
{
|
||||||
clear_converted_functions();
|
clear_converted_functions();
|
||||||
close_all_menus();
|
|
||||||
get_scripts().clear();
|
get_scripts().clear();
|
||||||
clear_menus();
|
|
||||||
|
|
||||||
load_code(updater_script);
|
load_code(updater_script);
|
||||||
|
|
||||||
@ -428,9 +86,7 @@ namespace ui_scripting::lua::engine
|
|||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
clear_converted_functions();
|
clear_converted_functions();
|
||||||
close_all_menus();
|
|
||||||
get_scripts().clear();
|
get_scripts().clear();
|
||||||
clear_menus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_event(const std::string& type, const std::vector<int>& arguments)
|
void ui_event(const std::string& type, const std::vector<int>& arguments)
|
||||||
@ -444,11 +100,6 @@ namespace ui_scripting::lua::engine
|
|||||||
{
|
{
|
||||||
handle_char_event(arguments[0]);
|
handle_char_event(arguments[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "mousemove")
|
|
||||||
{
|
|
||||||
handle_mousemove_event(relative_mouse(arguments[0]), relative_mouse(arguments[1]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify(const event& e)
|
void notify(const event& e)
|
||||||
@ -461,9 +112,6 @@ namespace ui_scripting::lua::engine
|
|||||||
|
|
||||||
void run_frame()
|
void run_frame()
|
||||||
{
|
{
|
||||||
check_resize();
|
|
||||||
render_menus();
|
|
||||||
|
|
||||||
for (auto& script : get_scripts())
|
for (auto& script : get_scripts())
|
||||||
{
|
{
|
||||||
script->run_frame();
|
script->run_frame();
|
||||||
|
@ -7,9 +7,6 @@ namespace ui_scripting::lua::engine
|
|||||||
void start();
|
void start();
|
||||||
void stop();
|
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<int>&);
|
void ui_event(const std::string&, const std::vector<int>&);
|
||||||
void notify(const event& e);
|
void notify(const event& e);
|
||||||
void run_frame();
|
void run_frame();
|
||||||
|
@ -17,9 +17,9 @@ namespace ui_scripting::lua
|
|||||||
this->remove(handle);
|
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();)
|
for (auto i = tasks.begin(); i != tasks.end();)
|
||||||
{
|
{
|
||||||
if (i->event != event.name || i->element != event.element)
|
if (i->event != event.name)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
@ -78,8 +78,7 @@ namespace ui_scripting::lua
|
|||||||
return {id};
|
return {id};
|
||||||
}
|
}
|
||||||
|
|
||||||
void event_handler::add_endon_condition(const event_listener_handle& handle, const element* element,
|
void event_handler::add_endon_condition(const event_listener_handle& handle, const std::string& event)
|
||||||
const std::string& event)
|
|
||||||
{
|
{
|
||||||
auto merger = [&](task_list& tasks)
|
auto merger = [&](task_list& tasks)
|
||||||
{
|
{
|
||||||
@ -87,7 +86,7 @@ namespace ui_scripting::lua
|
|||||||
{
|
{
|
||||||
if (task.id == handle.id)
|
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)
|
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;
|
task.is_deleted = true;
|
||||||
break;
|
break;
|
||||||
|
@ -16,11 +16,10 @@ namespace ui_scripting::lua
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string event = {};
|
std::string event = {};
|
||||||
void* element{};
|
|
||||||
event_callback callback = {};
|
event_callback callback = {};
|
||||||
bool is_volatile = false;
|
bool is_volatile = false;
|
||||||
bool is_deleted = false;
|
bool is_deleted = false;
|
||||||
std::vector<std::pair<uint64_t, std::string>> endon_conditions{};
|
std::vector<std::string> endon_conditions{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class event_handler final
|
class event_handler final
|
||||||
@ -52,7 +51,7 @@ namespace ui_scripting::lua
|
|||||||
void merge_callbacks();
|
void merge_callbacks();
|
||||||
void handle_endon_conditions(const event& event);
|
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;
|
event_arguments build_arguments(const event& event) const;
|
||||||
};
|
};
|
||||||
|
@ -13,9 +13,9 @@ namespace ui_scripting::lua
|
|||||||
this->remove(handle);
|
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)
|
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;
|
task.is_deleted = true;
|
||||||
break;
|
break;
|
||||||
@ -118,7 +118,7 @@ namespace ui_scripting::lua
|
|||||||
return {id};
|
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)
|
auto merger = [&](task_list& tasks)
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ namespace ui_scripting::lua
|
|||||||
{
|
{
|
||||||
if (task.id == handle.id)
|
if (task.id == handle.id)
|
||||||
{
|
{
|
||||||
task.endon_conditions.emplace_back(element->id, event);
|
task.endon_conditions.emplace_back(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ namespace ui_scripting::lua
|
|||||||
std::chrono::milliseconds delay{};
|
std::chrono::milliseconds delay{};
|
||||||
bool is_volatile = false;
|
bool is_volatile = false;
|
||||||
bool is_deleted = false;
|
bool is_deleted = false;
|
||||||
std::vector<std::pair<uint64_t, std::string>> endon_conditions{};
|
std::vector<std::string> endon_conditions{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class scheduler final
|
class scheduler final
|
||||||
@ -46,7 +46,7 @@ namespace ui_scripting::lua
|
|||||||
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
|
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
|
||||||
std::atomic_int64_t current_task_id_ = 0;
|
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 remove(const task_handle& handle);
|
||||||
void merge_callbacks();
|
void merge_callbacks();
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
#include <std_include.hpp>
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<element*> children{};
|
|
||||||
};
|
|
||||||
}
|
|
@ -17,10 +17,8 @@
|
|||||||
#define MENU_MAIN 310
|
#define MENU_MAIN 310
|
||||||
|
|
||||||
#define TLS_DLL 311
|
#define TLS_DLL 311
|
||||||
#define RUNNER 312
|
|
||||||
|
|
||||||
#define ICON_IMAGE 313
|
#define ICON_IMAGE 312
|
||||||
|
|
||||||
#define LUA_ANIMATION_SCRIPT 314
|
#define LUA_JSON_SCRIPT 313
|
||||||
#define LUA_JSON_SCRIPT 315
|
#define LUI_UPDATER_MENU 314
|
||||||
#define LUI_UPDATER_MENU 316
|
|
||||||
|
@ -97,9 +97,7 @@ ID_ICON ICON "resources/icon.ico"
|
|||||||
|
|
||||||
MENU_MAIN RCDATA "resources/main.html"
|
MENU_MAIN RCDATA "resources/main.html"
|
||||||
|
|
||||||
LUA_ANIMATION_SCRIPT RCDATA "resources/animation.lua"
|
|
||||||
LUA_JSON_SCRIPT RCDATA "resources/json.lua"
|
LUA_JSON_SCRIPT RCDATA "resources/json.lua"
|
||||||
|
|
||||||
LUI_UPDATER_MENU RCDATA "resources/updater.lua"
|
LUI_UPDATER_MENU RCDATA "resources/updater.lua"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -108,12 +106,6 @@ TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll"
|
|||||||
TLS_DLL RCDATA "../../build/bin/x64/Release/tlsdll.dll"
|
TLS_DLL RCDATA "../../build/bin/x64/Release/tlsdll.dll"
|
||||||
#endif
|
#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"
|
ICON_IMAGE RCDATA "resources/icon.png"
|
||||||
|
|
||||||
#endif // English (United States) resources
|
#endif // English (United States) resources
|
||||||
|
@ -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
|
|
@ -10,6 +10,7 @@
|
|||||||
#pragma warning(disable: 4702)
|
#pragma warning(disable: 4702)
|
||||||
#pragma warning(disable: 4996)
|
#pragma warning(disable: 4996)
|
||||||
#pragma warning(disable: 5054)
|
#pragma warning(disable: 5054)
|
||||||
|
#pragma warning(disable: 5056)
|
||||||
#pragma warning(disable: 6011)
|
#pragma warning(disable: 6011)
|
||||||
#pragma warning(disable: 6297)
|
#pragma warning(disable: 6297)
|
||||||
#pragma warning(disable: 6385)
|
#pragma warning(disable: 6385)
|
||||||
|
@ -10,19 +10,25 @@ namespace utils::http
|
|||||||
{
|
{
|
||||||
struct progress_helper
|
struct progress_helper
|
||||||
{
|
{
|
||||||
const std::function<void(size_t)>* callback{};
|
const std::function<void(size_t, size_t, size_t)>* callback{};
|
||||||
std::exception_ptr exception{};
|
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<progress_helper*>(clientp);
|
auto* helper = static_cast<progress_helper*>(clientp);
|
||||||
|
|
||||||
try
|
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)
|
if (*helper->callback)
|
||||||
{
|
{
|
||||||
(*helper->callback)(dlnow);
|
(*helper->callback)(dlnow, dltotal, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
@ -44,7 +50,8 @@ namespace utils::http
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> get_data(const std::string& url, const headers& headers, const std::function<void(size_t)>& callback)
|
std::optional<std::string> get_data(const std::string& url, const headers& headers,
|
||||||
|
const std::function<void(size_t, size_t, size_t)>& callback)
|
||||||
{
|
{
|
||||||
curl_slist* header_list = nullptr;
|
curl_slist* header_list = nullptr;
|
||||||
auto* curl = curl_easy_init();
|
auto* curl = curl_easy_init();
|
||||||
@ -68,6 +75,7 @@ namespace utils::http
|
|||||||
std::string buffer{};
|
std::string buffer{};
|
||||||
progress_helper helper{};
|
progress_helper helper{};
|
||||||
helper.callback = &callback;
|
helper.callback = &callback;
|
||||||
|
helper.start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.data());
|
curl_easy_setopt(curl, CURLOPT_URL, url.data());
|
||||||
|
@ -8,6 +8,7 @@ namespace utils::http
|
|||||||
{
|
{
|
||||||
using headers = std::unordered_map<std::string, std::string>;
|
using headers = std::unordered_map<std::string, std::string>;
|
||||||
|
|
||||||
std::optional<std::string> get_data(const std::string& url, const headers& headers = {}, const std::function<void(size_t)>& callback = {});
|
std::optional<std::string> get_data(const std::string& url, const headers& headers = {},
|
||||||
|
const std::function<void(size_t, size_t, size_t)>& callback = {});
|
||||||
std::future<std::optional<std::string>> get_data_async(const std::string& url, const headers& headers = {});
|
std::future<std::optional<std::string>> get_data_async(const std::string& url, const headers& headers = {});
|
||||||
}
|
}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
@ -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
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user