This commit is contained in:
alice
2026-07-26 02:06:25 +02:00
parent b2bd1e0835
commit 50438cef27
30 changed files with 215 additions and 1179 deletions
-16
View File
@@ -96,20 +96,4 @@ namespace scripting
game::RemoveRefToValue(game::SCRIPT_OBJECT, {static_cast<int>(this->entity_id_)});
}
}
void entity::set(const std::string& field, const script_value& value) const
{
set_entity_field(*this, field, value);
}
template <>
script_value entity::get<script_value>(const std::string& field) const
{
return get_entity_field(*this, field);
}
script_value entity::call(const std::string& name, const std::vector<script_value>& arguments) const
{
return call_function(name, *this, arguments);
}
}
-16
View File
@@ -18,13 +18,6 @@ namespace scripting
entity& operator=(const entity& other);
entity& operator=(entity&& other) noexcept;
void set(const std::string& field, const script_value& value) const;
template <typename T = script_value>
T get(const std::string& field) const;
script_value call(const std::string& name, const std::vector<script_value>& arguments = {}) const;
unsigned int get_entity_id() const;
game::scr_entref_t get_entity_reference() const;
@@ -37,13 +30,4 @@ namespace scripting
void add() const;
void release() const;
};
template <>
script_value entity::get(const std::string& field) const;
template <typename T>
T entity::get(const std::string& field) const
{
return this->get<script_value>(field).as<T>();
}
}
-167
View File
@@ -32,16 +32,6 @@ namespace scripting
return script_value(game::scr_VmPub->top[1 - game::scr_VmPub->outparamcount]);
}
int get_field_id(const int classnum, const std::string& field)
{
if (scripting::fields_table[classnum].find(field) != scripting::fields_table[classnum].end())
{
return scripting::fields_table[classnum][field];
}
return -1;
}
void scr_notify_id(int id, unsigned int stringValue, unsigned int paramcount)
{
if (game::scr_VmPub->outparamcount)
@@ -95,47 +85,6 @@ namespace scripting
scr_notify_id(entity.get_entity_id(), event_id, game::scr_VmPub->inparamcount);
}
script_value call_function(const std::string& name, const entity& entity,
const std::vector<script_value>& arguments)
{
const auto entref = entity.get_entity_reference();
const auto is_method_call = *reinterpret_cast<const int*>(&entref) != -1;
const auto function = find_function(name, !is_method_call);
if (!function)
{
throw std::runtime_error("Unknown function '" + name + "'");
}
stack_isolation _;
for (auto i = arguments.rbegin(); i != arguments.rend(); ++i)
{
push_value(*i);
}
game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount;
game::scr_VmPub->inparamcount = 0;
if (!safe_execution::call(function, entref))
{
throw std::runtime_error("Error executing function '" + name + "'");
}
return get_return_value();
}
script_value call_function(const std::string& name, const std::vector<script_value>& arguments)
{
return call_function(name, entity(), arguments);
}
template <>
script_value call(const std::string& name, const std::vector<script_value>& arguments)
{
return call_function(name, arguments);
}
script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector<script_value>& arguments)
{
const auto id = entity.get_entity_id();
@@ -155,122 +104,6 @@ namespace scripting
return get_return_value();
}
const char* get_function_pos(const std::string& filename, const std::string& function)
{
if (scripting::script_function_table.find(filename) == scripting::script_function_table.end())
{
throw std::runtime_error("File '" + filename + "' not found");
};
const auto functions = scripting::script_function_table[filename];
if (functions.find(function) == functions.end())
{
throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found");
}
return functions.at(function);
}
script_value call_script_function(const entity& entity, const std::string& filename,
const std::string& function, const std::vector<script_value>& arguments)
{
const auto pos = get_function_pos(filename, function);
return exec_ent_thread(entity, pos, arguments);
}
static std::unordered_map<unsigned int, std::unordered_map<std::string, script_value>> custom_fields;
script_value get_custom_field(const entity& entity, const std::string& field)
{
auto fields = custom_fields[entity.get_entity_id()];
const auto _field = fields.find(field);
if (_field != fields.end())
{
return _field->second;
}
return {};
}
void set_custom_field(const entity& entity, const std::string& field, const script_value& value)
{
const auto id = entity.get_entity_id();
if (custom_fields[id].find(field) != custom_fields[id].end())
{
custom_fields[id][field] = value;
return;
}
custom_fields[id].insert(std::make_pair(field, value));
}
void clear_entity_fields(const entity& entity)
{
const auto id = entity.get_entity_id();
if (custom_fields.find(id) != custom_fields.end())
{
custom_fields[id].clear();
}
}
void clear_custom_fields()
{
custom_fields.clear();
}
void set_entity_field(const entity& entity, const std::string& field, const script_value& value)
{
const auto entref = entity.get_entity_reference();
const int id = get_field_id(entref.classnum, field);
if (id != -1)
{
stack_isolation _;
push_value(value);
game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount;
game::scr_VmPub->inparamcount = 0;
if (!safe_execution::set_entity_field(entref, id))
{
throw std::runtime_error("Failed to set value for field '" + field + "'");
}
}
else
{
set_custom_field(entity, field, value);
}
}
script_value get_entity_field(const entity& entity, const std::string& field)
{
const auto entref = entity.get_entity_reference();
const auto id = get_field_id(entref.classnum, field);
if (id != -1)
{
stack_isolation _;
game::VariableValue value{};
if (!safe_execution::get_entity_field(entref, id, &value))
{
throw std::runtime_error("Failed to get value for field '" + field + "'");
}
const auto __ = gsl::finally([value]()
{
game::RemoveRefToValue(value.type, value.u);
});
return value;
}
else
{
return get_custom_field(entity, field);
}
}
unsigned int make_array()
{
unsigned int index = 0;
-12
View File
@@ -9,10 +9,6 @@ namespace scripting
{
void push_value(const script_value& value);
script_value call_function(const std::string& name, const std::vector<script_value>& arguments);
script_value call_function(const std::string& name, const entity& entity,
const std::vector<script_value>& arguments);
template <typename T = script_value>
T call(const std::string& name, const std::vector<script_value>& arguments = {});
@@ -26,14 +22,6 @@ namespace scripting
}
script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector<script_value>& arguments);
script_value call_script_function(const entity& entity, const std::string& filename,
const std::string& function, const std::vector<script_value>& arguments);
void clear_entity_fields(const entity& entity);
void clear_custom_fields();
void set_entity_field(const entity& entity, const std::string& field, const script_value& value);
script_value get_entity_field(const entity& entity, const std::string& field);
void notify(const entity& entity, const std::string& event, const std::vector<script_value>& arguments);
-59
View File
@@ -5,64 +5,5 @@
namespace scripting
{
namespace
{
int find_function_index(const std::string& name, [[maybe_unused]] const bool prefer_global)
{
const auto target = utils::string::to_lower(name);
auto const& first = (*game::plutonium::gsc_ctx)->func_map();
auto const& second = (*game::plutonium::gsc_ctx)->meth_map();
if (const auto itr = first.find(name); itr != first.end())
{
return static_cast<int>(itr->second);
}
if (const auto itr = second.find(name); itr != second.end())
{
return static_cast<int>(itr->second);
}
return -1;
}
script_function get_function_by_index(const unsigned index)
{
static const auto function_table = game::plutonium::function_table.get();
static const auto method_table = game::plutonium::method_table.get();
if (index < 0x1C7)
{
return reinterpret_cast<script_function*>(function_table)[index];
}
return reinterpret_cast<script_function*>(method_table)[index - 0x8000];
}
}
std::string find_token(unsigned int id)
{
return (*game::plutonium::gsc_ctx)->token_name(id);
}
std::string find_file(unsigned int id)
{
return find_token(id);
}
int find_token_id(const std::string& name)
{
return (*game::plutonium::gsc_ctx)->token_id(name);
}
script_function find_function(const std::string& name, const bool prefer_global)
{
const auto index = find_function_index(name, prefer_global);
if (index < 0)
{
return nullptr;
}
return get_function_by_index(index);
}
}
-5
View File
@@ -4,9 +4,4 @@
namespace scripting
{
using script_function = void(*)(game::scr_entref_t);
script_function find_function(const std::string& name, const bool prefer_global);
int find_token_id(const std::string& name);
std::string find_token(unsigned int id);
std::string find_file(unsigned int id);
}
-7
View File
@@ -83,11 +83,4 @@ namespace game
WEAK symbol<dvar_t> sv_maxclients{0x1BA0E4C};
WEAK symbol<int> svs_clientCount{0x4B5CF8C};
WEAK symbol<client_s> svs_clients{0x4B5CF90};
namespace plutonium
{
WEAK symbol<std::unique_ptr<xsk::gsc::iw5_pc::context>> gsc_ctx{0};
WEAK symbol<void*> function_table{0};
WEAK symbol<void*> method_table{0};
}
}