Files

409 lines
15 KiB
C++
Raw Permalink Normal View History

2023-10-01 02:28:13 +08:00
#include "hooks.h"
2023-10-04 06:01:28 +08:00
extern auto GetGameGlobals() -> CGlobalVars*;
2023-10-06 05:08:40 +08:00
namespace hooks {
// "player_connect"
VMTHook* VMT_IServerGameClient;
VMTHook* VMT_INetworkServerServiceInteFace;
VMTHook* VMT_ISource2ServerInterFace;
2023-10-20 20:19:22 +08:00
VMTHook* VMT_GameEventSystem;
2023-10-01 02:28:13 +08:00
FireEventServerSide_t original_FireEventServerSide = NULL;
OnClientConnect_t original_OnClientConnected = NULL;
OnClientDisconnect_t original_OnClientDisconnect = NULL;
2023-10-01 02:28:13 +08:00
Host_Say_t original_Host_Say = NULL;
2023-10-04 06:01:28 +08:00
StartupServer_t origin_StartServer = NULL;
GameFrame_t origin_GameFrame = NULL;
2023-10-08 02:29:04 +08:00
CCSWeaponBase_Spawn_t origin_CCSWeaponBase_Spawn = NULL;
UTIL_SayText2Filter_t origin_UTIL_SayText2Filter = NULL;
2023-10-20 20:19:22 +08:00
PostEventAbstract_t origin_PostEventAbstract = NULL;
2023-10-21 04:24:28 +08:00
2023-10-20 20:19:22 +08:00
void __fastcall hook_PostEventAbstract(
void* rcx,
CSplitScreenSlot nSlot,
bool bLocalOnly,
int nClientCount,
const uint64* clients,
INetworkSerializable* pEvent,
const void* pData,
unsigned long nSize,
NetChannelBufType_t bufType)
{
2023-10-21 04:24:28 +08:00
do
{
if (global::EntitySystem == nullptr) {
break;
}
if (pEvent == nullptr) {
break;
}
2023-10-20 20:19:22 +08:00
NetMessageInfo_t* info = pEvent->GetNetMessageInfo();
2023-10-21 04:24:28 +08:00
if (info == nullptr) {
break;
}
const auto isBloodAboutMessage = (info->m_MessageId == TE_WorldDecalId || info->m_MessageId == TE_EffectDispatchId);
if (isBloodAboutMessage == false/* && isWeaponAboutMessage == false */) {
break;
}
2023-10-21 16:40:37 +08:00
// lazy fix me
for (uint64_t i = 0; i < global::MaxPlayers; i++)
2023-10-21 04:24:28 +08:00
{
2023-10-21 16:40:37 +08:00
if (!(*(uint64_t*)clients & ((uint64_t)1 << i))) {
2023-10-21 04:24:28 +08:00
continue;
}
2023-10-21 16:40:37 +08:00
const auto pEntity = global::EntitySystem->GetBaseEntity(PlayerSlot_to_EntityIndex(i));
2023-10-21 04:24:28 +08:00
if (pEntity == nullptr) {
continue;
}
if (pEntity->IsBasePlayerController() == false) {
continue;
}
const auto player = reinterpret_cast<CCSPlayerController*>(pEntity);
const auto [isSuccess, playerSetting] = ExtendPlayerManager::GetPlayerSettingBySteamId(player->m_steamID());
if (isSuccess == false) {
continue;
}
bool skipTheEvent = false;
if (isBloodAboutMessage) {
skipTheEvent = (playerSetting.bloodSetting == _ExtendPlayerSetting_Blood::kDisableBloodEffectDispatch && info->m_MessageId == TE_EffectDispatchId) ||
(playerSetting.bloodSetting == _ExtendPlayerSetting_Blood::kDisableBloodWorldDecal && info->m_MessageId == TE_WorldDecalId) ||
(playerSetting.bloodSetting == _ExtendPlayerSetting_Blood::kDisableBloodWorldDecalAndEffectDispatch);
}
/*
else if (isWeaponAboutMessage)
2023-10-20 20:19:22 +08:00
{
2023-10-21 04:24:28 +08:00
skipTheEvent = (playerSetting.weaponSetting == _ExtendPlayerSetting_Weapon::kDisablebulletHole);
}
*/
if (skipTheEvent) {
*(uint64*)clients &= ~((uint64)1 << i);
nClientCount--;
2023-10-20 20:19:22 +08:00
}
}
2023-10-21 04:24:28 +08:00
} while (false);
origin_PostEventAbstract(rcx, nSlot, bLocalOnly, nClientCount, clients, pEvent, pData, nSize, bufType);
2023-10-20 20:19:22 +08:00
}
void __fastcall hook_UTIL_SayText2Filter(
IRecipientFilter& filter, CCSPlayerController* pEntity,
uint64_t eMessageType, const char* messeageName, const char* param1,
const char* param2, const char* param3, const char* param4) {
const auto entIndex =
PlayerSlot_to_EntityIndex(filter.GetRecipientIndex(0).Get());
const auto isHandle = ScriptCallBacks::luCall_onSayText2Filter(
entIndex, eMessageType, messeageName, param1, param2, param3, param4);
if (isHandle == false) {
origin_UTIL_SayText2Filter(filter, pEntity, eMessageType, messeageName,
param1, param2, param3, param4);
}
}
// https://github.com/Source2ZE/CS2Fixes/blob/main/src/commands.cpp#L494
2023-10-08 02:29:04 +08:00
void __fastcall hook_CCSWeaponBase_Spawn(CBaseEntity* pThis, void* a2) {
const char* pszClassName = pThis->m_pEntity()->m_designerName;
origin_CCSWeaponBase_Spawn(pThis, a2);
2023-10-08 05:28:41 +08:00
if (pszClassName == nullptr) {
return;
}
LOG("Weapon spawn: %s\n", pszClassName);
2023-10-08 02:29:04 +08:00
do {
auto pWeapon = reinterpret_cast<CCSWeaponBase*>(pThis);
// Weapon could be already initialized with the correct data from
// GiveNamedItem, in that case we don't need to do anything
if (!pWeapon ||
pWeapon->m_AttributeManager()->m_Item()->m_bInitialized()) {
break;
}
const auto weaponName = Tools::toLower(std::string(pszClassName));
auto lookupWeaponSimpleName = std::string();
for (const auto& weapon : GameWeapons::WeaponMap) {
const auto& key = weapon.first;
const auto& [fullWeaponName, weaponItemDefIndex] = weapon.second;
2023-10-19 03:16:12 +08:00
if (fullWeaponName.find(weaponName) == std::string::npos) {
continue;
}
lookupWeaponSimpleName = key;
break;
}
if (lookupWeaponSimpleName.size() <= 1) {
2023-10-08 02:29:04 +08:00
break;
}
// lazy , fix me
2023-10-08 02:29:04 +08:00
const auto [fullWeaponName, weaponiItemDefIndex] =
GameWeapons::WeaponMap.at(lookupWeaponSimpleName);
2023-10-08 02:29:04 +08:00
2023-10-19 03:16:12 +08:00
LOG("Fixing a %s with index = %d and initialized = %d\n",
fullWeaponName.c_str(),
2023-10-08 02:29:04 +08:00
pWeapon->m_AttributeManager()->m_Item()->m_iItemDefinitionIndex(),
pWeapon->m_AttributeManager()->m_Item()->m_bInitialized());
pWeapon->m_AttributeManager()->m_Item()->m_bInitialized(true);
pWeapon->m_AttributeManager()->m_Item()->m_iItemDefinitionIndex(
weaponiItemDefIndex);
} while (false);
}
2023-10-04 06:01:28 +08:00
void __fastcall hook_GameFrame(void* rcx, bool simulating, bool bFirstTick,
bool bLastTick) {
/**
* simulating:
* ***********
* true | game is ticking
* false | game is not ticking
*/
2023-10-10 20:10:42 +08:00
if (global::GlobalVars != nullptr) {
if (simulating && global::HasTicked) {
global::m_flUniversalTime +=
global::GlobalVars->curtime - global::m_flLastTickedTime;
} else {
2023-10-10 20:10:42 +08:00
global::m_flUniversalTime += global::GlobalVars->interval_per_tick;
}
2023-10-04 06:01:28 +08:00
2023-10-10 20:10:42 +08:00
global::m_flLastTickedTime = global::GlobalVars->curtime;
global::HasTicked = true;
2023-10-04 06:01:28 +08:00
2023-10-10 20:10:42 +08:00
GameTimer::ExcuteTimers();
GameTickRunTime::ExcuteTickFunctions();
}
if (global::EntitySystem == nullptr) {
global::EntitySystem = CGameEntitySystem::GetInstance();
}
2023-10-20 20:19:22 +08:00
if (global::GlobalVars == nullptr) {
global::GlobalVars = GetGameGlobals();
}
2023-10-04 06:01:28 +08:00
return origin_GameFrame(rcx, simulating, bFirstTick, bLastTick);
}
void __fastcall hook_StartServer(void* rcx,
const GameSessionConfiguration_t& config,
ISource2WorldSession* pWorldSession,
const char* a1) {
if (global::HasTicked) {
GameTimer::CleanUpTimers();
}
global::HasTicked = false;
global::GlobalVars = GetGameGlobals();
global::EntitySystem =
Offset::InterFaces::GameResourceServiceServer->GetGameEntitySystem();
return origin_StartServer(rcx, config, pWorldSession, a1);
}
void __fastcall hook_ClientDisconnect(void* rcx, CPlayerSlot slot, int reason,
const char* pszName, uint64_t xuid,
const char* pszNetworkID) {
2023-10-03 00:25:23 +08:00
bool isFakePlayer = true;
2023-10-02 05:03:37 +08:00
if (pszNetworkID != NULL && *pszNetworkID == '[') {
ExtendPlayerManager::RemovePlayerSlotBySteamId(
ExtendPlayerManager::SteamIDStringToUInt64(pszNetworkID));
2023-10-03 00:25:23 +08:00
isFakePlayer = false;
2023-10-02 05:03:37 +08:00
}
2023-10-03 00:25:23 +08:00
events::OnPlayerDisconnect(slot.Get(), pszName, xuid, pszNetworkID,
pszNetworkID, isFakePlayer);
return original_OnClientDisconnect(rcx, slot, reason, pszName, xuid,
pszNetworkID);
}
void __fastcall hook_OnClientConnected(void* rcx, CPlayerSlot slot,
const char* pszName, uint64_t xuid,
const char* pszNetworkID,
const char* pszAddress,
bool bFakePlayer) {
if (bFakePlayer == false) {
2023-10-02 05:03:37 +08:00
ExtendPlayerManager::AddSteamIdToPlayerSteamIdWithNameTable(
ExtendPlayerManager::SteamIDStringToUInt64(pszNetworkID),
slot.Get());
2023-10-01 02:28:13 +08:00
}
2023-10-03 00:25:23 +08:00
events::OnPlayerConnect(slot.Get(), pszName, xuid, pszNetworkID, pszAddress,
bFakePlayer);
return original_OnClientConnected(rcx, slot, pszName, xuid, pszNetworkID,
pszAddress, bFakePlayer);
}
void __fastcall hook_Host_Say(void* pEntity, void* args, bool teamonly,
int unk1, const char* unk2) {
const auto theArgs = reinterpret_cast<CCommand*>(args);
const auto theEntity = reinterpret_cast<CCSPlayerController*>(pEntity);
2023-10-01 02:28:13 +08:00
char* pos = nullptr;
2023-10-02 17:31:02 +08:00
bool blockMsg = false;
do {
2023-10-19 03:16:12 +08:00
if (theArgs == nullptr) {
break;
2023-10-03 00:25:23 +08:00
}
2023-10-02 17:31:02 +08:00
const auto message = std::string(theArgs->GetCommandString());
2023-10-19 03:16:12 +08:00
if (theEntity == nullptr) {
if (events::OnConsoleChat(message) == true) {
blockMsg = true;
break;
}
break;
}
2023-10-02 17:31:02 +08:00
if (events::OnPlayerChat(theEntity, message) == true) {
blockMsg = true;
break;
}
} while (false);
/*
if (*pMessage == '!' || *pMessage == '/')
ParseChatCommand(pMessage, pEntity);
2023-10-01 02:28:13 +08:00
if (*pMessage == '/')
return;
*/
2023-10-03 00:25:23 +08:00
if (blockMsg) {
return;
} else {
2023-10-02 17:31:02 +08:00
return original_Host_Say(pEntity, args, teamonly, unk1, unk2);
}
}
bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
IGameEvent* event, bool serverSide) {
do {
if (!event) {
break;
}
const char* eventName = event->GetName();
if (!eventName) {
break;
}
static constexpr auto player_death =
hash_32_fnv1a_const("player_death");
static constexpr auto player_chat = hash_32_fnv1a_const("player_chat");
2023-10-06 05:08:40 +08:00
static constexpr auto player_spawn =
hash_32_fnv1a_const("player_spawn");
2023-10-08 01:56:49 +08:00
static constexpr auto round_start = hash_32_fnv1a_const("round_start");
static constexpr auto round_end = hash_32_fnv1a_const("round_end");
2023-10-08 05:28:41 +08:00
static constexpr auto player_hurt = hash_32_fnv1a_const("player_hurt");
static constexpr auto player_team = hash_32_fnv1a_const("player_team");
2023-10-03 00:25:23 +08:00
switch (hash_32_fnv1a_const(eventName)) {
2023-10-01 02:28:13 +08:00
case player_death:
events::OnPlayerDeathEvent(event);
break;
2023-10-06 05:08:40 +08:00
case player_spawn:
events::OnPlayerSpawnEvent(event);
break;
2023-10-08 01:56:49 +08:00
case round_start:
events::OnRoundStartEvent(event);
break;
case round_end:
events::OnRoundEndEvent(event);
break;
2023-10-08 05:28:41 +08:00
case player_hurt:
events::OnPlayerHurtEvent(event);
break;
case player_team:
events::OnPlayerTeamChangeEevent(event);
break;
// V<><56>bug,<2C><EFBFBD><E2B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2023-10-01 02:28:13 +08:00
/*
case player_chat:
events::OnPlayerChat(event);
break;
}
*/
}
2023-10-01 02:28:13 +08:00
} while (false);
return original_FireEventServerSide(rcx, event, serverSide);
}
auto initMinHook() -> bool {
bool isSuccess = false;
// <20><>ʼ<EFBFBD><CABC>MiniHook
do {
if (MH_Initialize() != MH_OK) {
LOG("MH_Initialize() != MH_OK\n");
break;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (MH_CreateHook((LPVOID)Offset::FireEventServerSidePtr,
&hook_FireEventServerSide,
reinterpret_cast<LPVOID*>(
&original_FireEventServerSide)) != MH_OK) {
LOG("MH_CreateHook original_FireEventServerSide\n");
break;
}
if (MH_CreateHook((LPVOID)Offset::Host_SayPtr, &hook_Host_Say,
reinterpret_cast<LPVOID*>(&original_Host_Say)) !=
MH_OK) {
LOG("MH_CreateHook original_Host_Say\n");
break;
}
2023-10-08 02:29:04 +08:00
if (MH_CreateHook((LPVOID)Offset::FnCCSWeaponBase_Spawn,
&hook_CCSWeaponBase_Spawn,
reinterpret_cast<LPVOID*>(
&origin_CCSWeaponBase_Spawn)) != MH_OK) {
LOG("MH_CreateHook origin_CCSWeaponBase_Spawn\n");
break;
}
if (MH_CreateHook((LPVOID)Offset::FnUTIL_SayText2FilterPtr,
&hook_UTIL_SayText2Filter,
reinterpret_cast<LPVOID*>(
&origin_UTIL_SayText2Filter)) != MH_OK) {
LOG("MH_CreateHook origin_UTIL_SayText2Filter\n");
break;
}
// <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD>
if (MH_EnableHook(MH_ALL_HOOKS) != MH_OK) {
LOG("MH_EnableHook \n");
break;
}
isSuccess = true;
} while (false);
return isSuccess;
}
auto initVmtHook() -> bool {
VMT_IServerGameClient = new VMTHook(Memory::read<void*>(
reinterpret_cast<uint64_t>(Offset::InterFaces::IServerGameClient)));
2023-10-04 06:01:28 +08:00
VMT_INetworkServerServiceInteFace =
new VMTHook(Memory::read<void*>(reinterpret_cast<uint64_t>(
Offset::InterFaces::INetworkServerServiceInteFace)));
VMT_ISource2ServerInterFace =
new VMTHook(Memory::read<void*>(reinterpret_cast<uint64_t>(
Offset::InterFaces::ISource2ServerInterFace)));
2023-10-20 20:19:22 +08:00
VMT_GameEventSystem =
new VMTHook(Memory::read<void*>(reinterpret_cast<uint64_t>(
Offset::InterFaces::GameEventSystem)));
2023-10-04 06:01:28 +08:00
2023-10-20 20:19:22 +08:00
origin_PostEventAbstract = reinterpret_cast<PostEventAbstract_t>(
VMT_GameEventSystem->Hook(16, hook_PostEventAbstract));
original_OnClientConnected = reinterpret_cast<OnClientConnect_t>(
VMT_IServerGameClient->Hook(11, hook_OnClientConnected));
original_OnClientDisconnect = reinterpret_cast<OnClientDisconnect_t>(
VMT_IServerGameClient->Hook(16, hook_ClientDisconnect));
2023-10-04 06:01:28 +08:00
origin_StartServer = reinterpret_cast<StartupServer_t>(
VMT_INetworkServerServiceInteFace->Hook(27, hook_StartServer));
origin_GameFrame = reinterpret_cast<GameFrame_t>(
VMT_ISource2ServerInterFace->Hook(19, hook_GameFrame));
return original_OnClientConnected && original_OnClientDisconnect &&
origin_StartServer && origin_GameFrame;
}
2023-10-09 01:13:16 +08:00
auto initConVarHooks() -> void {
// Offset::InterFaces::IVEngineCvar->RegisterConVar
2023-10-09 01:13:16 +08:00
}
auto init() -> bool {
bool isSuccess = initMinHook() && initVmtHook();
// bool isSuccess = initVmtHook();
return isSuccess;
}
auto unload() -> void {
VMT_IServerGameClient->ClearHooks();
2023-10-20 20:19:22 +08:00
VMT_INetworkServerServiceInteFace->ClearHooks();
VMT_ISource2ServerInterFace->ClearHooks();
VMT_GameEventSystem->ClearHooks();
2023-10-01 04:57:41 +08:00
delete VMT_IServerGameClient;
2023-10-20 20:19:22 +08:00
delete VMT_INetworkServerServiceInteFace;
delete VMT_ISource2ServerInterFace;
delete VMT_GameEventSystem;
2023-10-01 04:57:41 +08:00
MH_DisableHook(MH_ALL_HOOKS);
MH_RemoveHook(MH_ALL_HOOKS);
MH_Uninitialize();
}
} // namespace hooks