mirror of
https://github.com/fedddddd/iw5-gsc-utils.git
synced 2025-04-22 05:35:43 +00:00
Add functions to change player clantags/name
This commit is contained in:
parent
97371d8f44
commit
9ead1676b0
@ -339,7 +339,7 @@ namespace gsc
|
||||
{
|
||||
if (ent.classnum != 0)
|
||||
{
|
||||
throw std::runtime_error("Invalid type");
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
const auto client = ent.entnum;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "scheduler.hpp"
|
||||
#include "command.hpp"
|
||||
#include "userinfo.hpp"
|
||||
|
||||
#include "game/scripting/event.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
@ -46,7 +47,9 @@ namespace scripting
|
||||
|
||||
if (e.name == "connected")
|
||||
{
|
||||
scripting::clear_entity_fields(e.entity);
|
||||
const auto player = e.arguments[0].as<scripting::entity>();
|
||||
const auto client = player.call("getentitynumber").as<int>();
|
||||
userinfo::clear_client_overrides(client);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +75,7 @@ namespace scripting
|
||||
|
||||
void g_shutdown_game_stub(const int free_scripts)
|
||||
{
|
||||
userinfo::clear_overrides();
|
||||
command::clear_script_commands();
|
||||
gsc::replaced_functions.clear();
|
||||
g_shutdown_game_hook.invoke<void>(free_scripts);
|
||||
|
177
src/component/userinfo.cpp
Normal file
177
src/component/userinfo.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include <stdinc.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include "game/scripting/event.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
#include "game/scripting/functions.hpp"
|
||||
#include "game/scripting/array.hpp"
|
||||
|
||||
#include "gsc.hpp"
|
||||
|
||||
namespace userinfo
|
||||
{
|
||||
using userinfo_map = std::unordered_map<std::string, std::string>;
|
||||
std::unordered_map<int, userinfo_map> userinfo_overrides;
|
||||
|
||||
namespace
|
||||
{
|
||||
utils::hook::detour sv_getuserinfo_hook;
|
||||
|
||||
userinfo_map userinfo_to_map(const std::string& userinfo)
|
||||
{
|
||||
userinfo_map map;
|
||||
const auto args = utils::string::split(userinfo, '\\');
|
||||
|
||||
for (auto i = 1; i < args.size() - 1; i += 2)
|
||||
{
|
||||
map[args[i]] = args[i + 1];
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
std::string map_to_userinfo(const userinfo_map& map)
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
for (const auto& value : map)
|
||||
{
|
||||
buffer.append("\\");
|
||||
buffer.append(value.first);
|
||||
buffer.append("\\");
|
||||
buffer.append(value.second);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void sv_getuserinfo_stub(int index, char* buffer, int bufferSize)
|
||||
{
|
||||
char _buffer[1024];
|
||||
sv_getuserinfo_hook.invoke<void>(index, _buffer, 1024);
|
||||
auto map = userinfo_to_map(_buffer);
|
||||
|
||||
if (userinfo_overrides.find(index) == userinfo_overrides.end())
|
||||
{
|
||||
userinfo_overrides[index] = {};
|
||||
}
|
||||
|
||||
for (const auto& values : userinfo_overrides[index])
|
||||
{
|
||||
if (values.second.empty())
|
||||
{
|
||||
map.erase(values.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
map[values.first] = values.second;
|
||||
}
|
||||
}
|
||||
|
||||
const auto userinfo = map_to_userinfo(map);
|
||||
strcpy_s(buffer, 1024, userinfo.data());
|
||||
}
|
||||
}
|
||||
|
||||
void clear_client_overrides(int client)
|
||||
{
|
||||
userinfo_overrides[client].clear();
|
||||
}
|
||||
|
||||
void clear_overrides()
|
||||
{
|
||||
userinfo_overrides.clear();
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
sv_getuserinfo_hook.create(0x573E00, sv_getuserinfo_stub);
|
||||
|
||||
gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto name = args[0].as<std::string>();
|
||||
|
||||
if (ent.classnum != 0 || ent.entnum > 17)
|
||||
{
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
userinfo_overrides[ent.entnum]["name"] = name;
|
||||
game::ClientUserinfoChanged(ent.entnum);
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto name = args[0].as<std::string>();
|
||||
|
||||
if (ent.classnum != 0 || ent.entnum > 17)
|
||||
{
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
userinfo_overrides[ent.entnum].erase("name");
|
||||
game::ClientUserinfoChanged(ent.entnum);
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto name = args[0].as<std::string>();
|
||||
|
||||
if (ent.classnum != 0 || ent.entnum > 17)
|
||||
{
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
userinfo_overrides[ent.entnum]["clantag"] = name;
|
||||
userinfo_overrides[ent.entnum]["ec_TagText"] = name;
|
||||
userinfo_overrides[ent.entnum]["ec_usingTag"] = "1";
|
||||
game::ClientUserinfoChanged(ent.entnum);
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
const auto name = args[0].as<std::string>();
|
||||
|
||||
if (ent.classnum != 0 || ent.entnum > 17)
|
||||
{
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
userinfo_overrides[ent.entnum].erase("clantag");
|
||||
userinfo_overrides[ent.entnum].erase("ec_TagText");
|
||||
userinfo_overrides[ent.entnum].erase("ec_usingTag");
|
||||
game::ClientUserinfoChanged(ent.entnum);
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||
{
|
||||
if (ent.classnum != 0 || ent.entnum > 17)
|
||||
{
|
||||
throw std::runtime_error("Invalid entity");
|
||||
}
|
||||
|
||||
userinfo_overrides[ent.entnum]["clantag"] = "";
|
||||
userinfo_overrides[ent.entnum]["ec_TagText"] = "";
|
||||
userinfo_overrides[ent.entnum]["ec_usingTag"] = "0";
|
||||
game::ClientUserinfoChanged(ent.entnum);
|
||||
|
||||
return {};
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(userinfo::component)
|
7
src/component/userinfo.hpp
Normal file
7
src/component/userinfo.hpp
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace userinfo
|
||||
{
|
||||
void clear_client_overrides(int client);
|
||||
void clear_overrides();
|
||||
}
|
@ -16,6 +16,7 @@ namespace game
|
||||
|
||||
WEAK symbol<void(unsigned int weapon, bool isAlternate, char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x42F760};
|
||||
|
||||
WEAK symbol<void(int client)> ClientUserinfoChanged{0x4FADB0};
|
||||
WEAK symbol<const char*(int index)> ConcatArgs{0x502150};
|
||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x545680};
|
||||
WEAK symbol<void(const char* cmdName, void(), cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x545DF0};
|
||||
|
Loading…
x
Reference in New Issue
Block a user