From 36d07057c5f5e0e8caba6296d5f7d28cfbe6b1cf Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 01:54:13 +0200 Subject: [PATCH] Add some functions --- src/client/component/scripting.cpp | 1 + src/client/component/scripting.hpp | 3 + src/client/game/scripting/lua/context.cpp | 71 ++++++++++++++++++++ src/client/game/symbols.hpp | 2 + src/client/game/ui_scripting/lua/context.cpp | 69 +++++++++++++++++++ 5 files changed, 146 insertions(+) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index f8730c86..9aa37307 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -18,6 +18,7 @@ namespace scripting { std::unordered_map> fields_table; std::unordered_map> script_function_table; + utils::concurrency::container shared_table; namespace { diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp index 865ae858..5794bff2 100644 --- a/src/client/component/scripting.hpp +++ b/src/client/component/scripting.hpp @@ -3,6 +3,9 @@ namespace scripting { + using shared_table_t = std::unordered_map; + extern std::unordered_map> fields_table; extern std::unordered_map> script_function_table; + extern utils::concurrency::container shared_table; } \ No newline at end of file diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index cb24ff3e..396b3837 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -9,6 +9,7 @@ #include "../../../component/command.hpp" #include "../../../component/logfile.hpp" #include "../../../component/scripting.hpp" +#include "../../../component/fastfiles.hpp" #include #include @@ -501,6 +502,76 @@ namespace scripting::lua return detour; }; + + game_type["assetlist"] = [](const game&, const sol::this_state s, const std::string& type_string) + { + auto table = sol::table::create(s.lua_state()); + auto index = 1; + auto type_index = -1; + + for (auto i = 0; i < ::game::XAssetType::ASSET_TYPE_COUNT; i++) + { + if (type_string == ::game::g_assetNames[i]) + { + type_index = i; + } + } + + if (type_index == -1) + { + throw std::runtime_error("Asset type does not exist"); + } + + const auto type = static_cast<::game::XAssetType>(type_index); + fastfiles::enum_assets(type, [type, &table, &index](const ::game::XAssetHeader header) + { + const auto asset = ::game::XAsset{type, header}; + const std::string asset_name = ::game::DB_GetXAssetName(&asset); + table[index++] = asset_name; + }, true); + + return table; + }; + + game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value) + { + scripting::shared_table.access([key, value](scripting::shared_table_t& table) + { + table[key] = value; + }); + }; + + game_type["sharedget"] = [](const game&, const std::string& key) + { + std::string result; + scripting::shared_table.access([key, &result](scripting::shared_table_t& table) + { + result = table[key]; + }); + return result; + }; + + game_type["sharedclear"] = [](const game&) + { + scripting::shared_table.access([](scripting::shared_table_t& table) + { + table.clear(); + }); + }; + + game_type["getentbyref"] = [](const game&, const sol::this_state s, + const unsigned int entnum, const unsigned int classnum) + { + const auto id = ::game::Scr_GetEntityId(entnum, classnum); + if (id) + { + return convert(s, scripting::entity{id}); + } + else + { + return sol::lua_value{s, sol::lua_nil}; + } + }; } } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 1f277cee..974cbab9 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -43,6 +43,8 @@ namespace game WEAK symbol CG_GameMessageBold{0x140138750, 0x140220620}; WEAK symbol CG_SetClientDvarFromServer{0, 0x140236120}; + WEAK symbol CG_GetWeaponDisplayName{0x14016EC30, 0x1400B5840}; WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 96286cdd..0d975d0d 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -10,6 +10,8 @@ #include "../../../component/updater.hpp" #include "../../../component/fps.hpp" #include "../../../component/localized_strings.hpp" +#include "../../../component/fastfiles.hpp" +#include "../../../component/scripting.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -68,6 +70,73 @@ namespace ui_scripting::lua localized_strings::override(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) + { + table[key] = value; + }); + }; + + game_type["sharedget"] = [](const game&, const std::string& key) + { + std::string result; + scripting::shared_table.access([key, &result](scripting::shared_table_t& table) + { + result = table[key]; + }); + return result; + }; + + game_type["sharedclear"] = [](const game&) + { + scripting::shared_table.access([](scripting::shared_table_t& table) + { + table.clear(); + }); + }; + + game_type["assetlist"] = [](const game&, const sol::this_state s, const std::string& type_string) + { + auto table = sol::table::create(s.lua_state()); + auto index = 1; + auto type_index = -1; + + for (auto i = 0; i < ::game::XAssetType::ASSET_TYPE_COUNT; i++) + { + if (type_string == ::game::g_assetNames[i]) + { + type_index = i; + } + } + + if (type_index == -1) + { + throw std::runtime_error("Asset type does not exist"); + } + + const auto type = static_cast<::game::XAssetType>(type_index); + fastfiles::enum_assets(type, [type, &table, &index](const ::game::XAssetHeader header) + { + const auto asset = ::game::XAsset{type, header}; + const std::string asset_name = ::game::DB_GetXAssetName(&asset); + table[index++] = asset_name; + }, true); + + return table; + }; + + game_type["getweapondisplayname"] = [](const game&, const std::string& name) + { + const auto alternate = name.starts_with("alt_"); + const auto weapon = ::game::G_GetWeaponForName(name.data()); + + char buffer[0x400] = {0}; + ::game::CG_GetWeaponDisplayName(weapon, alternate, buffer, 0x400); + + return std::string(buffer); + }; + auto userdata_type = state.new_usertype("userdata_"); userdata_type["new"] = sol::property(