Merge branch 'develop' into new-map-rotation
This commit is contained in:
commit
b5d4da254e
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -25,7 +25,7 @@
|
|||||||
[submodule "deps/protobuf"]
|
[submodule "deps/protobuf"]
|
||||||
path = deps/protobuf
|
path = deps/protobuf
|
||||||
url = https://github.com/google/protobuf.git
|
url = https://github.com/google/protobuf.git
|
||||||
branch = 3.17.x
|
branch = 3.20.x
|
||||||
[submodule "deps/udis86"]
|
[submodule "deps/udis86"]
|
||||||
path = deps/udis86
|
path = deps/udis86
|
||||||
url = https://github.com/vmt/udis86.git
|
url = https://github.com/vmt/udis86.git
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
| `--copy-pdb` | Copy debug information for binaries as well to the path given via --copy-to. |
|
| `--copy-pdb` | Copy debug information for binaries as well to the path given via --copy-to. |
|
||||||
| `--force-unit-tests` | Always compile unit tests. |
|
| `--force-unit-tests` | Always compile unit tests. |
|
||||||
| `--force-exception-handler` | Install custom unhandled exception handler even for Debug builds. |
|
| `--force-exception-handler` | Install custom unhandled exception handler even for Debug builds. |
|
||||||
| `--force-minidump-upload` | Upload minidumps even for Debug builds. |
|
| `--disable-binary-check` | Do not perform integrity checks on the exe. |
|
||||||
| `--iw4x-zones` | Zonebuilder generates iw4x zones that cannot be loaded without IW4x specific patches. |
|
| `--iw4x-zones` | Zonebuilder generates iw4x zones that cannot be loaded without IW4x specific patches. |
|
||||||
|
|
||||||
## Command line arguments
|
## Command line arguments
|
||||||
|
1
deps/premake/json11.lua
vendored
1
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
|
||||||
{
|
{
|
||||||
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b
|
Subproject commit 6e9e60367d8744e86856590d8ea0e793c61deeec
|
12
premake5.lua
12
premake5.lua
@ -82,8 +82,8 @@ newoption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newoption {
|
newoption {
|
||||||
trigger = "force-minidump-upload",
|
trigger = "disable-binary-check",
|
||||||
description = "Upload minidumps even for Debug builds."
|
description = "Do not perform integrity checks on the exe."
|
||||||
}
|
}
|
||||||
|
|
||||||
newoption {
|
newoption {
|
||||||
@ -206,7 +206,7 @@ workspace "iw4x"
|
|||||||
configurations {"Debug", "Release"}
|
configurations {"Debug", "Release"}
|
||||||
|
|
||||||
language "C++"
|
language "C++"
|
||||||
cppdialect "C++17"
|
cppdialect "C++20"
|
||||||
|
|
||||||
architecture "x86"
|
architecture "x86"
|
||||||
platforms "Win32"
|
platforms "Win32"
|
||||||
@ -262,12 +262,12 @@ workspace "iw4x"
|
|||||||
if _OPTIONS["force-unit-tests"] then
|
if _OPTIONS["force-unit-tests"] then
|
||||||
defines {"FORCE_UNIT_TESTS"}
|
defines {"FORCE_UNIT_TESTS"}
|
||||||
end
|
end
|
||||||
if _OPTIONS["force-minidump-upload"] then
|
|
||||||
defines {"FORCE_MINIDUMP_UPLOAD"}
|
|
||||||
end
|
|
||||||
if _OPTIONS["force-exception-handler"] then
|
if _OPTIONS["force-exception-handler"] then
|
||||||
defines {"FORCE_EXCEPTION_HANDLER"}
|
defines {"FORCE_EXCEPTION_HANDLER"}
|
||||||
end
|
end
|
||||||
|
if _OPTIONS["disable-binary-check"] then
|
||||||
|
defines {"DISABLE_BINARY_CHECK"}
|
||||||
|
end
|
||||||
if _OPTIONS["iw4x-zones"] then
|
if _OPTIONS["iw4x-zones"] then
|
||||||
defines {"GENERATE_IW4X_SPECIFIC_ZONES"}
|
defines {"GENERATE_IW4X_SPECIFIC_ZONES"}
|
||||||
end
|
end
|
||||||
|
@ -109,6 +109,8 @@ namespace Components
|
|||||||
Loader::Register(new RawMouse());
|
Loader::Register(new RawMouse());
|
||||||
Loader::Register(new Bullet());
|
Loader::Register(new Bullet());
|
||||||
Loader::Register(new MapRotation());
|
Loader::Register(new MapRotation());
|
||||||
|
Loader::Register(new Ceg());
|
||||||
|
Loader::Register(new UserInfo());
|
||||||
|
|
||||||
Loader::Pregame = false;
|
Loader::Pregame = false;
|
||||||
}
|
}
|
||||||
|
@ -140,3 +140,5 @@ namespace Components
|
|||||||
#include "Modules/RawMouse.hpp"
|
#include "Modules/RawMouse.hpp"
|
||||||
#include "Modules/Bullet.hpp"
|
#include "Modules/Bullet.hpp"
|
||||||
#include "Modules/MapRotation.hpp"
|
#include "Modules/MapRotation.hpp"
|
||||||
|
#include "Modules/Ceg.hpp"
|
||||||
|
#include "Modules/UserInfo.hpp"
|
||||||
|
@ -23,7 +23,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AssetHandler::AssetInterfaces.find(iAsset->getType()) != AssetHandler::AssetInterfaces.end())
|
if (AssetHandler::AssetInterfaces.contains(iAsset->getType()))
|
||||||
{
|
{
|
||||||
Logger::Print("Duplicate asset interface: %s\n", Game::DB_GetXAssetTypeName(iAsset->getType()));
|
Logger::Print("Duplicate asset interface: %s\n", Game::DB_GetXAssetTypeName(iAsset->getType()));
|
||||||
delete AssetHandler::AssetInterfaces[iAsset->getType()];
|
delete AssetHandler::AssetInterfaces[iAsset->getType()];
|
||||||
@ -58,7 +58,7 @@ namespace Components
|
|||||||
// Allow call DB_FindXAssetHeader within the hook
|
// Allow call DB_FindXAssetHeader within the hook
|
||||||
AssetHandler::SetBypassState(true);
|
AssetHandler::SetBypassState(true);
|
||||||
|
|
||||||
if (AssetHandler::TypeCallbacks.find(type) != AssetHandler::TypeCallbacks.end())
|
if (AssetHandler::TypeCallbacks.contains(type))
|
||||||
{
|
{
|
||||||
header = AssetHandler::TypeCallbacks[type](type, filename);
|
header = AssetHandler::TypeCallbacks[type](type, filename);
|
||||||
}
|
}
|
||||||
@ -329,17 +329,17 @@ namespace Components
|
|||||||
{
|
{
|
||||||
void* pointer = (*Game::g_streamBlocks)[offset->getUnpackedBlock()].data + offset->getUnpackedOffset();
|
void* pointer = (*Game::g_streamBlocks)[offset->getUnpackedBlock()].data + offset->getUnpackedOffset();
|
||||||
|
|
||||||
if (AssetHandler::Relocations.find(pointer) != AssetHandler::Relocations.end())
|
if (AssetHandler::Relocations.contains(pointer))
|
||||||
{
|
{
|
||||||
pointer = AssetHandler::Relocations[pointer];
|
pointer = AssetHandler::Relocations[pointer];
|
||||||
}
|
}
|
||||||
|
|
||||||
offset->pointer = *reinterpret_cast<void**>(pointer);
|
offset->pointer = *static_cast<void**>(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder)
|
void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder)
|
||||||
{
|
{
|
||||||
if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end())
|
if (AssetHandler::AssetInterfaces.contains(asset.type))
|
||||||
{
|
{
|
||||||
AssetHandler::AssetInterfaces[asset.type]->save(asset.header, builder);
|
AssetHandler::AssetInterfaces[asset.type]->save(asset.header, builder);
|
||||||
}
|
}
|
||||||
@ -351,7 +351,7 @@ namespace Components
|
|||||||
|
|
||||||
void AssetHandler::ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder)
|
void AssetHandler::ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder)
|
||||||
{
|
{
|
||||||
if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end())
|
if (AssetHandler::AssetInterfaces.contains(asset.type))
|
||||||
{
|
{
|
||||||
AssetHandler::AssetInterfaces[asset.type]->mark(asset.header, builder);
|
AssetHandler::AssetInterfaces[asset.type]->mark(asset.header, builder);
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@ namespace Components
|
|||||||
return { entry->second };
|
return { entry->second };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AssetHandler::AssetInterfaces.find(type) != AssetHandler::AssetInterfaces.end())
|
if (AssetHandler::AssetInterfaces.contains(type))
|
||||||
{
|
{
|
||||||
AssetHandler::AssetInterfaces[type]->load(&header, filename, builder);
|
AssetHandler::AssetInterfaces[type]->load(&header, filename, builder);
|
||||||
|
|
||||||
|
@ -243,7 +243,8 @@ namespace Assets
|
|||||||
{
|
{
|
||||||
Components::Logger::Print("No replacement found for material %s with techset %s\n", asset->info.name, asset->techniqueSet->name);
|
Components::Logger::Print("No replacement found for material %s with techset %s\n", asset->info.name, asset->techniqueSet->name);
|
||||||
std::string techName = asset->techniqueSet->name;
|
std::string techName = asset->techniqueSet->name;
|
||||||
if (techSetCorrespondance.find(techName) != techSetCorrespondance.end()) {
|
if (techSetCorrespondance.contains(techName))
|
||||||
|
{
|
||||||
auto iw4TechSetName = techSetCorrespondance[techName];
|
auto iw4TechSetName = techSetCorrespondance[techName];
|
||||||
Game::XAssetEntry* iw4TechSet = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, iw4TechSetName.data());
|
Game::XAssetEntry* iw4TechSet = Game::DB_FindXAssetEntry(Game::XAssetType::ASSET_TYPE_TECHNIQUE_SET, iw4TechSetName.data());
|
||||||
|
|
||||||
|
@ -311,10 +311,13 @@ namespace Components
|
|||||||
* Should be called when a client drops from the server
|
* Should be called when a client drops from the server
|
||||||
* but not "between levels" (Quake-III-Arena)
|
* but not "between levels" (Quake-III-Arena)
|
||||||
*/
|
*/
|
||||||
void Bots::ClientDisconnect_Hk(int clientNum)
|
void Bots::ClientDisconnect_Hk(const int clientNum)
|
||||||
{
|
{
|
||||||
g_botai[clientNum].active = false;
|
g_botai[clientNum].active = false;
|
||||||
|
|
||||||
|
// Clear the overrides for UserInfo
|
||||||
|
UserInfo::ClearClientOverrides(clientNum);
|
||||||
|
|
||||||
// Call original function
|
// Call original function
|
||||||
Utils::Hook::Call<void(int)>(0x4AA430)(clientNum);
|
Utils::Hook::Call<void(int)>(0x4AA430)(clientNum);
|
||||||
}
|
}
|
||||||
|
@ -173,8 +173,8 @@ namespace Components
|
|||||||
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).c_str(), playerTitle));
|
list.append(Utils::String::VA("\\%s\\%s", std::to_string(i).c_str(), playerTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data());
|
const auto* command = Utils::String::VA("%c customTitles \"%s\"", 21, list.data());
|
||||||
Game::SV_GameSendServerCommand(-1, 0, command.data());
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardTitles::ParseCustomTitles(const char* msg)
|
void CardTitles::ParseCustomTitles(const char* msg)
|
||||||
|
47
src/Components/Modules/Ceg.cpp
Normal file
47
src/Components/Modules/Ceg.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
Ceg::Ceg()
|
||||||
|
{
|
||||||
|
Utils::Hook::Signature signature(0x401000, 0x740000);
|
||||||
|
|
||||||
|
// Generic killer caller.
|
||||||
|
signature.add({
|
||||||
|
"\x56\x8B\x00\x24\x0c\x85\xF6\x7F\x0E", "xx?xxxxxx", [](char* address)
|
||||||
|
{
|
||||||
|
Utils::Hook::Set<BYTE>(address, 0xC3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
signature.process();
|
||||||
|
|
||||||
|
// Some more generic obfuscation (mov al, 1; retn)
|
||||||
|
Utils::Hook::Set<DWORD>(0x471B20, 0xC301B0);
|
||||||
|
Utils::Hook::Set<DWORD>(0x43A070, 0xC301B0);
|
||||||
|
Utils::Hook::Set<DWORD>(0x4C8B30, 0xC301B0);
|
||||||
|
Utils::Hook::Set<DWORD>(0x469340, 0xC301B0);
|
||||||
|
|
||||||
|
// Other checks
|
||||||
|
Utils::Hook::Set<DWORD>(0x401000, 0xC301B0);
|
||||||
|
Utils::Hook::Set<DWORD>(0x45F8B0, 0xC301B0);
|
||||||
|
Utils::Hook::Set<DWORD>(0x46FAE0, 0xC301B0);
|
||||||
|
|
||||||
|
// Removed in 159 SP binaries
|
||||||
|
Utils::Hook::Nop(0x46B173, 9);
|
||||||
|
Utils::Hook::Nop(0x43CA16, 9);
|
||||||
|
Utils::Hook::Nop(0x505426, 9);
|
||||||
|
|
||||||
|
// Something useless that can be skipped
|
||||||
|
Utils::Hook::Nop(0x4BB671, 2);
|
||||||
|
Utils::Hook::Nop(0x40A54D, 2);
|
||||||
|
|
||||||
|
// Random checks scattered throughout the binary
|
||||||
|
Utils::Hook::Set<BYTE>(0x499F90, 0xC3);
|
||||||
|
Utils::Hook::Set<BYTE>(0x4FC700, 0xC3);
|
||||||
|
Utils::Hook::Set<BYTE>(0x4C4170, 0xC3);
|
||||||
|
Utils::Hook::Set<BYTE>(0x49E8C0, 0xC3);
|
||||||
|
Utils::Hook::Set<BYTE>(0x42DB00, 0xC3);
|
||||||
|
Utils::Hook::Set<BYTE>(0x4F4CF0, 0xC3);
|
||||||
|
}
|
||||||
|
}
|
10
src/Components/Modules/Ceg.hpp
Normal file
10
src/Components/Modules/Ceg.hpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class Ceg : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ceg();
|
||||||
|
};
|
||||||
|
}
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
Game::dvar_t** Chat::cg_chatHeight = reinterpret_cast<Game::dvar_t**>(0x7ED398);
|
|
||||||
Dvar::Var Chat::cg_chatWidth;
|
Dvar::Var Chat::cg_chatWidth;
|
||||||
|
Dvar::Var Chat::sv_disableChat;
|
||||||
|
|
||||||
|
Game::dvar_t** Chat::cg_chatHeight = reinterpret_cast<Game::dvar_t**>(0x7ED398);
|
||||||
Game::dvar_t** Chat::cg_chatTime = reinterpret_cast<Game::dvar_t**>(0x9F5DE8);
|
Game::dvar_t** Chat::cg_chatTime = reinterpret_cast<Game::dvar_t**>(0x9F5DE8);
|
||||||
|
|
||||||
bool Chat::SendChat;
|
bool Chat::SendChat;
|
||||||
@ -23,11 +25,11 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(Chat::AccessMutex);
|
std::unique_lock<std::mutex> lock(Chat::AccessMutex);
|
||||||
if (Chat::MuteList.find(Game::svs_clients[player->s.number].steamID) != Chat::MuteList.end())
|
if (Chat::MuteList.contains(Game::svs_clients[player->s.number].steamID))
|
||||||
{
|
{
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
Chat::SendChat = false;
|
Chat::SendChat = false;
|
||||||
Game::SV_GameSendServerCommand(player->s.number, 0,
|
Game::SV_GameSendServerCommand(player->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
Utils::String::VA("%c \"You are muted\"", 0x65));
|
Utils::String::VA("%c \"You are muted\"", 0x65));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +39,13 @@ namespace Components
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Chat::sv_disableChat.get<bool>())
|
||||||
|
{
|
||||||
|
Chat::SendChat = false;
|
||||||
|
Game::SV_GameSendServerCommand(player->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
|
Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
||||||
|
}
|
||||||
|
|
||||||
TextRenderer::StripMaterialTextIcons(text, text, strlen(text) + 1);
|
TextRenderer::StripMaterialTextIcons(text, text, strlen(text) + 1);
|
||||||
|
|
||||||
Game::Scr_AddEntity(player);
|
Game::Scr_AddEntity(player);
|
||||||
@ -217,20 +226,20 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(Chat::AccessMutex);
|
std::unique_lock<std::mutex> lock(Chat::AccessMutex);
|
||||||
|
|
||||||
if (Chat::MuteList.find(client->steamID) == Chat::MuteList.end())
|
if (!Chat::MuteList.contains(client->steamID))
|
||||||
{
|
{
|
||||||
Chat::MuteList.insert(client->steamID);
|
Chat::MuteList.insert(client->steamID);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
Logger::Print("%s was muted\n", client->name);
|
Logger::Print("%s was muted\n", client->name);
|
||||||
Game::SV_GameSendServerCommand(client->gentity->s.number, 0,
|
Game::SV_GameSendServerCommand(client->gentity->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
Utils::String::VA("%c \"You were muted\"", 0x65));
|
Utils::String::VA("%c \"You were muted\"", 0x65));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
Logger::Print("%s is already muted\n", client->name);
|
Logger::Print("%s is already muted\n", client->name);
|
||||||
Game::SV_GameSendServerCommand(-1, 0,
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE,
|
||||||
Utils::String::VA("%c \"%s is already muted\"", 0x65, client->name));
|
Utils::String::VA("%c \"%s is already muted\"", 0x65, client->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +248,7 @@ namespace Components
|
|||||||
Chat::UnmuteInternal(client->steamID);
|
Chat::UnmuteInternal(client->steamID);
|
||||||
|
|
||||||
Logger::Print("%s was unmuted\n", client->name);
|
Logger::Print("%s was unmuted\n", client->name);
|
||||||
Game::SV_GameSendServerCommand(client->gentity->s.number, 0,
|
Game::SV_GameSendServerCommand(client->gentity->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
Utils::String::VA("%c \"You were unmuted\"", 0x65));
|
Utils::String::VA("%c \"You were unmuted\"", 0x65));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +326,11 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Dvar::OnInit([]
|
Dvar::OnInit([]
|
||||||
{
|
{
|
||||||
cg_chatWidth = Dvar::Register<int>("cg_chatWidth", 52, 1, std::numeric_limits<int>::max(), Game::DVAR_ARCHIVE, "The normalized maximum width of a chat message");
|
Chat::cg_chatWidth = Dvar::Register<int>("cg_chatWidth", 52, 1,
|
||||||
|
std::numeric_limits<int>::max(), Game::dvar_flag::DVAR_ARCHIVE, "The normalized maximum width of a chat message");
|
||||||
|
Chat::sv_disableChat = Dvar::Register<bool>("sv_disableChat", false,
|
||||||
|
Game::dvar_flag::DVAR_NONE, "Disable chat messages from clients");
|
||||||
|
|
||||||
Chat::AddChatCommands();
|
Chat::AddChatCommands();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,8 +9,11 @@ namespace Components
|
|||||||
Chat();
|
Chat();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Game::dvar_t** cg_chatHeight;
|
|
||||||
static Dvar::Var cg_chatWidth;
|
static Dvar::Var cg_chatWidth;
|
||||||
|
static Dvar::Var sv_disableChat;
|
||||||
|
|
||||||
|
// Game dvars
|
||||||
|
static Game::dvar_t** cg_chatHeight;
|
||||||
static Game::dvar_t** cg_chatTime;
|
static Game::dvar_t** cg_chatTime;
|
||||||
|
|
||||||
static bool SendChat;
|
static bool SendChat;
|
||||||
|
@ -32,7 +32,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string command = Utils::String::VA("%c clantags \"%s\"", 22, list.data());
|
std::string command = Utils::String::VA("%c clantags \"%s\"", 22, list.data());
|
||||||
Game::SV_GameSendServerCommand(-1, 0, command.data());
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, command.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ClanTags::GetUserClantag(std::uint32_t /*clientnum*/, const char* playername)
|
const char* ClanTags::GetUserClantag(std::uint32_t /*clientnum*/, const char* playername)
|
||||||
|
@ -11,14 +11,14 @@ namespace Components
|
|||||||
if (!Dvar::Var("sv_cheats").get<bool>())
|
if (!Dvar::Var("sv_cheats").get<bool>())
|
||||||
{
|
{
|
||||||
Logger::Print("CheatsOk: cheats are disabled!\n");
|
Logger::Print("CheatsOk: cheats are disabled!\n");
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65));
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->health < 1)
|
if (ent->health < 1)
|
||||||
{
|
{
|
||||||
Logger::Print("CheatsOk: entity %i must be alive to use this command!\n", entNum);
|
Logger::Print("CheatsOk: entity %i must be alive to use this command!\n", entNum);
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_MUSTBEALIVECOMMAND\"", 0x65));
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"GAME_MUSTBEALIVECOMMAND\"", 0x65));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace Components
|
|||||||
const auto entNum = ent->s.number;
|
const auto entNum = ent->s.number;
|
||||||
Logger::Print("Noclip toggled for entity %i\n", entNum);
|
Logger::Print("Noclip toggled for entity %i\n", entNum);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 0x65,
|
||||||
(ent->client->flags & Game::PLAYER_FLAG_NOCLIP) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
|
(ent->client->flags & Game::PLAYER_FLAG_NOCLIP) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ namespace Components
|
|||||||
const auto entNum = ent->s.number;
|
const auto entNum = ent->s.number;
|
||||||
Logger::Print("UFO toggled for entity %i\n", entNum);
|
Logger::Print("UFO toggled for entity %i\n", entNum);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 0x65,
|
||||||
(ent->client->flags & Game::PLAYER_FLAG_UFO) ? "GAME_UFOON" : "GAME_UFOOFF"));
|
(ent->client->flags & Game::PLAYER_FLAG_UFO) ? "GAME_UFOON" : "GAME_UFOOFF"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ namespace Components
|
|||||||
const auto entNum = ent->s.number;
|
const auto entNum = ent->s.number;
|
||||||
Logger::Print("God toggled for entity %i\n", entNum);
|
Logger::Print("God toggled for entity %i\n", entNum);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 0x65,
|
||||||
(ent->flags & Game::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF"));
|
(ent->flags & Game::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ namespace Components
|
|||||||
const auto entNum = ent->s.number;
|
const auto entNum = ent->s.number;
|
||||||
Logger::Print("Demigod toggled for entity %i\n", entNum);
|
Logger::Print("Demigod toggled for entity %i\n", entNum);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 0x65,
|
||||||
(ent->flags & Game::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF"));
|
(ent->flags & Game::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ namespace Components
|
|||||||
const auto entNum = ent->s.number;
|
const auto entNum = ent->s.number;
|
||||||
Logger::Print("Notarget toggled for entity %i\n", entNum);
|
Logger::Print("Notarget toggled for entity %i\n", entNum);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
Game::SV_GameSendServerCommand(entNum, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 0x65,
|
||||||
(ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"));
|
(ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ namespace Components
|
|||||||
|
|
||||||
if (params->size() < 4 || params->size() > 6)
|
if (params->size() < 4 || params->size() > 6)
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(ent->s.number, 0,
|
Game::SV_GameSendServerCommand(ent->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
Utils::String::VA("%c \"GAME_USAGE\x15: setviewpos x y z [yaw] [pitch]\n\"", 0x65));
|
Utils::String::VA("%c \"GAME_USAGE\x15: setviewpos x y z [yaw] [pitch]\n\"", 0x65));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ namespace Components
|
|||||||
strncpy_s(ent->client->visionName[visMode],
|
strncpy_s(ent->client->visionName[visMode],
|
||||||
sizeof(Game::gclient_t::visionName[0]) / sizeof(char), name, _TRUNCATE);
|
sizeof(Game::gclient_t::visionName[0]) / sizeof(char), name, _TRUNCATE);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(ent->s.number, 1,
|
Game::SV_GameSendServerCommand(ent->s.number, Game::SV_CMD_RELIABLE,
|
||||||
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ namespace Components
|
|||||||
strncpy_s(ent->client->visionName[visMode],
|
strncpy_s(ent->client->visionName[visMode],
|
||||||
sizeof(Game::gclient_t::visionName[0]) / sizeof(char), name, _TRUNCATE);
|
sizeof(Game::gclient_t::visionName[0]) / sizeof(char), name, _TRUNCATE);
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(ent->s.number, 1,
|
Game::SV_GameSendServerCommand(ent->s.number, Game::SV_CMD_RELIABLE,
|
||||||
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -245,6 +245,82 @@ namespace Components
|
|||||||
assert(ent != nullptr);
|
assert(ent != nullptr);
|
||||||
ent->client->ps.stunTime = 1000 + Game::level->time; // 1000 is the default test stun time
|
ent->client->ps.stunTime = 1000 + Game::level->time; // 1000 is the default test stun time
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ClientCommand::Add("give", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||||
|
{
|
||||||
|
if (!ClientCommand::CheatsOk(ent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (params->size() < 2)
|
||||||
|
{
|
||||||
|
Game::SV_GameSendServerCommand(ent->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||||
|
Utils::String::VA("%c \"GAME_USAGE\x15: give weapon\n\"", 0x65));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::level->initializing = 1;
|
||||||
|
const auto* weaponName = params->get(1);
|
||||||
|
const auto weaponIndex = Game::G_GetWeaponIndexForName(weaponName);
|
||||||
|
|
||||||
|
if (weaponIndex == 0)
|
||||||
|
{
|
||||||
|
Game::level->initializing = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game::BG_GetWeaponDef(weaponIndex)->inventoryType == Game::weapInventoryType_t::WEAPINVENTORY_ALTMODE)
|
||||||
|
{
|
||||||
|
Game::Com_PrintError(Game::CON_CHANNEL_ERROR,
|
||||||
|
"You can't directly spawn the altfire weapon '%s'. Spawn a weapon that has this altmode instead.\n", weaponName);
|
||||||
|
Game::level->initializing = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* weapEnt = Game::G_Spawn();
|
||||||
|
Utils::VectorCopy(weapEnt->r.currentOrigin, ent->r.currentOrigin);
|
||||||
|
Game::G_GetItemClassname(static_cast<int>(weaponIndex), weapEnt);
|
||||||
|
Game::G_SpawnItem(weapEnt, static_cast<int>(weaponIndex));
|
||||||
|
|
||||||
|
weapEnt->active = 1;
|
||||||
|
const auto offHandClass = Game::BG_GetWeaponDef(weaponIndex)->offhandClass;
|
||||||
|
if (offHandClass != Game::OFFHAND_CLASS_NONE)
|
||||||
|
{
|
||||||
|
auto* client = ent->client;
|
||||||
|
if ((client->ps.weapCommon.offhandPrimary != offHandClass) && (client->ps.weapCommon.offhandSecondary != offHandClass))
|
||||||
|
{
|
||||||
|
switch (offHandClass)
|
||||||
|
{
|
||||||
|
case Game::OFFHAND_CLASS_FRAG_GRENADE:
|
||||||
|
case Game::OFFHAND_CLASS_THROWINGKNIFE:
|
||||||
|
case Game::OFFHAND_CLASS_OTHER:
|
||||||
|
client->ps.weapCommon.offhandPrimary = offHandClass;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
client->ps.weapCommon.offhandSecondary = offHandClass;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::Touch_Item(weapEnt, ent, 0);
|
||||||
|
weapEnt->active = 0;
|
||||||
|
|
||||||
|
if (weapEnt->r.isInUse)
|
||||||
|
{
|
||||||
|
Game::G_FreeEntity(weapEnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::level->initializing = 0;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < std::extent_v<decltype(Game::playerState_s::weaponsEquipped)>; ++i)
|
||||||
|
{
|
||||||
|
const auto index = ent->client->ps.weaponsEquipped[i];
|
||||||
|
if (index != 0)
|
||||||
|
{
|
||||||
|
Game::Add_Ammo(ent, index, 0, 998, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientCommand::AddScriptFunctions()
|
void ClientCommand::AddScriptFunctions()
|
||||||
|
@ -64,7 +64,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
const auto command = Utils::String::ToLower(name);
|
const auto command = Utils::String::ToLower(name);
|
||||||
|
|
||||||
if (Command::FunctionMap.find(command) == Command::FunctionMap.end())
|
if (!Command::FunctionMap.contains(command))
|
||||||
{
|
{
|
||||||
Command::AddRaw(name, Command::MainCallback);
|
Command::AddRaw(name, Command::MainCallback);
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ namespace Components
|
|||||||
|
|
||||||
const auto command = Utils::String::ToLower(name);
|
const auto command = Utils::String::ToLower(name);
|
||||||
|
|
||||||
if (Command::FunctionMapSV.find(command) == Command::FunctionMapSV.end())
|
if (!Command::FunctionMapSV.contains(command))
|
||||||
{
|
{
|
||||||
Command::AddRawSV(name, Command::MainCallbackSV);
|
Command::AddRawSV(name, Command::MainCallbackSV);
|
||||||
|
|
||||||
@ -168,17 +168,4 @@ namespace Components
|
|||||||
got->second(¶ms);
|
got->second(¶ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Command::Command()
|
|
||||||
{
|
|
||||||
AssertSize(Game::cmd_function_t, 24);
|
|
||||||
|
|
||||||
Command::Add("openLink", [](Command::Params* params)
|
|
||||||
{
|
|
||||||
if (params->size() > 1)
|
|
||||||
{
|
|
||||||
Utils::OpenUrl(params->get(1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ namespace Components
|
|||||||
class Command : public Component
|
class Command : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static_assert(sizeof(Game::cmd_function_t) == 0x18);
|
||||||
|
|
||||||
class Params
|
class Params
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -45,7 +47,7 @@ namespace Components
|
|||||||
int nesting_;
|
int nesting_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Command();
|
Command() = default;
|
||||||
|
|
||||||
static Game::cmd_function_t* Allocate();
|
static Game::cmd_function_t* Allocate();
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::SV_GameSendServerCommand(-1, 0, list.data());
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, list.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dedicated::TimeWrapStub(Game::errorParm_t code, const char* message)
|
void Dedicated::TimeWrapStub(Game::errorParm_t code, const char* message)
|
||||||
@ -160,11 +160,9 @@ namespace Components
|
|||||||
Dedicated::Dedicated()
|
Dedicated::Dedicated()
|
||||||
{
|
{
|
||||||
// Map rotation
|
// Map rotation
|
||||||
Dvar::OnInit([]
|
|
||||||
{
|
Dedicated::COMLogFilter = Dvar::Register<bool>("com_logFilter", true,
|
||||||
Dedicated::COMLogFilter = Dvar::Register<bool>("com_logFilter", true,
|
Game::dvar_flag::DVAR_LATCH, "Removes ~95% of unneeded lines from the log");
|
||||||
Game::dvar_flag::DVAR_LATCH, "Removes ~95% of unneeded lines from the log");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())
|
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())
|
||||||
{
|
{
|
||||||
@ -287,12 +285,12 @@ namespace Components
|
|||||||
|
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
||||||
Game::Com_Printf(15, "%s: %s\n", name.data(), message.data());
|
Game::Com_Printf(15, "%s: %s\n", name.data(), message.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
|
||||||
Game::Com_Printf(15, "Console: %s\n", message.data());
|
Game::Com_Printf(15, "Console: %s\n", message.data());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -308,12 +306,12 @@ namespace Components
|
|||||||
|
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
Game::SV_GameSendServerCommand(client, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s: %s\"", 104, name.data(), message.data()));
|
||||||
Game::Com_Printf(15, "%s -> %i: %s\n", name.data(), client, message.data());
|
Game::Com_Printf(15, "%s -> %i: %s\n", name.data(), client, message.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
|
Game::SV_GameSendServerCommand(client, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Console: %s\"", 104, message.data()));
|
||||||
Game::Com_Printf(15, "Console -> %i: %s\n", client, message.data());
|
Game::Com_Printf(15, "Console -> %i: %s\n", client, message.data());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -324,7 +322,7 @@ namespace Components
|
|||||||
if (params->size() < 2) return;
|
if (params->size() < 2) return;
|
||||||
|
|
||||||
std::string message = params->join(1);
|
std::string message = params->join(1);
|
||||||
Game::SV_GameSendServerCommand(-1, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
|
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 104, message.data()));
|
||||||
Game::Com_Printf(15, "Raw: %s\n", message.data());
|
Game::Com_Printf(15, "Raw: %s\n", message.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -335,7 +333,7 @@ namespace Components
|
|||||||
|
|
||||||
int client = atoi(params->get(1));
|
int client = atoi(params->get(1));
|
||||||
std::string message = params->join(2);
|
std::string message = params->join(2);
|
||||||
Game::SV_GameSendServerCommand(client, 0, Utils::String::VA("%c \"%s\"", 104, message.data()));
|
Game::SV_GameSendServerCommand(client, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"%s\"", 104, message.data()));
|
||||||
Game::Com_Printf(15, "Raw -> %i: %s\n", client, message.data());
|
Game::Com_Printf(15, "Raw -> %i: %s\n", client, message.data());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -190,10 +190,10 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
|
std::lock_guard<std::recursive_mutex> _(Friends::Mutex);
|
||||||
|
|
||||||
const unsigned int modId = *reinterpret_cast<unsigned int*>("IW4x") | 0x80000000;
|
const auto modId = *reinterpret_cast<const unsigned int*>("IW4x") | 0x80000000;
|
||||||
|
|
||||||
// Split up the list
|
// Split up the list
|
||||||
for (auto entry : Friends::FriendsList)
|
for (const auto& entry : Friends::FriendsList)
|
||||||
{
|
{
|
||||||
Steam::FriendGameInfo info;
|
Steam::FriendGameInfo info;
|
||||||
if (Steam::Proxy::SteamFriends->GetFriendGamePlayed(entry.userId, &info) && info.m_gameID.modID == modId)
|
if (Steam::Proxy::SteamFriends->GetFriendGamePlayed(entry.userId, &info) && info.m_gameID.modID == modId)
|
||||||
|
@ -373,7 +373,7 @@ namespace Components
|
|||||||
if (!ps->weapIndex)
|
if (!ps->weapIndex)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto* weaponDef = Game::BG_GetWeaponDef(ps->weapIndex);
|
const auto* weaponDef = Game::BG_GetWeaponDef(static_cast<std::uint32_t>(ps->weapIndex));
|
||||||
|
|
||||||
return weaponDef->offhandClass != Game::OFFHAND_CLASS_NONE;
|
return weaponDef->offhandClass != Game::OFFHAND_CLASS_NONE;
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ namespace Components
|
|||||||
if (!AimAssist_IsLockonActive(input->localClientNum))
|
if (!AimAssist_IsLockonActive(input->localClientNum))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto* weaponDef = Game::BG_GetWeaponDef(aaGlob.ps.weapIndex);
|
const auto* weaponDef = Game::BG_GetWeaponDef(static_cast<std::uint32_t>(aaGlob.ps.weapIndex));
|
||||||
if (weaponDef->requireLockonToFire)
|
if (weaponDef->requireLockonToFire)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -532,7 +532,7 @@ namespace Components
|
|||||||
if (!ps->weapIndex)
|
if (!ps->weapIndex)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto* weaponDef = Game::BG_GetWeaponDef(ps->weapIndex);
|
const auto* weaponDef = Game::BG_GetWeaponDef(static_cast<std::uint32_t>(ps->weapIndex));
|
||||||
if (weaponDef->requireLockonToFire)
|
if (weaponDef->requireLockonToFire)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ namespace Components
|
|||||||
if (!AimAssist_IsSlowdownActive(&aaGlob.ps))
|
if (!AimAssist_IsSlowdownActive(&aaGlob.ps))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto* weaponDef = Game::BG_GetWeaponDef(aaGlob.ps.weapIndex);
|
const auto* weaponDef = Game::BG_GetWeaponDef(static_cast<std::uint32_t>(aaGlob.ps.weapIndex));
|
||||||
const auto aimAssistRange = AimAssist_Lerp(weaponDef->aimAssistRange, weaponDef->aimAssistRangeAds, aaGlob.adsLerp) * aim_aimAssistRangeScale.get<float>();
|
const auto aimAssistRange = AimAssist_Lerp(weaponDef->aimAssistRange, weaponDef->aimAssistRangeAds, aaGlob.adsLerp) * aim_aimAssistRangeScale.get<float>();
|
||||||
const auto screenTarget = AimAssist_GetBestTarget(&aaGlob, aimAssistRange, aaGlob.tweakables.slowdownRegionWidth, aaGlob.tweakables.slowdownRegionHeight);
|
const auto screenTarget = AimAssist_GetBestTarget(&aaGlob, aimAssistRange, aaGlob.tweakables.slowdownRegionWidth, aaGlob.tweakables.slowdownRegionHeight);
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ namespace Components
|
|||||||
|
|
||||||
if (bResult && cbBytes)
|
if (bResult && cbBytes)
|
||||||
{
|
{
|
||||||
if (pipe->packetCallbacks.find(pipe->packet.command) != pipe->packetCallbacks.end())
|
if (pipe->packetCallbacks.contains(pipe->packet.command))
|
||||||
{
|
{
|
||||||
pipe->packetCallbacks[pipe->packet.command](pipe->packet.buffer);
|
pipe->packetCallbacks[pipe->packet.command](pipe->packet.buffer);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace Components
|
|||||||
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
||||||
Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator();
|
Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator();
|
||||||
|
|
||||||
if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
|
if (Localization::LocalizeMap.contains(key))
|
||||||
{
|
{
|
||||||
Game::LocalizeEntry* entry = Localization::LocalizeMap[key];
|
Game::LocalizeEntry* entry = Localization::LocalizeMap[key];
|
||||||
|
|
||||||
@ -52,11 +52,11 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
||||||
|
|
||||||
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
|
if (Localization::TempLocalizeMap.contains(key))
|
||||||
{
|
{
|
||||||
entry = Localization::TempLocalizeMap[key];
|
entry = Localization::TempLocalizeMap[key];
|
||||||
}
|
}
|
||||||
else if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
|
else if (Localization::LocalizeMap.contains(key))
|
||||||
{
|
{
|
||||||
entry = Localization::LocalizeMap[key];
|
entry = Localization::LocalizeMap[key];
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ namespace Components
|
|||||||
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
||||||
Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator();
|
Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator();
|
||||||
|
|
||||||
if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end())
|
if (Localization::TempLocalizeMap.contains(key))
|
||||||
{
|
{
|
||||||
Game::LocalizeEntry* entry = Localization::TempLocalizeMap[key];
|
Game::LocalizeEntry* entry = Localization::TempLocalizeMap[key];
|
||||||
if (entry->value) allocator->free(entry->value);
|
if (entry->value) allocator->free(entry->value);
|
||||||
@ -256,11 +256,11 @@ namespace Components
|
|||||||
Game::XAssetHeader header = { nullptr };
|
Game::XAssetHeader header = { nullptr };
|
||||||
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
std::lock_guard<std::recursive_mutex> _(Localization::LocalizeMutex);
|
||||||
|
|
||||||
if (Localization::TempLocalizeMap.find(filename) != Localization::TempLocalizeMap.end())
|
if (Localization::TempLocalizeMap.contains(filename))
|
||||||
{
|
{
|
||||||
header.localize = Localization::TempLocalizeMap[filename];
|
header.localize = Localization::TempLocalizeMap[filename];
|
||||||
}
|
}
|
||||||
else if (Localization::LocalizeMap.find(filename) != Localization::LocalizeMap.end())
|
else if (Localization::LocalizeMap.contains(filename))
|
||||||
{
|
{
|
||||||
header.localize = Localization::LocalizeMap[filename];
|
header.localize = Localization::LocalizeMap[filename];
|
||||||
}
|
}
|
||||||
|
@ -920,7 +920,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::string name = gameWorld->dpvs.smodelDrawInsts[i].model->name;
|
std::string name = gameWorld->dpvs.smodelDrawInsts[i].model->name;
|
||||||
|
|
||||||
if (models.find(name) == models.end()) models[name] = 1;
|
if (!models.contains(name)) models[name] = 1;
|
||||||
else models[name]++;
|
else models[name]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ namespace Components
|
|||||||
Game::XSurface* tempSurfaces = allocator.allocateArray<Game::XSurface>(modelSurfs->numsurfs);
|
Game::XSurface* tempSurfaces = allocator.allocateArray<Game::XSurface>(modelSurfs->numsurfs);
|
||||||
char* surfaceData = reinterpret_cast<char*>(modelSurfs->surfs);
|
char* surfaceData = reinterpret_cast<char*>(modelSurfs->surfs);
|
||||||
|
|
||||||
if (ModelSurfs::AllocMap.find(modelSurfs->name) != ModelSurfs::AllocMap.end())
|
if (ModelSurfs::AllocMap.contains(modelSurfs->name))
|
||||||
{
|
{
|
||||||
Game::CModelAllocData* allocData = ModelSurfs::AllocMap[modelSurfs->name];
|
Game::CModelAllocData* allocData = ModelSurfs::AllocMap[modelSurfs->name];
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ namespace Components
|
|||||||
|
|
||||||
if (hasCustomSurface && !ModelSurfs::AllocMap.empty())
|
if (hasCustomSurface && !ModelSurfs::AllocMap.empty())
|
||||||
{
|
{
|
||||||
auto allocData = ModelSurfs::AllocMap.find(header.modelSurfs->name);
|
const auto allocData = ModelSurfs::AllocMap.find(header.modelSurfs->name);
|
||||||
if (allocData != ModelSurfs::AllocMap.end())
|
if (allocData != ModelSurfs::AllocMap.end())
|
||||||
{
|
{
|
||||||
Utils::Memory::FreeAlign(allocData->second->indexBuffer);
|
Utils::Memory::FreeAlign(allocData->second->indexBuffer);
|
||||||
|
@ -39,7 +39,7 @@ namespace Components
|
|||||||
|
|
||||||
const char* Party::GetLobbyInfo(SteamID lobby, const std::string& key)
|
const char* Party::GetLobbyInfo(SteamID lobby, const std::string& key)
|
||||||
{
|
{
|
||||||
if (Party::LobbyMap.find(lobby.bits) != Party::LobbyMap.end())
|
if (Party::LobbyMap.contains(lobby.bits))
|
||||||
{
|
{
|
||||||
Network::Address address = Party::LobbyMap[lobby.bits];
|
Network::Address address = Party::LobbyMap[lobby.bits];
|
||||||
|
|
||||||
@ -58,10 +58,7 @@ namespace Components
|
|||||||
|
|
||||||
void Party::RemoveLobby(SteamID lobby)
|
void Party::RemoveLobby(SteamID lobby)
|
||||||
{
|
{
|
||||||
if (Party::LobbyMap.find(lobby.bits) != Party::LobbyMap.end())
|
Party::LobbyMap.erase(lobby.bits);
|
||||||
{
|
|
||||||
Party::LobbyMap.erase(Party::LobbyMap.find(lobby.bits));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Party::ConnectError(const std::string& message)
|
void Party::ConnectError(const std::string& message)
|
||||||
|
@ -229,17 +229,18 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Game::dvar_t* QuickPatch::Dvar_RegisterConMinicon(const char* dvarName, [[maybe_unused]] bool value, unsigned __int16 flags, const char* description)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
constexpr auto value_ = true;
|
||||||
|
#else
|
||||||
|
constexpr auto value_ = false;
|
||||||
|
#endif
|
||||||
|
return Game::Dvar_RegisterBool(dvarName, value_, flags, description);
|
||||||
|
}
|
||||||
|
|
||||||
QuickPatch::QuickPatch()
|
QuickPatch::QuickPatch()
|
||||||
{
|
{
|
||||||
// quitHard
|
|
||||||
Command::Add("quitHard", [](Command::Params*)
|
|
||||||
{
|
|
||||||
int data = false;
|
|
||||||
const Utils::Library ntdll("ntdll.dll");
|
|
||||||
ntdll.invokePascal<void>("RtlAdjustPrivilege", 19, true, false, &data);
|
|
||||||
ntdll.invokePascal<void>("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, 6, &data);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Filtering any mapents that is intended for Spec:Ops gamemode (CODO) and prevent them from spawning
|
// Filtering any mapents that is intended for Spec:Ops gamemode (CODO) and prevent them from spawning
|
||||||
Utils::Hook(0x5FBD6E, QuickPatch::IsDynClassnameStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5FBD6E, QuickPatch::IsDynClassnameStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
@ -260,6 +261,8 @@ namespace Components
|
|||||||
Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick();
|
Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x5063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
Utils::Hook(0x4FA448, QuickPatch::Dvar_RegisterConMinicon, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Make sure preDestroy is called when the game shuts down
|
// Make sure preDestroy is called when the game shuts down
|
||||||
Scheduler::OnShutdown(Loader::PreDestroy);
|
Scheduler::OnShutdown(Loader::PreDestroy);
|
||||||
|
|
||||||
@ -714,17 +717,6 @@ namespace Components
|
|||||||
|
|
||||||
// Disable cheat protection for dvars
|
// Disable cheat protection for dvars
|
||||||
Utils::Hook::Set<BYTE>(0x647682, 0xEB);
|
Utils::Hook::Set<BYTE>(0x647682, 0xEB);
|
||||||
|
|
||||||
// Constantly draw the mini console
|
|
||||||
Utils::Hook::Set<BYTE>(0x412A45, 0xEB);
|
|
||||||
|
|
||||||
Scheduler::OnFrame([]()
|
|
||||||
{
|
|
||||||
if (*reinterpret_cast<Game::Font_s**>(0x62E4BAC))
|
|
||||||
{
|
|
||||||
Game::Con_DrawMiniConsole(0, 2, 4, (Game::CL_IsCgameInitialized() ? 1.0f : 0.4f));
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
#else
|
#else
|
||||||
// Remove missing tag message
|
// Remove missing tag message
|
||||||
Utils::Hook::Nop(0x4EBF1A, 5);
|
Utils::Hook::Nop(0x4EBF1A, 5);
|
||||||
|
@ -27,5 +27,7 @@ namespace Components
|
|||||||
|
|
||||||
static void CL_KeyEvent_OnEscape();
|
static void CL_KeyEvent_OnEscape();
|
||||||
static void CL_KeyEvent_ConsoleEscape_Stub();
|
static void CL_KeyEvent_ConsoleEscape_Stub();
|
||||||
|
|
||||||
|
static Game::dvar_t* Dvar_RegisterConMinicon(const char* dvarName, bool value, unsigned __int16 flags, const char* description);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::GetReplacedPos(const char* pos)
|
void Script::GetReplacedPos(const char* pos)
|
||||||
{
|
{
|
||||||
if (Script::ReplacedFunctions.find(pos) != Script::ReplacedFunctions.end())
|
if (Script::ReplacedFunctions.contains(pos))
|
||||||
{
|
{
|
||||||
Script::ReplacedPos = Script::ReplacedFunctions[pos];
|
Script::ReplacedPos = Script::ReplacedFunctions[pos];
|
||||||
}
|
}
|
||||||
@ -475,7 +475,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end())
|
if (Script::ReplacedFunctions.contains(what))
|
||||||
{
|
{
|
||||||
Logger::Print("Warning: ReplacedFunctions already contains codePosValue for a function\n");
|
Logger::Print("Warning: ReplacedFunctions already contains codePosValue for a function\n");
|
||||||
}
|
}
|
||||||
@ -667,7 +667,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::Scr_AddBool(static_cast<int>(Script::ScriptStorage.count(key))); // Until C++17
|
Game::Scr_AddInt(static_cast<int>(Script::ScriptStorage.count(key)));
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageClear", [] // gsc: StorageClear();
|
Script::AddFunction("StorageClear", [] // gsc: StorageClear();
|
||||||
|
@ -417,5 +417,8 @@ namespace Components
|
|||||||
Utils::Hook(0x41BED2, ScriptExtension::Scr_SetObjectFieldStub, HOOK_CALL).install()->quick(); // SetEntityFieldValue
|
Utils::Hook(0x41BED2, ScriptExtension::Scr_SetObjectFieldStub, HOOK_CALL).install()->quick(); // SetEntityFieldValue
|
||||||
Utils::Hook(0x5FBF01, ScriptExtension::Scr_SetClientFieldStub, HOOK_CALL).install()->quick(); // Scr_SetObjectField
|
Utils::Hook(0x5FBF01, ScriptExtension::Scr_SetClientFieldStub, HOOK_CALL).install()->quick(); // Scr_SetObjectField
|
||||||
Utils::Hook(0x4FF413, ScriptExtension::Scr_GetEntityFieldStub, HOOK_CALL).install()->quick(); // Scr_GetObjectField
|
Utils::Hook(0x4FF413, ScriptExtension::Scr_GetEntityFieldStub, HOOK_CALL).install()->quick(); // Scr_GetObjectField
|
||||||
|
|
||||||
|
// Fix format string in Scr_RandomFloatRange
|
||||||
|
Utils::Hook::Set<const char*>(0x5F10C6, "Scr_RandomFloatRange parms: %f %f ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ namespace Components
|
|||||||
|
|
||||||
std::string filename = Utils::String::ToLower(_filename);
|
std::string filename = Utils::String::ToLower(_filename);
|
||||||
|
|
||||||
if (StringTable::StringTableMap.find(filename) != StringTable::StringTableMap.end())
|
if (StringTable::StringTableMap.contains(filename))
|
||||||
{
|
{
|
||||||
header.stringTable = StringTable::StringTableMap[filename];
|
header.stringTable = StringTable::StringTableMap[filename];
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ namespace Components
|
|||||||
// No need to patch version 155
|
// No need to patch version 155
|
||||||
if (newData[i].version == 155) continue;
|
if (newData[i].version == 155) continue;
|
||||||
|
|
||||||
if (patchDefinitions.find(newData[i].version) != patchDefinitions.end())
|
if (patchDefinitions.contains(newData[i].version))
|
||||||
{
|
{
|
||||||
auto patchData = patchDefinitions[newData[i].version];
|
auto patchData = patchDefinitions[newData[i].version];
|
||||||
auto otherData = otherPatchDefinitions[newData[i].version];
|
auto otherData = otherPatchDefinitions[newData[i].version];
|
||||||
|
@ -12,7 +12,7 @@ namespace Components
|
|||||||
|
|
||||||
const char* UIFeeder::GetItemText()
|
const char* UIFeeder::GetItemText()
|
||||||
{
|
{
|
||||||
if (UIFeeder::Feeders.find(UIFeeder::Current.feeder) != UIFeeder::Feeders.end())
|
if (UIFeeder::Feeders.contains(UIFeeder::Current.feeder))
|
||||||
{
|
{
|
||||||
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemText(UIFeeder::Current.index, UIFeeder::Current.column);
|
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemText(UIFeeder::Current.index, UIFeeder::Current.column);
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ namespace Components
|
|||||||
|
|
||||||
unsigned int UIFeeder::GetItemCount()
|
unsigned int UIFeeder::GetItemCount()
|
||||||
{
|
{
|
||||||
if (UIFeeder::Feeders.find(UIFeeder::Current.feeder) != UIFeeder::Feeders.end())
|
if (UIFeeder::Feeders.contains(UIFeeder::Current.feeder))
|
||||||
{
|
{
|
||||||
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemCount();
|
return UIFeeder::Feeders[UIFeeder::Current.feeder].getItemCount();
|
||||||
}
|
}
|
||||||
@ -313,7 +313,7 @@ namespace Components
|
|||||||
|
|
||||||
void UIFeeder::ApplyMap(UIScript::Token)
|
void UIFeeder::ApplyMap(UIScript::Token)
|
||||||
{
|
{
|
||||||
std::string mapname = Dvar::Var("ui_map_name").get<std::string>();
|
const auto mapname = Dvar::Var("ui_map_name").get<std::string>();
|
||||||
|
|
||||||
Dvar::Var("ui_mapname").set(mapname);
|
Dvar::Var("ui_mapname").set(mapname);
|
||||||
Utils::Hook::Call<void(const char*)>(0x503B50)(mapname.data()); // Party_SetDisplayMapName
|
Utils::Hook::Call<void(const char*)>(0x503B50)(mapname.data()); // Party_SetDisplayMapName
|
||||||
@ -321,7 +321,7 @@ namespace Components
|
|||||||
|
|
||||||
void UIFeeder::ApplyInitialMap(UIScript::Token)
|
void UIFeeder::ApplyInitialMap(UIScript::Token)
|
||||||
{
|
{
|
||||||
std::string mapname = Dvar::Var("ui_mapname").get<std::string>();
|
const auto mapname = Dvar::Var("ui_mapname").get<std::string>();
|
||||||
|
|
||||||
Game::UI_UpdateArenas();
|
Game::UI_UpdateArenas();
|
||||||
Game::UI_SortArenas();
|
Game::UI_SortArenas();
|
||||||
|
@ -55,7 +55,7 @@ namespace Components
|
|||||||
|
|
||||||
bool UIScript::RunMenuScript(const char* name, const char** args)
|
bool UIScript::RunMenuScript(const char* name, const char** args)
|
||||||
{
|
{
|
||||||
if (UIScript::UIScripts.find(name) != UIScript::UIScripts.end())
|
if (UIScript::UIScripts.contains(name))
|
||||||
{
|
{
|
||||||
UIScript::UIScripts[name](UIScript::Token(args));
|
UIScript::UIScripts[name](UIScript::Token(args));
|
||||||
return true;
|
return true;
|
||||||
|
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();
|
||||||
|
|
||||||
|
static void ClearClientOverrides(int client);
|
||||||
|
static void ClearAllOverrides();
|
||||||
|
|
||||||
|
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 AddScriptMethods();
|
||||||
|
};
|
||||||
|
}
|
@ -530,7 +530,7 @@ namespace Components
|
|||||||
// Check if the given pointer has already been mapped
|
// Check if the given pointer has already been mapped
|
||||||
bool ZoneBuilder::Zone::hasPointer(const void* pointer)
|
bool ZoneBuilder::Zone::hasPointer(const void* pointer)
|
||||||
{
|
{
|
||||||
return (this->pointerMap.find(pointer) != this->pointerMap.end());
|
return this->pointerMap.contains(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get stored offset for given file pointer
|
// Get stored offset for given file pointer
|
||||||
@ -644,7 +644,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (type < Game::XAssetType::ASSET_TYPE_COUNT && type >= 0)
|
if (type < Game::XAssetType::ASSET_TYPE_COUNT && type >= 0)
|
||||||
{
|
{
|
||||||
if (this->renameMap[type].find(asset) != this->renameMap[type].end())
|
if (this->renameMap[type].contains(asset))
|
||||||
{
|
{
|
||||||
return this->renameMap[type][asset];
|
return this->renameMap[type][asset];
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace Main
|
|||||||
popad
|
popad
|
||||||
|
|
||||||
push 6BAA2Fh // Continue init routine
|
push 6BAA2Fh // Continue init routine
|
||||||
push 6CA062h // ___security_init_cookie
|
push 6CA062h // __security_init_cookie
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,6 +54,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
|
|||||||
|
|
||||||
Steam::Proxy::RunMod();
|
Steam::Proxy::RunMod();
|
||||||
|
|
||||||
|
#ifndef DISABLE_BINARY_CHECK
|
||||||
// Ensure we're working with our desired binary
|
// Ensure we're working with our desired binary
|
||||||
auto* _module = reinterpret_cast<char*>(0x400000);
|
auto* _module = reinterpret_cast<char*>(0x400000);
|
||||||
auto hash1 = Utils::Cryptography::JenkinsOneAtATime::Compute(_module + 0x1000, 0x2D531F); // .text
|
auto hash1 = Utils::Cryptography::JenkinsOneAtATime::Compute(_module + 0x1000, 0x2D531F); // .text
|
||||||
@ -69,6 +70,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
|
|||||||
|
|
||||||
DWORD oldProtect;
|
DWORD oldProtect;
|
||||||
VirtualProtect(_module + 0x1000, 0x2D6000, PAGE_EXECUTE_READ, &oldProtect); // Protect the .text segment
|
VirtualProtect(_module + 0x1000, 0x2D6000, PAGE_EXECUTE_READ, &oldProtect); // Protect the .text segment
|
||||||
|
#endif
|
||||||
|
|
||||||
// Install entry point hook
|
// Install entry point hook
|
||||||
Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
|
@ -68,6 +68,7 @@ namespace Game
|
|||||||
|
|
||||||
Com_Error_t Com_Error = Com_Error_t(0x4B22D0);
|
Com_Error_t Com_Error = Com_Error_t(0x4B22D0);
|
||||||
Com_Printf_t Com_Printf = Com_Printf_t(0x402500);
|
Com_Printf_t Com_Printf = Com_Printf_t(0x402500);
|
||||||
|
Com_PrintError_t Com_PrintError = Com_PrintError_t(0x4F8C70);
|
||||||
Com_PrintMessage_t Com_PrintMessage = Com_PrintMessage_t(0x4AA830);
|
Com_PrintMessage_t Com_PrintMessage = Com_PrintMessage_t(0x4AA830);
|
||||||
Com_EndParseSession_t Com_EndParseSession = Com_EndParseSession_t(0x4B80B0);
|
Com_EndParseSession_t Com_EndParseSession = Com_EndParseSession_t(0x4B80B0);
|
||||||
Com_BeginParseSession_t Com_BeginParseSession = Com_BeginParseSession_t(0x4AAB80);
|
Com_BeginParseSession_t Com_BeginParseSession = Com_BeginParseSession_t(0x4AAB80);
|
||||||
@ -156,6 +157,10 @@ namespace Game
|
|||||||
G_LogPrintf_t G_LogPrintf = G_LogPrintf_t(0x4B0150);
|
G_LogPrintf_t G_LogPrintf = G_LogPrintf_t(0x4B0150);
|
||||||
G_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540);
|
G_GetWeaponIndexForName_t G_GetWeaponIndexForName = G_GetWeaponIndexForName_t(0x49E540);
|
||||||
G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840);
|
G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString = G_SpawnEntitiesFromString_t(0x4D8840);
|
||||||
|
G_Spawn_t G_Spawn = G_Spawn_t(0x4226F0);
|
||||||
|
G_FreeEntity_t G_FreeEntity = G_FreeEntity_t(0x44C9D0);
|
||||||
|
G_SpawnItem_t G_SpawnItem = G_SpawnItem_t(0x403770);
|
||||||
|
G_GetItemClassname_t G_GetItemClassname = G_GetItemClassname_t(0x492630);
|
||||||
G_PrintEntities_t G_PrintEntities = G_PrintEntities_t(0x4E6A50);
|
G_PrintEntities_t G_PrintEntities = G_PrintEntities_t(0x4E6A50);
|
||||||
G_GetEntityTypeName_t G_GetEntityTypeName = G_GetEntityTypeName_t(0x4EB810);
|
G_GetEntityTypeName_t G_GetEntityTypeName = G_GetEntityTypeName_t(0x4EB810);
|
||||||
|
|
||||||
@ -431,6 +436,12 @@ 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);
|
||||||
|
|
||||||
|
Touch_Item_t Touch_Item = Touch_Item_t(0x44FA20);
|
||||||
|
|
||||||
|
Add_Ammo_t Add_Ammo = Add_Ammo_t(0x4E1480);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace Game
|
|||||||
typedef void*(__cdecl * BG_LoadWeaponDef_LoadObj_t)(const char* filename);
|
typedef void*(__cdecl * BG_LoadWeaponDef_LoadObj_t)(const char* filename);
|
||||||
extern BG_LoadWeaponDef_LoadObj_t BG_LoadWeaponDef_LoadObj;
|
extern BG_LoadWeaponDef_LoadObj_t BG_LoadWeaponDef_LoadObj;
|
||||||
|
|
||||||
typedef WeaponDef* (__cdecl * BG_GetWeaponDef_t)(int weaponIndex);
|
typedef WeaponDef*(__cdecl * BG_GetWeaponDef_t)(unsigned int weaponIndex);
|
||||||
extern BG_GetWeaponDef_t BG_GetWeaponDef;
|
extern BG_GetWeaponDef_t BG_GetWeaponDef;
|
||||||
|
|
||||||
typedef const char*(__cdecl * BG_GetEntityTypeName_t)(const int eType);
|
typedef const char*(__cdecl * BG_GetEntityTypeName_t)(const int eType);
|
||||||
@ -139,6 +139,9 @@ namespace Game
|
|||||||
typedef void(__cdecl * Com_Printf_t)(int channel, const char *fmt, ...);
|
typedef void(__cdecl * Com_Printf_t)(int channel, const char *fmt, ...);
|
||||||
extern Com_Printf_t Com_Printf;
|
extern Com_Printf_t Com_Printf;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Com_PrintError_t)(int channel, const char* fmt, ...);
|
||||||
|
extern Com_PrintError_t Com_PrintError;
|
||||||
|
|
||||||
typedef void(__cdecl * Com_PrintMessage_t)(int channel, const char *msg, int error);
|
typedef void(__cdecl * Com_PrintMessage_t)(int channel, const char *msg, int error);
|
||||||
extern Com_PrintMessage_t Com_PrintMessage;
|
extern Com_PrintMessage_t Com_PrintMessage;
|
||||||
|
|
||||||
@ -389,6 +392,18 @@ namespace Game
|
|||||||
typedef void(__cdecl * G_SpawnEntitiesFromString_t)();
|
typedef void(__cdecl * G_SpawnEntitiesFromString_t)();
|
||||||
extern G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString;
|
extern G_SpawnEntitiesFromString_t G_SpawnEntitiesFromString;
|
||||||
|
|
||||||
|
typedef gentity_s*(__cdecl * G_Spawn_t)();
|
||||||
|
extern G_Spawn_t G_Spawn;
|
||||||
|
|
||||||
|
typedef void(__cdecl * G_FreeEntity_t)(gentity_s* ed);
|
||||||
|
extern G_FreeEntity_t G_FreeEntity;
|
||||||
|
|
||||||
|
typedef void(__cdecl * G_SpawnItem_t)(gentity_s* ent, int item);
|
||||||
|
extern G_SpawnItem_t G_SpawnItem;
|
||||||
|
|
||||||
|
typedef void(__cdecl * G_GetItemClassname_t)(int item, gentity_s* ent);
|
||||||
|
extern G_GetItemClassname_t G_GetItemClassname;
|
||||||
|
|
||||||
typedef void(__cdecl * G_PrintEntities_t)();
|
typedef void(__cdecl * G_PrintEntities_t)();
|
||||||
extern G_PrintEntities_t G_PrintEntities;
|
extern G_PrintEntities_t G_PrintEntities;
|
||||||
|
|
||||||
@ -834,7 +849,7 @@ namespace Game
|
|||||||
typedef int(__cdecl* SV_GameClientNum_Score_t)(int clientID);
|
typedef int(__cdecl* SV_GameClientNum_Score_t)(int clientID);
|
||||||
extern SV_GameClientNum_Score_t SV_GameClientNum_Score;
|
extern SV_GameClientNum_Score_t SV_GameClientNum_Score;
|
||||||
|
|
||||||
typedef void(__cdecl * SV_GameSendServerCommand_t)(int clientNum, /*svscmd_type*/int type, const char* text);
|
typedef void(__cdecl * SV_GameSendServerCommand_t)(int clientNum, svscmd_type type, const char* text);
|
||||||
extern SV_GameSendServerCommand_t SV_GameSendServerCommand;
|
extern SV_GameSendServerCommand_t SV_GameSendServerCommand;
|
||||||
|
|
||||||
typedef void(__cdecl * SV_Cmd_TokenizeString_t)(const char* string);
|
typedef void(__cdecl * SV_Cmd_TokenizeString_t)(const char* string);
|
||||||
@ -1029,6 +1044,15 @@ 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 * Touch_Item_t)(gentity_s* ent, gentity_s* other, int touched);
|
||||||
|
extern Touch_Item_t Touch_Item;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Add_Ammo_t)(gentity_s* ent, unsigned int weaponIndex, unsigned char weaponModel, int count, int fillClip);
|
||||||
|
extern Add_Ammo_t Add_Ammo;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -343,6 +343,12 @@ namespace Game
|
|||||||
HITLOC_NUM
|
HITLOC_NUM
|
||||||
} hitLocation_t;
|
} hitLocation_t;
|
||||||
|
|
||||||
|
enum svscmd_type
|
||||||
|
{
|
||||||
|
SV_CMD_CAN_IGNORE = 0x0,
|
||||||
|
SV_CMD_RELIABLE = 0x1,
|
||||||
|
};
|
||||||
|
|
||||||
struct FxEffectDef;
|
struct FxEffectDef;
|
||||||
struct pathnode_t;
|
struct pathnode_t;
|
||||||
struct pathnode_tree_t;
|
struct pathnode_tree_t;
|
||||||
@ -1621,7 +1627,6 @@ namespace Game
|
|||||||
int groundEntityNum;
|
int groundEntityNum;
|
||||||
int loopSound;
|
int loopSound;
|
||||||
int surfType;
|
int surfType;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
int brushModel;
|
int brushModel;
|
||||||
@ -1630,7 +1635,6 @@ namespace Game
|
|||||||
int xmodel;
|
int xmodel;
|
||||||
int primaryLight;
|
int primaryLight;
|
||||||
} index;
|
} index;
|
||||||
|
|
||||||
int clientNum;
|
int clientNum;
|
||||||
int iHeadIcon;
|
int iHeadIcon;
|
||||||
int iHeadIconTeam;
|
int iHeadIconTeam;
|
||||||
@ -1649,7 +1653,16 @@ namespace Game
|
|||||||
int fxId;
|
int fxId;
|
||||||
int helicopterStage;
|
int helicopterStage;
|
||||||
} un1;
|
} un1;
|
||||||
int un2;
|
union
|
||||||
|
{
|
||||||
|
int hintType;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned __int16 vehicleXModel;
|
||||||
|
char weaponModel;
|
||||||
|
} __s1;
|
||||||
|
int actorFlags;
|
||||||
|
} un2;
|
||||||
clientLinkInfo_t clientLinkInfo;
|
clientLinkInfo_t clientLinkInfo;
|
||||||
unsigned int partBits[6];
|
unsigned int partBits[6];
|
||||||
int clientMask[1];
|
int clientMask[1];
|
||||||
|
@ -36,7 +36,7 @@ namespace Steam
|
|||||||
|
|
||||||
std::pair<void*, uint16_t> Interface::getMethod(const std::string& method)
|
std::pair<void*, uint16_t> Interface::getMethod(const std::string& method)
|
||||||
{
|
{
|
||||||
if(this->methodCache.find(method) != this->methodCache.end())
|
if(this->methodCache.contains(method))
|
||||||
{
|
{
|
||||||
return this->methodCache[method];
|
return this->methodCache[method];
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ namespace Steam
|
|||||||
|
|
||||||
for (auto result : results)
|
for (auto result : results)
|
||||||
{
|
{
|
||||||
if (Callbacks::ResultHandlers.find(result.call) != Callbacks::ResultHandlers.end())
|
if (Callbacks::ResultHandlers.contains(result.call))
|
||||||
{
|
{
|
||||||
Callbacks::ResultHandlers[result.call]->Run(result.data, false, result.call);
|
Callbacks::ResultHandlers[result.call]->Run(result.data, false, result.call);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ namespace Utils
|
|||||||
{
|
{
|
||||||
for (auto& entity : this->entities)
|
for (auto& entity : this->entities)
|
||||||
{
|
{
|
||||||
if (entity.find("classname") != entity.end())
|
if (entity.contains("classname"))
|
||||||
{
|
{
|
||||||
if (entity["classname"] == "misc_turret"s)
|
if (entity["classname"] == "misc_turret"s)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hook::Signature::add(Hook::Signature::Container& container)
|
void Hook::Signature::add(const Hook::Signature::Container& container)
|
||||||
{
|
{
|
||||||
Hook::Signature::signatures.push_back(container);
|
Hook::Signature::signatures.push_back(container);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace Utils
|
|||||||
Signature() : Signature(0x400000, 0x800000) {}
|
Signature() : Signature(0x400000, 0x800000) {}
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
void add(Container& container);
|
void add(const Container& container);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* start;
|
void* start;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ namespace Utils
|
|||||||
|
|
||||||
bool isPointerMapped(void* ptr)
|
bool isPointerMapped(void* ptr)
|
||||||
{
|
{
|
||||||
return this->ptrMap.find(ptr) != this->ptrMap.end();
|
return this->ptrMap.contains(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> T* getPointer(void* oldPtr)
|
template <typename T> T* getPointer(void* oldPtr)
|
||||||
|
@ -127,4 +127,7 @@ namespace Utils
|
|||||||
mutable std::recursive_mutex mutex;
|
mutable std::recursive_mutex mutex;
|
||||||
std::vector<Slot<T>> slots;
|
std::vector<Slot<T>> slots;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto VectorCopy(T a, T b) { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
|
||||||
}
|
}
|
||||||
|
BIN
tools/protoc.exe
BIN
tools/protoc.exe
Binary file not shown.
Loading…
Reference in New Issue
Block a user