scripting additions, changes, and cleanup (#330)
This commit is contained in:
@ -130,12 +130,12 @@ namespace dedicated
|
||||
|
||||
void sys_error_stub(const char* msg, ...)
|
||||
{
|
||||
char buffer[2048];
|
||||
char buffer[2048]{};
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
|
||||
vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap);
|
||||
vsnprintf_s(buffer, _TRUNCATE, msg, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "scripting.hpp"
|
||||
|
||||
#include "game/dvars.hpp"
|
||||
#include "game/scripting/functions.hpp"
|
||||
|
||||
#include <xsk/gsc/types.hpp>
|
||||
#include <xsk/gsc/interfaces/compiler.hpp>
|
||||
@ -72,14 +71,6 @@ namespace gsc
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: check back on this to see if there is a property we can distinguish compared to our rawfiles, like compressedLen?
|
||||
// this will filter out the rawfile "gsc" the game zones actually have, this seems to get all of them
|
||||
if (name.starts_with("maps/createfx") || name.starts_with("maps/createart")
|
||||
|| (name.starts_with("maps/mp") && name.ends_with("_fx.gsc")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto name_str = name.data();
|
||||
|
||||
if (game::DB_XAssetExists(game::ASSET_TYPE_RAWFILE, name_str) &&
|
||||
@ -107,6 +98,22 @@ namespace gsc
|
||||
return loaded_scripts[real_name];
|
||||
}
|
||||
|
||||
/*
|
||||
without this check, gsc rawfiles that a map contains will be compiled. however, these aren't the correct files.
|
||||
each rawfile has a scriptfile counterpart in asset pool that is meant to be used instead.
|
||||
the gsc rawfiles are just leftover from creating the maps.
|
||||
|
||||
(if you are creating a custom map, you can safely have gsc rawfiles without having scriptfile counterparts)
|
||||
*/
|
||||
if (real_name.starts_with("maps/createfx") || real_name.starts_with("maps/createart")
|
||||
|| (real_name.starts_with("maps/mp") && real_name.ends_with("_fx.gsc")))
|
||||
{
|
||||
if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, real_name.data()))
|
||||
{
|
||||
return game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, real_name.data(), false).scriptfile;
|
||||
}
|
||||
}
|
||||
|
||||
std::string source_buffer{};
|
||||
if (!read_scriptfile(real_name + ".gsc", &source_buffer))
|
||||
{
|
||||
@ -792,7 +799,7 @@ namespace gsc
|
||||
|
||||
for (auto i = 0u; i < args.size(); ++i)
|
||||
{
|
||||
const auto str = args[i].as<std::string>();
|
||||
const auto str = args[i].to_string();
|
||||
buffer.append(str);
|
||||
buffer.append("\t");
|
||||
}
|
||||
@ -865,6 +872,19 @@ namespace gsc
|
||||
return scripting::script_value{};
|
||||
});
|
||||
|
||||
function::add("getfunction", [](const function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto filename = args[0].as<std::string>();
|
||||
const auto function = args[1].as<std::string>();
|
||||
|
||||
if (scripting::script_function_table[filename].find(function) != scripting::script_function_table[filename].end())
|
||||
{
|
||||
return scripting::function{scripting::script_function_table[filename][function]};
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
scripting::on_shutdown([](int free_scripts)
|
||||
{
|
||||
if (free_scripts)
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/scripting/script_value.hpp"
|
||||
#include "game/scripting/array.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
#include "game/scripting/function.hpp"
|
||||
|
||||
namespace gsc
|
||||
{
|
||||
|
@ -50,6 +50,18 @@ namespace io
|
||||
|
||||
throw std::runtime_error("fs_game is not properly defined");
|
||||
}
|
||||
|
||||
void replace(std::string& str, const std::string& from, const std::string& to)
|
||||
{
|
||||
const auto start_pos = str.find(from);
|
||||
|
||||
if (start_pos == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
str.replace(start_pos, from.length(), to);
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
@ -60,7 +72,7 @@ namespace io
|
||||
use_root_folder = utils::flags::has_flag("io_game_dir");
|
||||
if (use_root_folder)
|
||||
{
|
||||
console::warn("WARNING: GSC has access to your game folder. To prevent possible malicious code, remove this flag.");
|
||||
console::warn("GSC has access to your game folder. To prevent possible malicious code, remove the '-io_game_dir' launch flag.");
|
||||
}
|
||||
|
||||
gsc::function::add("fileexists", [](const gsc::function_args& args)
|
||||
@ -141,6 +153,19 @@ namespace io
|
||||
const auto path = convert_path(args[0].as<std::string>());
|
||||
return utils::io::remove_file(path);
|
||||
});
|
||||
|
||||
gsc::function::add("va", [](const gsc::function_args& args)
|
||||
{
|
||||
auto fmt = args[0].as<std::string>();
|
||||
|
||||
for (auto i = 1u; i < args.size(); i++)
|
||||
{
|
||||
const auto arg = args[i].to_string();
|
||||
replace(fmt, "%s", arg);
|
||||
}
|
||||
|
||||
return fmt;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
210
src/client/component/json.cpp
Normal file
210
src/client/component/json.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "scheduler.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "json.hpp"
|
||||
|
||||
#include <json.hpp>
|
||||
|
||||
namespace json
|
||||
{
|
||||
namespace
|
||||
{
|
||||
nlohmann::json gsc_to_json(scripting::script_value _value);
|
||||
|
||||
nlohmann::json entity_to_array(unsigned int id)
|
||||
{
|
||||
scripting::array array(id);
|
||||
nlohmann::json obj;
|
||||
|
||||
auto string_indexed = -1;
|
||||
const auto keys = array.get_keys();
|
||||
for (auto i = 0; i < keys.size(); i++)
|
||||
{
|
||||
const auto is_int = keys[i].is<int>();
|
||||
const auto is_string = keys[i].is<std::string>();
|
||||
|
||||
if (string_indexed == -1)
|
||||
{
|
||||
string_indexed = is_string;
|
||||
}
|
||||
|
||||
if (!string_indexed && is_int)
|
||||
{
|
||||
const auto index = keys[i].as<int>();
|
||||
obj[index] = gsc_to_json(array[index]);
|
||||
}
|
||||
else if (string_indexed && is_string)
|
||||
{
|
||||
const auto key = keys[i].as<std::string>();
|
||||
obj.emplace(key, gsc_to_json(array[key]));
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
nlohmann::json vector_to_array(const float* value)
|
||||
{
|
||||
nlohmann::json obj;
|
||||
obj.push_back(value[0]);
|
||||
obj.push_back(value[1]);
|
||||
obj.push_back(value[2]);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
nlohmann::json gsc_to_json(scripting::script_value _value)
|
||||
{
|
||||
const auto variable = _value.get_raw();
|
||||
const auto value = variable.u;
|
||||
const auto type = variable.type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (game::SCRIPT_NONE):
|
||||
return {};
|
||||
case (game::SCRIPT_INTEGER):
|
||||
return value.intValue;
|
||||
case (game::SCRIPT_FLOAT):
|
||||
return value.floatValue;
|
||||
case (game::SCRIPT_STRING):
|
||||
case (game::SCRIPT_ISTRING):
|
||||
return game::SL_ConvertToString(static_cast<game::scr_string_t>(value.stringValue));
|
||||
case (game::SCRIPT_VECTOR):
|
||||
return vector_to_array(value.vectorValue);
|
||||
case (game::SCRIPT_OBJECT):
|
||||
{
|
||||
const auto object_type = game::scr_VarGlob->objectVariableValue[value.uintValue].w.type;
|
||||
|
||||
switch (object_type)
|
||||
{
|
||||
case (game::SCRIPT_STRUCT):
|
||||
return "[struct]";
|
||||
case (game::SCRIPT_ARRAY):
|
||||
return entity_to_array(value.uintValue);
|
||||
default:
|
||||
return "[entity]";
|
||||
}
|
||||
}
|
||||
case (game::SCRIPT_FUNCTION):
|
||||
return _value.as<scripting::function>().get_name();
|
||||
default:
|
||||
return "[unknown type]";
|
||||
};
|
||||
}
|
||||
|
||||
scripting::script_value json_to_gsc(nlohmann::json obj)
|
||||
{
|
||||
const auto type = obj.type();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (nlohmann::detail::value_t::number_integer):
|
||||
case (nlohmann::detail::value_t::number_unsigned):
|
||||
return obj.get<int>();
|
||||
case (nlohmann::detail::value_t::number_float):
|
||||
return obj.get<float>();
|
||||
case (nlohmann::detail::value_t::string):
|
||||
return obj.get<std::string>();
|
||||
case (nlohmann::detail::value_t::array):
|
||||
{
|
||||
scripting::array array;
|
||||
|
||||
for (const auto& [key, value] : obj.items())
|
||||
{
|
||||
array.push(json_to_gsc(value));
|
||||
}
|
||||
|
||||
return array.get_raw();
|
||||
}
|
||||
case (nlohmann::detail::value_t::object):
|
||||
{
|
||||
scripting::array array;
|
||||
|
||||
for (const auto& [key, value] : obj.items())
|
||||
{
|
||||
array[key] = json_to_gsc(value);
|
||||
}
|
||||
|
||||
return array.get_raw();
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::string gsc_to_string(const scripting::script_value& value)
|
||||
{
|
||||
return gsc_to_json(value).dump();
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
gsc::function::add("array", [](const gsc::function_args& args)
|
||||
{
|
||||
scripting::array array(args.get_raw());
|
||||
return array.get_raw();
|
||||
});
|
||||
|
||||
gsc::function::add("map", [](const gsc::function_args& args)
|
||||
{
|
||||
scripting::array array;
|
||||
|
||||
for (auto i = 0u; i < args.size(); i += 2)
|
||||
{
|
||||
if (i >= args.size() - 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto key = args[i].as<std::string>();
|
||||
array[key] = args[i + 1];
|
||||
}
|
||||
|
||||
return array;
|
||||
});
|
||||
|
||||
gsc::function::add("jsonparse", [](const gsc::function_args& args)
|
||||
{
|
||||
const auto json = args[0].as<std::string>();
|
||||
const auto obj = nlohmann::json::parse(json);
|
||||
return json_to_gsc(obj);
|
||||
});
|
||||
|
||||
gsc::function::add("jsonserialize", [](const gsc::function_args& args)
|
||||
{
|
||||
const auto value = args[0];
|
||||
auto indent = -1;
|
||||
|
||||
if (args.size() > 1)
|
||||
{
|
||||
indent = args[1].as<int>();
|
||||
}
|
||||
|
||||
return gsc_to_json(value).dump(indent);
|
||||
});
|
||||
|
||||
gsc::function::add("jsonprint", [](const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
for (const auto arg : args.get_raw())
|
||||
{
|
||||
buffer.append(gsc_to_string(arg));
|
||||
buffer.append("\t");
|
||||
}
|
||||
|
||||
printf("%s\n", buffer.data());
|
||||
return {};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(json::component)
|
6
src/client/component/json.hpp
Normal file
6
src/client/component/json.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace json
|
||||
{
|
||||
std::string gsc_to_string(const scripting::script_value& _value);
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "gsc.hpp"
|
||||
#include "logfile.hpp"
|
||||
#include "scripting.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include "game/dvars.hpp"
|
||||
@ -34,6 +36,8 @@ namespace logfile
|
||||
std::vector<sol::protected_function> player_killed_callbacks;
|
||||
std::vector<sol::protected_function> player_damage_callbacks;
|
||||
|
||||
std::vector<scripting::function> say_callbacks;
|
||||
|
||||
game::dvar_t* logfile;
|
||||
game::dvar_t* g_log;
|
||||
|
||||
@ -302,13 +306,22 @@ namespace logfile
|
||||
|
||||
game::SV_Cmd_ArgvBuffer(0, cmd, 1024);
|
||||
|
||||
auto hidden = false;
|
||||
if (cmd == "say"s || cmd == "say_team"s)
|
||||
{
|
||||
auto hidden = false;
|
||||
std::string message(game::ConcatArgs(1));
|
||||
message.erase(0, 1);
|
||||
|
||||
hidden = message[1] == '/';
|
||||
message.erase(0, hidden ? 2 : 1);
|
||||
for (const auto& callback : say_callbacks)
|
||||
{
|
||||
const auto entity_id = game::Scr_GetEntityId(client_num, 0);
|
||||
const auto result = callback(entity_id, {message, cmd == "say_team"s});
|
||||
|
||||
if (result.is<int>() && !hidden)
|
||||
{
|
||||
hidden = result.as<int>() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
scheduler::once([cmd, message, self, hidden]()
|
||||
{
|
||||
@ -383,6 +396,18 @@ namespace logfile
|
||||
g_log = dvars::register_string("g_log", "h1-mod\\logs\\games_mp.log", game::DVAR_FLAG_NONE, "Log file path");
|
||||
}, scheduler::pipeline::main);
|
||||
g_log_printf_hook.create(game::G_LogPrintf, g_log_printf_stub);
|
||||
|
||||
gsc::function::add("onplayersay", [](const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto function = args[0].as<scripting::function>();
|
||||
say_callbacks.push_back(function);
|
||||
return {};
|
||||
});
|
||||
|
||||
scripting::on_shutdown([](int)
|
||||
{
|
||||
say_callbacks.clear();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace logger
|
||||
{
|
||||
utils::hook::detour com_error_hook;
|
||||
|
||||
const game::dvar_t* logger_dev = nullptr;
|
||||
game::dvar_t* logger_dev = nullptr;
|
||||
|
||||
void print_error(const char* msg, ...)
|
||||
{
|
||||
|
@ -1,33 +1,27 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
|
||||
#include "game/scripting/entity.hpp"
|
||||
#include "game/scripting/functions.hpp"
|
||||
#include "game/scripting/event.hpp"
|
||||
#include "game/scripting/lua/engine.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
|
||||
#include "console.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "scheduler.hpp"
|
||||
#include "scripting.hpp"
|
||||
|
||||
#include <xsk/gsc/types.hpp>
|
||||
#include <xsk/resolver.hpp>
|
||||
#include <xsk/utils/compression.hpp>
|
||||
#include "game/game.hpp"
|
||||
|
||||
#include "game/scripting/event.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
#include "game/scripting/functions.hpp"
|
||||
#include "game/scripting/lua/engine.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace scripting
|
||||
{
|
||||
std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
|
||||
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
|
||||
std::unordered_map<std::string, std::vector<std::pair<std::string, const char*>>> script_function_table_sort;
|
||||
std::unordered_map<const char*, std::pair<std::string, std::string>> script_function_table_rev;
|
||||
|
||||
utils::concurrency::container<shared_table_t> shared_table;
|
||||
|
||||
std::string current_file;
|
||||
@ -49,7 +43,7 @@ namespace scripting
|
||||
|
||||
utils::hook::detour db_find_xasset_header_hook;
|
||||
|
||||
std::string current_scriptfile;
|
||||
std::string current_script_file;
|
||||
unsigned int current_file_id{};
|
||||
|
||||
game::dvar_t* g_dump_scripts;
|
||||
@ -96,14 +90,11 @@ namespace scripting
|
||||
{
|
||||
if (!game::VirtualLobby_Loaded())
|
||||
{
|
||||
// init game in game log
|
||||
game::G_LogPrintf("------------------------------------------------------------\n");
|
||||
game::G_LogPrintf("InitGame\n");
|
||||
|
||||
// start lua engine
|
||||
lua::engine::start();
|
||||
|
||||
// execute main handles
|
||||
gsc::load_main_handles();
|
||||
}
|
||||
|
||||
@ -114,7 +105,6 @@ namespace scripting
|
||||
{
|
||||
if (!game::VirtualLobby_Loaded())
|
||||
{
|
||||
// execute init handles
|
||||
gsc::load_init_handles();
|
||||
}
|
||||
|
||||
@ -141,7 +131,7 @@ namespace scripting
|
||||
game::G_LogPrintf("ShutdownGame:\n");
|
||||
game::G_LogPrintf("------------------------------------------------------------\n");
|
||||
|
||||
return g_shutdown_game_hook.invoke<void>(free_scripts);
|
||||
g_shutdown_game_hook.invoke<void>(free_scripts);
|
||||
}
|
||||
|
||||
void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t name, unsigned int canonical_string, unsigned int offset)
|
||||
@ -158,7 +148,7 @@ namespace scripting
|
||||
|
||||
void process_script_stub(const char* filename)
|
||||
{
|
||||
current_scriptfile = filename;
|
||||
current_script_file = filename;
|
||||
|
||||
const auto file_id = atoi(filename);
|
||||
if (file_id)
|
||||
@ -182,9 +172,9 @@ namespace scripting
|
||||
filename = scripting::get_token(current_file_id);
|
||||
}
|
||||
|
||||
if (script_function_table_sort.find(filename) == script_function_table_sort.end())
|
||||
if (!script_function_table_sort.contains(filename))
|
||||
{
|
||||
const auto script = gsc::find_script(game::ASSET_TYPE_SCRIPTFILE, current_scriptfile.data(), false);
|
||||
const auto script = gsc::find_script(game::ASSET_TYPE_SCRIPTFILE, current_script_file.data(), false);
|
||||
if (script)
|
||||
{
|
||||
const auto end = &script->bytecode[script->bytecodeLen];
|
||||
@ -201,6 +191,7 @@ namespace scripting
|
||||
{
|
||||
const auto name = get_token(id);
|
||||
script_function_table[file][name] = pos;
|
||||
script_function_table_rev[pos] = {file, name};
|
||||
}
|
||||
|
||||
void scr_set_thread_position_stub(unsigned int thread_name, const char* code_pos)
|
||||
@ -275,7 +266,7 @@ namespace scripting
|
||||
|
||||
g_shutdown_game_hook.create(SELECT_VALUE(0x2A5130_b, 0x422F30_b), g_shutdown_game_stub);
|
||||
|
||||
scheduler::loop([]()
|
||||
scheduler::loop([]
|
||||
{
|
||||
lua::engine::run_frame();
|
||||
}, scheduler::pipeline::server);
|
||||
|
@ -8,6 +8,8 @@ namespace scripting
|
||||
extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
|
||||
extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
|
||||
extern std::unordered_map<std::string, std::vector<std::pair<std::string, const char*>>> script_function_table_sort;
|
||||
extern std::unordered_map<const char*, std::pair<std::string, std::string>> script_function_table_rev;
|
||||
|
||||
extern utils::concurrency::container<shared_table_t> shared_table;
|
||||
|
||||
extern std::string current_file;
|
||||
|
@ -48,16 +48,10 @@ namespace ui_scripting
|
||||
const auto lui_updater = utils::nt::load_resource(LUI_UPDATER);
|
||||
const auto lua_json = utils::nt::load_resource(LUA_JSON);
|
||||
|
||||
struct script
|
||||
{
|
||||
std::string name;
|
||||
std::string root;
|
||||
};
|
||||
|
||||
struct globals_t
|
||||
{
|
||||
std::string in_require_script;
|
||||
std::vector<script> loaded_scripts;
|
||||
std::unordered_map<std::string, std::string> loaded_scripts;
|
||||
bool load_raw_script{};
|
||||
std::string raw_script_name{};
|
||||
};
|
||||
@ -66,28 +60,13 @@ namespace ui_scripting
|
||||
|
||||
bool is_loaded_script(const std::string& name)
|
||||
{
|
||||
for (auto i = globals.loaded_scripts.begin(); i != globals.loaded_scripts.end(); ++i)
|
||||
{
|
||||
if (i->name == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return globals.loaded_scripts.contains(name);
|
||||
}
|
||||
|
||||
std::string get_root_script(const std::string& name)
|
||||
{
|
||||
for (auto i = globals.loaded_scripts.begin(); i != globals.loaded_scripts.end(); ++i)
|
||||
{
|
||||
if (i->name == name)
|
||||
{
|
||||
return i->root;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
const auto itr = globals.loaded_scripts.find(name);
|
||||
return itr == globals.loaded_scripts.end() ? std::string() : itr->second;
|
||||
}
|
||||
|
||||
table get_globals()
|
||||
@ -133,7 +112,7 @@ namespace ui_scripting
|
||||
|
||||
void load_script(const std::string& name, const std::string& data)
|
||||
{
|
||||
globals.loaded_scripts.push_back({name, name});
|
||||
globals.loaded_scripts[name] = name;
|
||||
|
||||
const auto lua = get_globals();
|
||||
const auto load_results = lua["loadstring"](data, name);
|
||||
@ -451,8 +430,10 @@ namespace ui_scripting
|
||||
return hks_package_require_hook.invoke<void*>(state);
|
||||
}
|
||||
|
||||
game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, int allow_create_default)
|
||||
game::XAssetHeader db_find_x_asset_header_stub(game::XAssetType type, const char* name, int allow_create_default)
|
||||
{
|
||||
game::XAssetHeader header{.luaFile = nullptr};
|
||||
|
||||
if (!is_loaded_script(globals.in_require_script))
|
||||
{
|
||||
return game::DB_FindXAssetHeader(type, name, allow_create_default);
|
||||
@ -466,14 +447,14 @@ namespace ui_scripting
|
||||
{
|
||||
globals.load_raw_script = true;
|
||||
globals.raw_script_name = target_script;
|
||||
return static_cast<game::XAssetHeader>(reinterpret_cast<game::LuaFile*>(1));
|
||||
header.luaFile = reinterpret_cast<game::LuaFile*>(1);
|
||||
}
|
||||
else if (name_.starts_with("ui/LUI/"))
|
||||
{
|
||||
return game::DB_FindXAssetHeader(type, name, allow_create_default);
|
||||
}
|
||||
|
||||
return static_cast<game::XAssetHeader>(nullptr);
|
||||
return header;
|
||||
}
|
||||
|
||||
int hks_load_stub(game::hks::lua_State* state, void* compiler_options,
|
||||
@ -482,14 +463,12 @@ namespace ui_scripting
|
||||
if (globals.load_raw_script)
|
||||
{
|
||||
globals.load_raw_script = false;
|
||||
globals.loaded_scripts.push_back({globals.raw_script_name, globals.in_require_script});
|
||||
globals.loaded_scripts[globals.raw_script_name] = globals.in_require_script;
|
||||
return load_buffer(globals.raw_script_name, utils::io::read_file(globals.raw_script_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
return hks_load_hook.invoke<int>(state, compiler_options, reader,
|
||||
reader_data, chunk_name);
|
||||
}
|
||||
|
||||
return hks_load_hook.invoke<int>(state, compiler_options, reader,
|
||||
reader_data, chunk_name);
|
||||
}
|
||||
|
||||
std::string current_error;
|
||||
@ -506,7 +485,7 @@ namespace ui_scripting
|
||||
}
|
||||
|
||||
const auto closure = value.v.cClosure;
|
||||
if (converted_functions.find(closure) == converted_functions.end())
|
||||
if (!converted_functions.contains(closure))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -563,8 +542,8 @@ namespace ui_scripting
|
||||
return;
|
||||
}
|
||||
|
||||
utils::hook::call(SELECT_VALUE(0xE7419_b, 0x25E809_b), db_find_xasset_header_stub);
|
||||
utils::hook::call(SELECT_VALUE(0xE72CB_b, 0x25E6BB_b), db_find_xasset_header_stub);
|
||||
utils::hook::call(SELECT_VALUE(0xE7419_b, 0x25E809_b), db_find_x_asset_header_stub);
|
||||
utils::hook::call(SELECT_VALUE(0xE72CB_b, 0x25E6BB_b), db_find_x_asset_header_stub);
|
||||
|
||||
hks_load_hook.create(SELECT_VALUE(0xB46F0_b, 0x22C180_b), hks_load_stub);
|
||||
|
||||
@ -572,7 +551,7 @@ namespace ui_scripting
|
||||
hks_start_hook.create(SELECT_VALUE(0x103C50_b, 0x27A790_b), hks_start_stub);
|
||||
hks_shutdown_hook.create(SELECT_VALUE(0xFB370_b, 0x2707C0_b), hks_shutdown_stub);
|
||||
|
||||
command::add("lui_restart", []()
|
||||
command::add("lui_restart", []
|
||||
{
|
||||
utils::hook::invoke<void>(SELECT_VALUE(0x1052C0_b, 0x27BEC0_b));
|
||||
});
|
||||
|
Reference in New Issue
Block a user