void *SpawnSpecial::OnSpawnSpecial(ZombieClassType zombieClassType, void *vector, void *qangle) { L4D_DEBUG_LOG("ZombieManager::SpawnSpecial has been called with class %d", zombieClassType); cell_t result = Pl_Continue; cell_t overrideZombieClass = zombieClassType; if(g_pFwdOnSpawnSpecial) { L4D_DEBUG_LOG("L4D_OnSpawnSpecial forward has been sent out"); g_pFwdOnSpawnSpecial->PushCellByRef(&overrideZombieClass); g_pFwdOnSpawnSpecial->PushArray(reinterpret_cast<cell_t*>(vector), 3); g_pFwdOnSpawnSpecial->PushArray(reinterpret_cast<cell_t*>(qangle), 3); g_pFwdOnSpawnSpecial->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("ZombieManager::SpawnSpecial will be skipped"); return NULL; } else if(result == Pl_Changed) { L4D_DEBUG_LOG("ZombieManager::SpawnSpecial will be called with class %d", overrideZombieClass); return (this->*(GetTrampoline()))(*reinterpret_cast<ZombieClassType*>(&overrideZombieClass), vector, qangle); } else { return (this->*(GetTrampoline()))(zombieClassType, vector, qangle); } }
void *GetScriptValueString::OnGetScriptValueString(const char *key, const char *defaultValue, char *retValue, int sizeof_retValue) { L4D_DEBUG_LOG("CDirector::GetScriptValue(%s,%s,%s,%d) is about to be called", key, defaultValue, retValue, sizeof_retValue); cell_t result = Pl_Continue; (this->*(GetTrampoline()))(key, defaultValue, retValue, sizeof_retValue); L4D_DEBUG_LOG("CDirector::GetScriptValue() passed string result: %s", retValue); if(g_pFwdOnGetScriptValueString) { //L4D_DEBUG_LOG("L4D_OnGetScriptValueString() forward has been sent out"); g_pFwdOnGetScriptValueString->PushString(key); defaultValue == NULL ? g_pFwdOnGetScriptValueString->PushString("") : g_pFwdOnGetScriptValueString->PushString(key); g_pFwdOnGetScriptValueString->PushStringEx(retValue, sizeof_retValue, SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); g_pFwdOnGetScriptValueString->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("CDirector::OnGetScriptValueString will be skipped"); return NULL; } else { return (this->*(GetTrampoline()))(key, defaultValue, retValue, sizeof_retValue); } }
void ChangeFinaleStage::OnChangeFinaleStage(int finaleType, const char *key) { cell_t result = Pl_Continue; if(g_pFwdOnChangeFinaleStage) { L4D_DEBUG_LOG("L4D2_OnChangeFinaleStage(%d, [%s]) forward has been sent out", finaleType, key); g_pFwdOnChangeFinaleStage->PushCellByRef(&finaleType); if (key != NULL) { g_pFwdOnChangeFinaleStage->PushString(key); } else { g_pFwdOnChangeFinaleStage->PushString(""); } g_pFwdOnChangeFinaleStage->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("L4D2_OnChangeFinaleStage() will be skipped"); return; } else { (this->*(GetTrampoline()))(finaleType, key); return; } }
float GetScriptValueFloat::OnGetScriptValueFloat(const char *key, float defaultValue) { //L4D_DEBUG_LOG("CDirector::GetScriptValue(%s,%d) has been called", key, defaultValue); cell_t result = Pl_Continue; float actualInvocationResult = (this->*(GetTrampoline()))(key, defaultValue); float overrideValue = actualInvocationResult; if(g_pFwdOnGetScriptValueFloat) { //L4D_DEBUG_LOG("L4D_OnGetScriptValueFloat() forward has been sent out"); g_pFwdOnGetScriptValueFloat->PushString(key); g_pFwdOnGetScriptValueFloat->PushFloatByRef(&overrideValue); float exec = g_pFwdOnGetScriptValueFloat->Execute(&result); //L4D_DEBUG_LOG("L4D_OnGetScriptValueFloat() forward result = %d (0 means no error)", exec); } if(result == Pl_Handled) { //L4D_DEBUG_LOG("CDirector::OnGetScriptValueFloat return value overriden with %d", overrideValue); return overrideValue; } else { return actualInvocationResult; } }
float GetRunTopSpeed::OnGetRunTopSpeed() { //L4D_DEBUG_LOG("CTerrorPlayer::GetRunTopSpeed() has been called"); cell_t result = Pl_Continue; float actualInvocationResult = (this->*(GetTrampoline()))(); float overrideValue = actualInvocationResult; if(g_pFwdOnGetRunTopSpeed) { edict_t *pEntity = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity*>(this)); int target = IndexOfEdict(pEntity); //L4D_DEBUG_LOG("L4D_OnGetRunTopSpeed(target %d) forward has been sent out", target); g_pFwdOnGetRunTopSpeed->PushCell(target); g_pFwdOnGetRunTopSpeed->PushFloatByRef(&overrideValue); g_pFwdOnGetRunTopSpeed->Execute(&result); } if(result == Pl_Handled) { //L4D_DEBUG_LOG("CTerrorPlayer::GetRunTopSpeed() return value overriden with %d", overrideValue); return overrideValue; } else { return actualInvocationResult; } }
int FastGetSurvivorSet::OnFastGetSurvivorSet() { //L4D_DEBUG_LOG("FastGetSurvivorSet() has been called"); cell_t result = Pl_Continue; int actualInvocationResult = (this->*(GetTrampoline()))(); int overrideValue = actualInvocationResult; if(g_pFwdOnFastGetSurvivorSet) { //L4D_DEBUG_LOG("L4D_OnFastGetSurvivorSet(return %d) forward has been sent out", target); g_pFwdOnFastGetSurvivorSet->PushCellByRef(&overrideValue); g_pFwdOnFastGetSurvivorSet->Execute(&result); } if(result == Pl_Handled) { //L4D_DEBUG_LOG("CTerrorPlayer::FastGetSurvivorSet() return value overriden with %d", overrideValue); return overrideValue; } else { return actualInvocationResult; } }
void EndVersusModeRound::OnEndVersusModeRound(bool countSurvivors) { L4D_DEBUG_LOG("CDirectorVersusMode::EndVersusModeRound(%s) has been called", countSurvivors ? "true" : "false"); if(g_bRoundEnd) return; g_bRoundEnd = true; cell_t result = Pl_Continue; if(g_pFwdOnEndVersusModeRound) { L4D_DEBUG_LOG("L4D2_OnEndVersusModeRound forward has been sent out"); g_pFwdOnEndVersusModeRound->PushCell(static_cast<bool>(countSurvivors)); g_pFwdOnEndVersusModeRound->Execute(&result); } if(result == Pl_Handled) return; (this->*(GetTrampoline()))(countSurvivors); if(g_pFwdOnEndVersusModeRound_Post) { L4D_DEBUG_LOG("L4D2_OnEndVersusModeRound_Post forward has been sent out"); g_pFwdOnEndVersusModeRound_Post->Execute(NULL); } return; }
int HasConfigurableDifficulty::OnHasConfigurableDifficulty() { //L4D_DEBUG_LOG("HasConfigurableDifficulty() has been called"); cell_t result = Pl_Continue; int actualInvocationResult = (this->*(GetTrampoline()))(); int overrideValue = actualInvocationResult; if(g_pFwdOnHasConfigurableDifficulty) { //L4D_DEBUG_LOG("L4D_OnHasConfigurableDifficulty(return %d) forward has been sent out", target); g_pFwdOnHasConfigurableDifficulty->PushCellByRef(&overrideValue); g_pFwdOnHasConfigurableDifficulty->Execute(&result); } if(result == Pl_Handled) { //L4D_DEBUG_LOG("CTerrorGameRules::HasConfigurableDifficulty() return value overriden with %d", overrideValue); return overrideValue; } else { return actualInvocationResult; } }
void ClearTeamScores::OnClearTeamScores(CLEAR_TEAM_SCORES_ARG) { bool b = newCampaign; L4D_DEBUG_LOG("CTerrorGameRules::ClearTeamScores has been called, bool=%d", b); cell_t result = Pl_Continue; if(g_pFwdOnClearTeamScores) { L4D_DEBUG_LOG("L4D_OnClearTeamScores forward has been sent out"); g_pFwdOnClearTeamScores->PushCell(static_cast<cell_t>(b)); g_pFwdOnClearTeamScores->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("CTerrorGameRules::ClearTeamScores will be skipped"); return; } else { (this->*(GetTrampoline()))(b); return; } }
void ReplaceTank::OnReplaceTank(CTerrorPlayer* tank, CTerrorPlayer* newtank) { (this->*(GetTrampoline()))(tank, newtank); if (g_pFwdOnReplaceTank) { int old_tank = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(tank))); int new_tank = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(newtank))); g_pFwdOnReplaceTank->PushCell(old_tank); g_pFwdOnReplaceTank->PushCell(new_tank); g_pFwdOnReplaceTank->Execute(NULL); } }
int ShovedBySurvivor::OnShovedBySurvivor(CBaseEntity *sourceEnt, void *sourceDir) { cell_t result = Pl_Continue; if (g_pFwdOnShovedBySurvivor) { cell_t target = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity*>(this))); edict_t *pSource = gameents->BaseEntityToEdict(sourceEnt); g_pFwdOnShovedBySurvivor->PushCell(target); g_pFwdOnShovedBySurvivor->PushCell(pSource ? IndexOfEdict(pSource) : 0); g_pFwdOnShovedBySurvivor->Execute(&result); } return result == Pl_Handled ? 0 : (this->*(GetTrampoline()))(sourceEnt, sourceDir); }
void *PlayerUse::OnPlayerUse(CBaseEntity *p) { cell_t result = Pl_Continue; if (g_pFwdOnPlayerUse) { cell_t client = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity*>(this))); cell_t entity = IndexOfEdict(gameents->BaseEntityToEdict(p)); g_pFwdOnPlayerUse->PushCell(client); g_pFwdOnPlayerUse->PushCell(entity); g_pFwdOnPlayerUse->Execute(&result); } return result == Pl_Handled ? 0 : (this->*(GetTrampoline()))(p); }
int __thiscall RevivedByDefib::OnRevived(CBaseEntity *pInitiator, void *deathModel) { CBaseEntity* pTarget = reinterpret_cast<CBaseEntity*>(this); cell_t client = gamehelpers->EntityToBCompatRef(pTarget); IGamePlayer* pGamePlayer = playerhelpers->GetGamePlayer(client); if(pGamePlayer) { IPlayerInfo* pInfo = pGamePlayer->GetPlayerInfo(); if(pInfo) { r_nowAlive(pInfo->GetAbsOrigin(), g_dead_players, arraysize(g_dead_players)); L4D_DEBUG_LOG("RevivedByDefib called for: %s", pInfo->GetName()); } } return (this->*(GetTrampoline()))(pInitiator, deathModel); }
/* On Windows overwriting maxPlayers makes the server browser display that value On Linux overwriting maxPlayers only makes 'status' show that value as the max */ int ServerPlayerCounts::OnGetMasterServerPlayerCounts(int* currentPlayers, int* maxPlayers, int* unknownArg) { int arg1, arg2, arg3; int results = (this->*(GetTrampoline()))(&arg1, &arg2, &arg3); //spams log every 2 seconds //L4D_DEBUG_LOG("CServer::GetMasterServerPlayerCounts returned %d, args(%d, %d, %d) / MaxSlots = %d", results, arg1, arg2, arg3, ::PlayerSlots::MaxSlots); *currentPlayers = arg1; *maxPlayers = arg2; *unknownArg = arg3; //always 0 in brief testing if(::PlayerSlots::MaxSlots != -1) { *maxPlayers = ::PlayerSlots::MaxSlots; } return results; }
void CBaseServer::OnFillServerInfo(int SVC_ServerInfo) { cell_t result = Pl_Continue; if (g_pFwdAddonsDisabler && AddonsDisabler::AddonsEclipse > 0 && vanillaModeSig) { int m_nPlayerSlot = *(int *)((unsigned char *)SVC_ServerInfo + 48); IClient *pClient = g_pServer->GetClient(m_nPlayerSlot); L4D_DEBUG_LOG("ADDONS DISABLER: Eligible client '%s' connected[%s]", pClient->GetClientName(), pClient->GetNetworkIDString()); g_pFwdAddonsDisabler->PushString(pClient->GetNetworkIDString()); g_pFwdAddonsDisabler->Execute(&result); /* uint8_t != unsigned char in terms of type */ uint8_t disableAddons = result == Pl_Handled ? 0 : 1; memset((unsigned char *)SVC_ServerInfo + 25, disableAddons, sizeof(uint8_t)); } (this->*(GetTrampoline()))(SVC_ServerInfo); }
void *ShovedByPounceLanding::OnShovedByPounceLanding(CTerrorPlayer* jockeyOrHunter) { cell_t result = Pl_Continue; if (g_pFwdOnShovedByPounceLanding) { int victim = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(this))); int attacker = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(jockeyOrHunter))); g_pFwdOnShovedByPounceLanding->PushCell(victim); g_pFwdOnShovedByPounceLanding->PushCell(attacker); g_pFwdOnShovedByPounceLanding->Execute(&result); } if (result == Pl_Handled) { return NULL; } else { return (this->*(GetTrampoline()))(jockeyOrHunter); } }
void *FirstSurvivorLeftSafeArea::OnFirstSurvivorLeftSafeArea(CTerrorPlayer *p) { L4D_DEBUG_LOG("CDirector::OnFirstSurvivorLeftSafeArea has been called"); cell_t result = Pl_Continue; if(g_pFwdOnFirstSurvivorLeftSafeArea) { int client; if(p == NULL) { /* quite possible the survivor is NULL e.g. CDirectorScavengeMode::ShouldUpdateTeamReadiness calls OnFirstSurvivorLeftSafeArea(NULL) */ client = 0; } else { edict_t *pEntity = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity*>(p)); client = IndexOfEdict(pEntity); } L4D_DEBUG_LOG("L4D_OnFirstSurvivorLeftSafeArea(%d) forward has been sent out", client); g_pFwdOnFirstSurvivorLeftSafeArea->PushCell(client); g_pFwdOnFirstSurvivorLeftSafeArea->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("CDirector::OnFirstSurvivorLeftSafeArea will be skipped"); return NULL; } else { g_bRoundEnd = false; return (this->*(GetTrampoline()))(p); } }
void *SpawnTank::OnSpawnTank(void *vector, void *qangle) { L4D_DEBUG_LOG("ZombieManager::SpawnTank has been called"); cell_t result = Pl_Continue; if(g_pFwdOnSpawnTank) { L4D_DEBUG_LOG("L4D_OnTankSpawn forward has been sent out"); g_pFwdOnSpawnTank->PushArray(reinterpret_cast<cell_t*>(vector), 3); g_pFwdOnSpawnTank->PushArray(reinterpret_cast<cell_t*>(qangle), 3); g_pFwdOnSpawnTank->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("ZombieManager::SpawnTank will be skipped"); return NULL; } else { return (this->*(GetTrampoline()))(vector, qangle); } }
void GameRulesNetworkChanged::OnGameRulesNetworkChanged() { L4D_DEBUG_LOG("CTerrorGameRules::GameRulesNetworkChanged has been called"); cell_t result = Pl_Continue; if(g_pFwdOnGameRulesNetworkChanged) { L4D_DEBUG_LOG("L4D_OnGameRulesNetworkChanged forward has been sent out"); g_pFwdOnGameRulesNetworkChanged->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("Director::GameRulesNetworkChanged will be skipped"); return; } else { L4D_DEBUG_LOG("CTerrorGameRules::GameRulesNetworkChanged will be invoked"); return (this->*(GetTrampoline()))(); } }
ActionStruct_t JockeyAttackUpdate::OnJockeyAttackUpdate(Jockey* pJockey, float fu) { cell_t result = Pl_Continue; if(g_pFwdOnJockeyAttackUpdate) { edict_t *pJockeyEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity*>(pJockey)); cell_t entity = IndexOfEdict(pJockeyEdict); cell_t victim = *(reinterpret_cast<cell_t*>(this)+13); g_pFwdOnJockeyAttackUpdate->PushCell(entity); g_pFwdOnJockeyAttackUpdate->PushCellByRef(&victim); g_pFwdOnJockeyAttackUpdate->Execute(&result); if(result == Pl_Handled) { *(reinterpret_cast<DWORD*>(this)+13) = NULL; } else if (result == Pl_Changed) { *(reinterpret_cast<DWORD*>(this)+13) = victim; } } ActionStruct_t ActionResult = (this->*(GetTrampoline()))(pJockey, fu); return ActionResult; }
void SpawnITMob::OnSpawnITMob(int amount) { L4D_DEBUG_LOG("ZombieManager::SpawnITMob(%d) has been called", amount); cell_t result = Pl_Continue; if(g_pFwdOnSpawnITMob) { L4D_DEBUG_LOG("L4D_OnSpawnITMob() forward has been sent out"); g_pFwdOnSpawnITMob->PushCellByRef(&amount); g_pFwdOnSpawnITMob->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("ZombieManager::SpawnITMob will be skipped"); return; } else { (this->*(GetTrampoline()))(amount); return; } }
void RecomputeTeamScores::OnRecomputeTeamScores() { L4D_DEBUG_LOG("CTerrorGameRules::RecomputeTeamScores has been called"); /* //unsigned char *calloffset = *(unsigned char **)writeaddr; float maxflow; //-0x208694(%ebx),%ecx __asm__("mov -0xf0(%%ebx),%%eax\n\t" "mov (%%eax),%%eax\n\t" "mov 0x5a8(%%eax),%0" :"=r"(maxflow)); //__asm__("mov -0x227040(%%ebx), %0;" :"=r"(maxflow)); L4D_DEBUG_LOG("L4D_OnRecomputeTeamScores MaxFlow -> %.2f", maxflow); */ cell_t result = Pl_Continue; if(g_pFwdOnRecomputeTeamScores) { L4D_DEBUG_LOG("L4D_OnRecomputeTeamScores forward has been sent out"); g_pFwdOnRecomputeTeamScores->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("Director::RecomputeTeamScores will be skipped"); return; } else { L4D_DEBUG_LOG("CTerrorGameRules::RecomputeTeamScores will be invoked"); return (this->*(GetTrampoline()))(); } }
void GetMissionVersusBossSpawning::OnGetMissionVersusBossSpawning(float &spawn_pos_min, float &spawn_pos_max, float &tank_chance, float &witch_chance) { L4D_DEBUG_LOG("CDirectorVersusMode::GetMissionVersusBossSpawning has been called, %f %f %f %f", spawn_pos_min, spawn_pos_max, tank_chance, witch_chance); float ov_spawn_pos_min = spawn_pos_min; float ov_spawn_pos_max = spawn_pos_max; float ov_tank_chance = tank_chance; float ov_witch_chance = witch_chance; cell_t result = Pl_Continue; if(g_pFwdOnGetMissionVersusBossSpawning) { L4D_DEBUG_LOG("L4D_OnGetMissionVersusBossSpawning forward has been sent out"); g_pFwdOnGetMissionVersusBossSpawning->PushFloatByRef(&ov_spawn_pos_min); g_pFwdOnGetMissionVersusBossSpawning->PushFloatByRef(&ov_spawn_pos_max); g_pFwdOnGetMissionVersusBossSpawning->PushFloatByRef(&ov_tank_chance); g_pFwdOnGetMissionVersusBossSpawning->PushFloatByRef(&ov_witch_chance); g_pFwdOnGetMissionVersusBossSpawning->Execute(&result); } switch(result) { case Pl_Changed: spawn_pos_min = ov_spawn_pos_min; spawn_pos_max = ov_spawn_pos_max; tank_chance = ov_tank_chance; witch_chance = ov_witch_chance; break; case Pl_Handled: break; case Pl_Continue: default: (this->*(GetTrampoline()))(spawn_pos_min, spawn_pos_max, tank_chance, witch_chance); } return; }
void *TerrorWeaponHit::OnTerrorWeaponHit(CGameTrace *trace/* a1 */, void *vector/* a2 */, bool userCall/* a3 */) { L4D_DEBUG_LOG("CTerrorWeapon::OnHit() has been called"); cell_t result = Pl_Continue; int hEntity = *(int *)((unsigned char*)trace + 76); // did the m2 trace hit anyone(i.e. an entity) /* deadstop check: see if it's going to be versus_shove_hunter_fov_pouncing(true) or versus_shove_hunter_fov(false) often returns 0 when it shouldn't - either this shit is unreliable, or the game is buggy as f**k probably both */ int isDeadstop = *(int *)((unsigned char *)hEntity + 16024); int weapon = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(this))); int entity = IndexOfEdict(gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(hEntity))); CBaseHandle &weaponOwner = *(CBaseHandle *)((unsigned char *)this + 5108); // get the weapon's owner and thus check its validity(shoves are a secondary attack of anything you're able to hold, even pills and cola) int client = !weaponOwner.IsValid() ? -1 : weaponOwner.GetEntryIndex(); // very simplistic and unreliable check, but meh /* there's another check being performed here to see if the current gamemode allows bashing... we don't need it */ if (g_pFwdOnTerrorWeaponHit && client && entity && userCall) { g_pFwdOnTerrorWeaponHit->PushCell(client); // who shoved g_pFwdOnTerrorWeaponHit->PushCell(entity); // who got shoved g_pFwdOnTerrorWeaponHit->PushCell(weapon); // weapon that's been held while shoving g_pFwdOnTerrorWeaponHit->PushArray(reinterpret_cast<cell_t *>(vector), 3); // shove angles g_pFwdOnTerrorWeaponHit->PushCell(isDeadstop ? true : false); // reliable for high pounces only g_pFwdOnTerrorWeaponHit->Execute(&result); } if(result == Pl_Handled) { L4D_DEBUG_LOG("CTerrorWeapon::OnHit() will be skipped"); return NULL; } else { return (this->*(GetTrampoline()))(trace, vector, userCall); } }