Skip to content

Commit

Permalink
Add hudelem::set_text + fix format
Browse files Browse the repository at this point in the history
  • Loading branch information
alicealys committed Nov 11, 2023
1 parent 5426cdc commit 7c43dd3
Show file tree
Hide file tree
Showing 5 changed files with 902 additions and 673 deletions.
4 changes: 2 additions & 2 deletions src/component/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ namespace command
for (auto i = argc - 1; i > 1; i--)
{
const auto arg = params[i];
game::add(arg);
scripting::push_value(arg);
}

const auto name = game::SL_GetString(params[1], 0);
Expand Down Expand Up @@ -273,7 +273,7 @@ namespace command
for (auto i = argc - 1; i > 2; i--)
{
const auto arg = params[i];
game::add(arg);
scripting::push_value(arg);
}

const auto name = game::SL_GetString(params[2], 0);
Expand Down
152 changes: 152 additions & 0 deletions src/component/config_strings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include <stdinc.hpp>
#include "loader/component_loader.hpp"

#include "gsc.hpp"
#include "scripting.hpp"

#include <utils/hook.hpp>

namespace config_strings
{
namespace
{
std::unordered_set<std::uint32_t> reserved_config_strings;
std::unordered_map<game::game_hudelem_s*, std::uint32_t> hudelem_config_strings;

bool is_string_reserved(const std::uint32_t offset)
{
return reserved_config_strings.contains(offset);
}

std::uint32_t get_config_string()
{
auto index = -1;
const auto scr_const_ = *reinterpret_cast<short*>(SELECT(0x24E5588, 0x24B7188));
for (auto i = 1; i < 512; i++)
{
const auto string_value = game::sv_configstrings[i + 488];
if (string_value == scr_const_ && !is_string_reserved(i))
{
index = i;
break;
}
}

if (index == -1)
{
throw std::runtime_error("out of config strings");
}

reserved_config_strings.insert(index);

return index;
}

utils::hook::detour scr_free_hud_elem_hook;
void scr_free_hud_elem_stub(game::game_hudelem_s* hud)
{
const auto _0 = gsl::finally([&]
{
scr_free_hud_elem_hook.invoke<void>(hud);
});

const auto iter = hudelem_config_strings.find(hud);
if (iter == hudelem_config_strings.end())
{
return;
}

game::SV_SetConfigString(iter->second + 488, 0);
reserved_config_strings.erase(iter->second);
hudelem_config_strings.erase(iter);
}

void g_localized_string_index_stub_1(utils::hook::assembler& a)
{
const auto not_reserved = a.newLabel();

a.add(esp, 4);

a.pushad();
a.push(esi);
a.call(is_string_reserved);
a.cmp(al, 0);
a.jz(not_reserved);

a.pop(esi);
a.popad();
a.jmp(SELECT(0x6D657E, 0x467D6E));

a.bind(not_reserved);
a.pop(esi);
a.popad();

a.cmp(eax, ecx);
a.jmp(SELECT(0x6D6578, 0x467D68));
}

void g_localized_string_index_stub_2(utils::hook::assembler& a)
{
const auto not_reserved = a.newLabel();

a.add(esp, 4);

a.pushad();
a.push(esi);
a.call(is_string_reserved);
a.cmp(al, 0);
a.jz(not_reserved);

a.pop(esi);
a.popad();
a.jmp(SELECT(0x6D6638, 0x467E2E));

a.bind(not_reserved);
a.pop(esi);
a.popad();

a.cmp(eax, ecx);
a.jmp(SELECT(0x6D663E, 0x467E28));
}
}

class component final : public component_interface
{
public:
void post_unpack() override
{
utils::hook::jump(SELECT(0x6D6573, 0x467D63), utils::hook::assemble(g_localized_string_index_stub_1));
utils::hook::jump(SELECT(0x6D6633, 0x467E23), utils::hook::assemble(g_localized_string_index_stub_2));
scr_free_hud_elem_hook.create(SELECT(0x56E800, 0x6186A0), scr_free_hud_elem_stub);

scripting::on_shutdown([&]
{
reserved_config_strings.clear();
hudelem_config_strings.clear();
});

gsc::method::add("hudelem::set_text", [](const scripting::entity& entity, const std::string& text)
{
const auto ent = entity.get_entity_reference();
const auto hudelem = &game::g_hudelems[ent.entnum];
const auto iter = hudelem_config_strings.find(hudelem);

if (iter == hudelem_config_strings.end())
{
const auto index = get_config_string();
printf("reserve string %i\n", index);
hudelem->elem.text = static_cast<short>(index);
hudelem_config_strings.insert(std::make_pair(hudelem, index));
}
else
{
hudelem->elem.text = static_cast<short>(iter->second);
}

game::SV_SetConfigString(hudelem->elem.text + 488, text.data());
});
}
};
}

REGISTER_COMPONENT(config_strings::component)
Loading

0 comments on commit 7c43dd3

Please sign in to comment.