[Script] Add way to modify player name
This commit is contained in:
parent
db51c06a12
commit
854949a34f
3
deps/premake/json11.lua
vendored
3
deps/premake/json11.lua
vendored
@ -15,6 +15,7 @@ end
|
|||||||
function json11.project()
|
function json11.project()
|
||||||
project "json11"
|
project "json11"
|
||||||
language "C++"
|
language "C++"
|
||||||
|
cppdialect "C++11"
|
||||||
|
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
@ -29,4 +30,4 @@ function json11.project()
|
|||||||
kind "StaticLib"
|
kind "StaticLib"
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(dependencies, json11)
|
table.insert(dependencies, json11)
|
||||||
|
@ -109,6 +109,7 @@ namespace Components
|
|||||||
Loader::Register(new RawMouse());
|
Loader::Register(new RawMouse());
|
||||||
Loader::Register(new Bullet());
|
Loader::Register(new Bullet());
|
||||||
Loader::Register(new Ceg());
|
Loader::Register(new Ceg());
|
||||||
|
Loader::Register(new UserInfo());
|
||||||
|
|
||||||
Loader::Pregame = false;
|
Loader::Pregame = false;
|
||||||
}
|
}
|
||||||
|
@ -140,3 +140,4 @@ namespace Components
|
|||||||
#include "Modules/RawMouse.hpp"
|
#include "Modules/RawMouse.hpp"
|
||||||
#include "Modules/Bullet.hpp"
|
#include "Modules/Bullet.hpp"
|
||||||
#include "Modules/Ceg.hpp"
|
#include "Modules/Ceg.hpp"
|
||||||
|
#include "Modules/UserInfo.hpp"
|
||||||
|
@ -451,7 +451,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerList::Insert(Network::Address address, Utils::InfoString info)
|
void ServerList::Insert(const Network::Address& address, const Utils::InfoString& info)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(ServerList::RefreshContainer.mutex);
|
std::lock_guard<std::recursive_mutex> _(ServerList::RefreshContainer.mutex);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ namespace Components
|
|||||||
static void RefreshVisibleListInternal(UIScript::Token, bool refresh = false);
|
static void RefreshVisibleListInternal(UIScript::Token, bool refresh = false);
|
||||||
static void UpdateVisibleList(UIScript::Token);
|
static void UpdateVisibleList(UIScript::Token);
|
||||||
static void InsertRequest(Network::Address address);
|
static void InsertRequest(Network::Address address);
|
||||||
static void Insert(Network::Address address, Utils::InfoString info);
|
static void Insert(const Network::Address& address, const Utils::InfoString& info);
|
||||||
|
|
||||||
static ServerInfo* GetCurrentServer();
|
static ServerInfo* GetCurrentServer();
|
||||||
|
|
||||||
|
76
src/Components/Modules/UserInfo.cpp
Normal file
76
src/Components/Modules/UserInfo.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
std::unordered_map<int, UserInfo::userInfoMap> UserInfo::UserInfoOverrides;
|
||||||
|
|
||||||
|
void UserInfo::SV_GetUserInfo_Stub(int index, char* buffer, int bufferSize)
|
||||||
|
{
|
||||||
|
Utils::Hook::Call<void(int, char*, int)>(0x49A160)(index, buffer, bufferSize);
|
||||||
|
|
||||||
|
Utils::InfoString map(buffer);
|
||||||
|
|
||||||
|
if (!UserInfoOverrides.contains(index))
|
||||||
|
{
|
||||||
|
UserInfoOverrides[index] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [key, val] : UserInfoOverrides[index])
|
||||||
|
{
|
||||||
|
if (val.empty())
|
||||||
|
{
|
||||||
|
map.remove(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map.set(key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto userInfo = map.build();
|
||||||
|
strncpy_s(buffer, bufferSize, userInfo.data(), _TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfo::ClearClientOverrides(const int client)
|
||||||
|
{
|
||||||
|
UserInfoOverrides[client].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfo::ClearAllOverrides()
|
||||||
|
{
|
||||||
|
UserInfoOverrides.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInfo::AddScriptMethods()
|
||||||
|
{
|
||||||
|
Script::AddMethod("SetName", [](Game::scr_entref_t entref) // gsc: self SetName(<string>)
|
||||||
|
{
|
||||||
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
const auto* name = Game::Scr_GetString(0);
|
||||||
|
|
||||||
|
UserInfoOverrides[ent->s.number]["name"] = name;
|
||||||
|
Game::ClientUserinfoChanged(ent->s.number);
|
||||||
|
});
|
||||||
|
|
||||||
|
Script::AddMethod("ResetName", [](Game::scr_entref_t entref) // gsc: self ResetName()
|
||||||
|
{
|
||||||
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
|
||||||
|
UserInfoOverrides[ent->s.number].erase("name");
|
||||||
|
Game::ClientUserinfoChanged(ent->s.number);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo::UserInfo()
|
||||||
|
{
|
||||||
|
Utils::Hook(0x445268, SV_GetUserInfo_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x478B04, SV_GetUserInfo_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
AddScriptMethods();
|
||||||
|
|
||||||
|
Script::OnVMShutdown([]
|
||||||
|
{
|
||||||
|
ClearAllOverrides();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
21
src/Components/Modules/UserInfo.hpp
Normal file
21
src/Components/Modules/UserInfo.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class UserInfo : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UserInfo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
using userInfoMap = std::unordered_map<std::string, std::string>;
|
||||||
|
static std::unordered_map<int, userInfoMap> UserInfoOverrides;
|
||||||
|
|
||||||
|
static void SV_GetUserInfo_Stub(int index, char* buffer, int bufferSize);
|
||||||
|
|
||||||
|
static void ClearClientOverrides(int client);
|
||||||
|
static void ClearAllOverrides();
|
||||||
|
|
||||||
|
static void AddScriptMethods();
|
||||||
|
};
|
||||||
|
}
|
@ -431,6 +431,8 @@ namespace Game
|
|||||||
IN_Init_t IN_Init = IN_Init_t(0x45D620);
|
IN_Init_t IN_Init = IN_Init_t(0x45D620);
|
||||||
IN_Shutdown_t IN_Shutdown = IN_Shutdown_t(0x426360);
|
IN_Shutdown_t IN_Shutdown = IN_Shutdown_t(0x426360);
|
||||||
|
|
||||||
|
ClientUserinfoChanged_t ClientUserinfoChanged = ClientUserinfoChanged_t(0x445240);
|
||||||
|
|
||||||
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
||||||
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
||||||
|
|
||||||
|
@ -1029,6 +1029,9 @@ namespace Game
|
|||||||
typedef void(__cdecl * IN_Shutdown_t)();
|
typedef void(__cdecl * IN_Shutdown_t)();
|
||||||
extern IN_Shutdown_t IN_Shutdown;
|
extern IN_Shutdown_t IN_Shutdown;
|
||||||
|
|
||||||
|
typedef void(__cdecl * ClientUserinfoChanged_t)(int clientNum);
|
||||||
|
extern ClientUserinfoChanged_t ClientUserinfoChanged;
|
||||||
|
|
||||||
extern XAssetHeader* DB_XAssetPool;
|
extern XAssetHeader* DB_XAssetPool;
|
||||||
extern unsigned int* g_poolSize;
|
extern unsigned int* g_poolSize;
|
||||||
|
|
||||||
|
@ -2,12 +2,22 @@
|
|||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
|
InfoString::InfoString(const std::string& buffer)
|
||||||
|
{
|
||||||
|
this->parse(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void InfoString::set(const std::string& key, const std::string& value)
|
void InfoString::set(const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
this->keyValuePairs[key] = value;
|
this->keyValuePairs[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InfoString::get(const std::string& key)
|
void InfoString::remove(const std::string& key)
|
||||||
|
{
|
||||||
|
this->keyValuePairs.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InfoString::get(const std::string& key) const
|
||||||
{
|
{
|
||||||
const auto value = this->keyValuePairs.find(key);
|
const auto value = this->keyValuePairs.find(key);
|
||||||
if (value != this->keyValuePairs.end())
|
if (value != this->keyValuePairs.end())
|
||||||
@ -15,7 +25,7 @@ namespace Utils
|
|||||||
return value->second;
|
return value->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoString::parse(std::string buffer)
|
void InfoString::parse(std::string buffer)
|
||||||
@ -25,17 +35,17 @@ namespace Utils
|
|||||||
buffer = buffer.substr(1);
|
buffer = buffer.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto KeyValues = Utils::String::Split(buffer, '\\');
|
const auto keyValues = Utils::String::Split(buffer, '\\');
|
||||||
|
|
||||||
for (size_t i = 0; !KeyValues.empty() && i < (KeyValues.size() - 1); i += 2)
|
for (std::size_t i = 0; !keyValues.empty() && i < (keyValues.size() - 1); i += 2)
|
||||||
{
|
{
|
||||||
const auto& key = KeyValues[i];
|
const auto& key = keyValues[i];
|
||||||
const auto& value = KeyValues[i + 1];
|
const auto& value = keyValues[i + 1];
|
||||||
this->keyValuePairs[key] = value;
|
this->keyValuePairs[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InfoString::build()
|
std::string InfoString::build() const
|
||||||
{
|
{
|
||||||
std::string infoString;
|
std::string infoString;
|
||||||
|
|
||||||
@ -54,16 +64,18 @@ namespace Utils
|
|||||||
return infoString;
|
return infoString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
void InfoString::dump()
|
void InfoString::dump()
|
||||||
{
|
{
|
||||||
for (const auto& [key, value] : this->keyValuePairs)
|
for (const auto& [key, value] : this->keyValuePairs)
|
||||||
{
|
{
|
||||||
OutputDebugStringA(Utils::String::VA("%s: %s\n", key.data(), value.data()));
|
OutputDebugStringA(String::VA("%s: %s\n", key.data(), value.data()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
json11::Json InfoString::to_json()
|
json11::Json InfoString::to_json() const
|
||||||
{
|
{
|
||||||
return this->keyValuePairs;
|
return {this->keyValuePairs};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,23 @@ namespace Utils
|
|||||||
class InfoString
|
class InfoString
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InfoString() {};
|
InfoString() = default;
|
||||||
InfoString(const std::string& buffer) : InfoString() { this->parse(buffer); };
|
explicit InfoString(const std::string& buffer);
|
||||||
|
|
||||||
void set(const std::string& key, const std::string& value);
|
void set(const std::string& key, const std::string& value);
|
||||||
std::string get(const std::string& key);
|
void remove(const std::string& key);
|
||||||
std::string build();
|
|
||||||
|
|
||||||
|
[[nodiscard]] std::string get(const std::string& key) const;
|
||||||
|
[[nodiscard]] std::string build() const;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
void dump();
|
void dump();
|
||||||
|
#endif
|
||||||
|
|
||||||
json11::Json to_json();
|
[[nodiscard]] json11::Json to_json() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> keyValuePairs;
|
std::unordered_map<std::string, std::string> keyValuePairs;
|
||||||
void parse(std::string buffer);
|
void parse(std::string buffer);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user