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;
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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;
|
2023-10-20 02:11:59 +08:00
|
|
|
|
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
|
|
|
|
}
|
2023-10-20 02:11:59 +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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-11 03:58:34 +08:00
|
|
|
|
// 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;
|
|
|
|
|
|
}
|
2023-10-11 03:58:34 +08:00
|
|
|
|
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) {
|
2023-10-11 03:58:34 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
lookupWeaponSimpleName = key;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (lookupWeaponSimpleName.size() <= 1) {
|
2023-10-08 02:29:04 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2023-10-11 03:58:34 +08:00
|
|
|
|
// lazy , fix me
|
2023-10-08 02:29:04 +08:00
|
|
|
|
const auto [fullWeaponName, weaponiItemDefIndex] =
|
2023-10-11 03:58:34 +08:00
|
|
|
|
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;
|
2023-10-11 03:58:34 +08:00
|
|
|
|
} 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();
|
|
|
|
|
|
}
|
2023-10-14 02:06:59 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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);
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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);
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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
|
|
|
|
|
2023-10-01 22:13:20 +08:00
|
|
|
|
char* pos = nullptr;
|
2023-10-02 17:31:02 +08:00
|
|
|
|
bool blockMsg = false;
|
2023-10-01 22:13:20 +08:00
|
|
|
|
do {
|
2023-10-19 03:16:12 +08:00
|
|
|
|
if (theArgs == nullptr) {
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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;
|
2023-10-01 22:13:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
} while (false);
|
|
|
|
|
|
/*
|
|
|
|
|
|
if (*pMessage == '!' || *pMessage == '/')
|
|
|
|
|
|
ParseChatCommand(pMessage, pEntity);
|
2023-10-01 02:28:13 +08:00
|
|
|
|
|
2023-10-01 22:13:20 +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);
|
|
|
|
|
|
}
|
2023-10-01 22:13:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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");
|
2023-10-11 03:58:34 +08:00
|
|
|
|
static constexpr auto player_team = hash_32_fnv1a_const("player_team");
|
2023-10-03 00:25:23 +08:00
|
|
|
|
|
2023-10-01 22:13:20 +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;
|
2023-10-11 03:58:34 +08:00
|
|
|
|
case player_team:
|
|
|
|
|
|
events::OnPlayerTeamChangeEevent(event);
|
|
|
|
|
|
break;
|
2023-10-01 22:13:20 +08:00
|
|
|
|
// 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 22:13:20 +08:00
|
|
|
|
}
|
2023-10-01 02:28:13 +08:00
|
|
|
|
|
2023-10-01 22:13:20 +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;
|
|
|
|
|
|
}
|
2023-10-20 02:11:59 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2023-10-01 22:13:20 +08:00
|
|
|
|
// <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));
|
2023-10-01 22:13:20 +08:00
|
|
|
|
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-01 22:13:20 +08:00
|
|
|
|
}
|
2023-10-09 01:13:16 +08:00
|
|
|
|
auto initConVarHooks() -> void {
|
2023-10-11 03:58:34 +08:00
|
|
|
|
// Offset::InterFaces::IVEngineCvar->RegisterConVar
|
2023-10-09 01:13:16 +08:00
|
|
|
|
}
|
2023-10-01 22:13:20 +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
|
|
|
|
|
2023-10-01 22:13:20 +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
|
|
|
|
|
2023-10-01 22:13:20 +08:00
|
|
|
|
MH_DisableHook(MH_ALL_HOOKS);
|
|
|
|
|
|
MH_RemoveHook(MH_ALL_HOOKS);
|
|
|
|
|
|
MH_Uninitialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
} // namespace hooks
|