diff --git a/data/ui_scripts/mods/loading.lua b/data/ui_scripts/mods/loading.lua index a71fc4d7..7918d7f0 100644 --- a/data/ui_scripts/mods/loading.lua +++ b/data/ui_scripts/mods/loading.lua @@ -2,12 +2,12 @@ game:addlocalizedstring("MENU_MODS", "MODS") game:addlocalizedstring("MENU_MODS_DESC", "Load installed mods.") game:addlocalizedstring("LUA_MENU_MOD_DESC_DEFAULT", "Load &&1.") game:addlocalizedstring("LUA_MENU_MOD_DESC", "&&1\nAuthor: &&2\nVersion: &&3") -game:addlocalizedstring("LUA_MENU_OPEN_STORE", "Store") -game:addlocalizedstring("LUA_MENU_OPEN_STORE_DESC", "Download and install mods.") game:addlocalizedstring("LUA_MENU_LOADED_MOD", "Loaded mod: ^3&&1") game:addlocalizedstring("LUA_MENU_AVAILABLE_MODS", "Available mods") game:addlocalizedstring("LUA_MENU_UNLOAD", "Unload") game:addlocalizedstring("LUA_MENU_UNLOAD_DESC", "Unload the currently loaded mod.") +game:addlocalizedstring("LUA_MENU_WORKSHOP", "Workshop") +game:addlocalizedstring("LUA_MENU_WORKSHOP_DESC", "Download and install mods.") function createdivider(menu, text) local element = LUI.UIElement.new( { @@ -26,6 +26,8 @@ function createdivider(menu, text) title_bar_text = Engine.ToUpperCase(text) })) + element.text = element:getFirstChild():getFirstChild():getNextSibling() + menu.list:addElement(element) return element end @@ -78,12 +80,12 @@ LUI.MenuBuilder.registerType("mods_menu", function(a1) showTopRightSmallBar = true }) - menu:AddButton("@LUA_MENU_OPEN_STORE", function() - if (LUI.MenuBuilder.m_types_build["mods_store_menu"]) then - LUI.FlowManager.RequestAddMenu(nil, "mods_store_menu") + menu:AddButton("@LUA_MENU_WORKSHOP", function() + if (LUI.MenuBuilder.m_types_build["mods_workshop_menu"]) then + LUI.FlowManager.RequestAddMenu(nil, "mods_workshop_menu") end end, nil, true, nil, { - desc_text = Engine.Localize("@LUA_MENU_OPEN_STORE_DESC") + desc_text = Engine.Localize("@LUA_MENU_WORKSHOP_DESC") }) local modfolder = game:getloadedmod() @@ -92,7 +94,7 @@ LUI.MenuBuilder.registerType("mods_menu", function(a1) createdivider(menu, Engine.Localize("@LUA_MENU_LOADED_MOD", name:truncate(24))) menu:AddButton("@LUA_MENU_UNLOAD", function() - game:executecommand("unloadmod") + Engine.Exec("unloadmod") end, nil, true, nil, { desc_text = Engine.Localize("@LUA_MENU_UNLOAD_DESC") }) @@ -109,7 +111,7 @@ LUI.MenuBuilder.registerType("mods_menu", function(a1) if (mods[i] ~= modfolder) then game:addlocalizedstring(name, name) menu:AddButton(name, function() - game:executecommand("loadmod " .. mods[i]) + Engine.Exec("loadmod " .. mods[i]) end, nil, true, nil, { desc_text = desc }) diff --git a/data/ui_scripts/settings/__init__.lua b/data/ui_scripts/settings/__init__.lua index 00cd8125..26b798ac 100644 --- a/data/ui_scripts/settings/__init__.lua +++ b/data/ui_scripts/settings/__init__.lua @@ -55,8 +55,8 @@ LUI.addmenubutton("pc_controls", { LUI.MenuBuilder.m_types_build["settings_menu"] = function(a1) local menu = LUI.MenuTemplate.new(a1, { menu_title = "@MENU_GENERAL", - menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + luiglobals.H1MenuDims.spacing), - menu_width = luiglobals.GenericMenuDims.OptionMenuWidth + menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + H1MenuDims.spacing), + menu_width = GenericMenuDims.OptionMenuWidth }) createdivider(menu, "@LUA_MENU_UPDATES") diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp index cba191cc..321364a5 100644 --- a/src/client/component/filesystem.cpp +++ b/src/client/component/filesystem.cpp @@ -27,13 +27,18 @@ namespace filesystem return {}; } - bool read_file(const std::string& path, std::string* data) + bool read_file(const std::string& path, std::string* data, std::string* real_path) { for (const auto& search_path : get_search_paths()) { const auto path_ = search_path + "/" + path; if (utils::io::read_file(path_, data)) { + if (real_path != nullptr) + { + *real_path = path_; + } + return true; } } diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp index 718e5377..3e9c5b02 100644 --- a/src/client/component/filesystem.hpp +++ b/src/client/component/filesystem.hpp @@ -4,5 +4,5 @@ namespace filesystem { std::unordered_set& get_search_paths(); std::string read_file(const std::string& path); - bool read_file(const std::string& path, std::string* data); + bool read_file(const std::string& path, std::string* data, std::string* real_path = nullptr); } \ No newline at end of file diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 78d8f401..3e1a6a6c 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -386,11 +386,13 @@ namespace game_console va_end(ap); const auto formatted = std::string(va_buffer); + printf(va_buffer); + const auto lines = utils::string::split(formatted, '\n'); for (auto& line : lines) { - print(type == con_type_info ? line : "^"s.append(std::to_string(type)).append(line)); + print(type == con_type_info ? line : "^"s.append(std::to_string(type)).append(line), false); } } diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 2fb43498..3f34bf2e 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -5,7 +5,6 @@ #include "game_console.hpp" #include "gui.hpp" -#include "game/ui_scripting/lua/engine.hpp" #include "game/ui_scripting/execution.hpp" #include diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index ed0301b8..07ae3b07 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -87,6 +87,7 @@ namespace scheduler utils::hook::detour r_end_frame_hook; utils::hook::detour g_run_frame_hook; utils::hook::detour main_frame_hook; + utils::hook::detour hks_frame_hook; void execute(const pipeline type) { @@ -97,11 +98,6 @@ namespace scheduler void r_end_frame_stub() { execute(pipeline::renderer); - if (game::Sys_IsMainThread()) - { - execute(pipeline::lui); - } - r_end_frame_hook.invoke(); } @@ -116,6 +112,16 @@ namespace scheduler main_frame_hook.invoke(); execute(pipeline::main); } + + void hks_frame_stub() + { + const auto state = *game::hks::lua_state; + if (state) + { + execute(pipeline::lui); + } + hks_frame_hook.invoke(); + } } void schedule(const std::function& callback, const pipeline type, @@ -186,6 +192,7 @@ namespace scheduler r_end_frame_hook.create(0x14076D7B0, scheduler::r_end_frame_stub); g_run_frame_hook.create(0x1404CB030, scheduler::server_frame_stub); main_frame_hook.create(0x140417FA0, scheduler::main_frame_stub); + hks_frame_hook.create(0x140327880, scheduler::hks_frame_stub); } void pre_destroy() override diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index ee6d4831..cfa93990 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -7,172 +7,461 @@ #include "scheduler.hpp" #include "command.hpp" -#include "ui_scripting.hpp" +#include "filesystem.hpp" +#include "localized_strings.hpp" +#include "scripting.hpp" +#include "fastfiles.hpp" +#include "mods.hpp" +#include "updater.hpp" -#include "game/ui_scripting/lua/engine.hpp" #include "game/ui_scripting/execution.hpp" -#include "game/ui_scripting/lua/error.hpp" +#include "game/scripting/execution.hpp" + +#include "ui_scripting.hpp" #include #include +#include namespace ui_scripting { namespace { - std::unordered_map converted_functions; + const auto lui_common = utils::nt::load_resource(LUI_COMMON); + const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); + const auto lua_json = utils::nt::load_resource(LUA_JSON); + + std::unordered_map> converted_functions; - utils::hook::detour hksi_lual_error_hook; - utils::hook::detour hksi_lual_error_hook2; utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; - utils::hook::detour hks_allocator_hook; - utils::hook::detour lui_error_hook; - utils::hook::detour hksi_hks_error_hook; - utils::hook::detour hks_frame_hook; + utils::hook::detour hks_package_require_hook; - int error_hook_enabled = 0; - - void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) + struct script { - char va_buffer[2048] = {0}; + std::string name; + std::string root; + }; - va_list ap; - va_start(ap, fmt); - vsprintf_s(va_buffer, fmt, ap); - va_end(ap); + struct globals_t + { + std::string in_require_script; + std::vector