QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl) { QueryCvarCookie_t cookie = 0; #if SOURCE_ENGINE != SE_DARKMESSIAH /* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */ if (m_bIsDLLQueryHooked) { #if SOURCE_ENGINE == SE_DOTA cookie = engine->StartQueryCvarValue(CEntityIndex(IndexOfEdict(pPlayer)), name); #else cookie = engine->StartQueryCvarValue(pPlayer, name); #endif } #if SOURCE_ENGINE != SE_DOTA else if (m_bIsVSPQueryHooked) { cookie = serverpluginhelpers->StartQueryCvarValue(pPlayer, name); } #endif else { return InvalidQueryCvarCookie; } ConVarQuery query = {cookie, pCallback, (cell_t)hndl, IndexOfEdict(pPlayer)}; m_ConVarQueries.push_back(query); #endif return cookie; }
QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl) { QueryCvarCookie_t cookie = sCoreProviderImpl.QueryClientConVar(IndexOfEdict(pPlayer), name); if (pCallback != NULL) { ConVarQuery query = { cookie, pCallback, (cell_t) hndl, IndexOfEdict(pPlayer) }; m_ConVarQueries.push_back(query); } return cookie; }
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); } }
void ValveMenuStyle::HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin) { if (type != DIALOG_MENU) { return; } int client = IndexOfEdict(pEdict); if (client < 1 || client > 256) { return; } CValveMenuPlayer *player = &m_players[client]; /* We don't care if the player is in a menu because, for all intents and purposes, * the menu is completely private. Instead, we just figure out the level we'll need * in order to override it. */ player->curPrioLevel = kv->GetInt("level", player->curPrioLevel); /* Oh no! What happens if we got a menu that overwrites ours?! */ if (player->bInMenu) { /* Okay, let the external menu survive for now. It may live another * day to avenge its grandfather, killed in the great Menu Interruption * battle. */ _CancelClientMenu(client, MenuCancel_Interrupted, true); } }
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); }
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) { ValvePassInfo pass[2]; InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall)) { return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod"); } else if (!pCall) { return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized"); } } CBaseEntity *pEntity; START_CALL(); DECODE_VALVE_PARAM(1, thisinfo, 0); DECODE_VALVE_PARAM(2, vparams, 0); FINISH_CALL_SIMPLE(&pEntity); if (pEntity == NULL) { return -1; } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict) { return -1; } return IndexOfEdict(pEdict); }
static cell_t CreateFakeClient(IPluginContext *pContext, const cell_t *params) { if (!g_SourceMod.IsMapRunning()) { return pContext->ThrowNativeError("Cannot create fakeclient when no map is active"); } char *netname; pContext->LocalToString(params[1], &netname); #if SOURCE_ENGINE == SE_DOTA int index = engine->CreateFakeClient(netname).Get(); if (index == -1) { return 0; } return index; #else edict_t *pEdict = engine->CreateFakeClient(netname); /* :TODO: does the engine fire forwards for us and whatnot? no idea... */ if (!pEdict) { return 0; } return IndexOfEdict(pEdict); #endif }
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; } }
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); }
//--------------------------------------------------------------------------------- // Purpose: Process a players death //--------------------------------------------------------------------------------- void ManiAFK::ProcessUsercmds ( CBasePlayer *pPlayer, CUserCmd *cmds, int numcmds ) { if (war_mode) return; if (mani_afk_kicker.GetInt() == 0) return; if (!pPlayer) return; edict_t *pEdict = serverents->BaseEntityToEdict((CBaseEntity *) pPlayer); if (!pEdict) return; #if defined ( GAME_CSGO ) int index = IndexOfEdict(pEdict); #else int index = engine->IndexOfEdict(pEdict); #endif if (index < 1 || index > max_players) return; if (cmds && numcmds && (cmds->forwardmove || cmds->sidemove || cmds->upmove || cmds->mousedx || cmds->mousedy)) { index --; time_t current_time; time(¤t_time); afk_list[index].last_active = current_time; afk_list[index].idle = false; afk_list[index].round_count = 0; } }
virtual void FakeClientCommand(edict_t *pEdict, const char *szCommand) { #if SOURCE_ENGINE == SE_DOTA engine->ClientCommand(IndexOfEdict(pEdict), "%s", szCommand); #else serverpluginhelpers->ClientCommand(pEdict, szCommand); #endif }
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor() { #if SOURCE_ENGINE == SE_DOTA return engine->GetChangeAccessor( IndexOfEdict((const edict_t *)this) ); #else return engine->GetChangeAccessor( (const edict_t *)this ); #endif }
virtual void ClientCommand(edict_t *pEdict, const char *szCommand) { #if SOURCE_ENGINE == SE_DOTA engine->ClientCommand(IndexOfEdict(pEdict), "%s", szCommand); #else engine->ClientCommand(pEdict, "%s", szCommand); #endif }
int GetClientAimTarget(edict_t *pEdict, bool only_players) { CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; if (pEntity == NULL) { return -1; } Vector eye_position; QAngle eye_angles; /* Get the private information we need */ #if SOURCE_ENGINE == SE_DOTA serverClients->ClientEarPosition(IndexOfEdict(pEdict), &eye_position); #else serverClients->ClientEarPosition(pEdict, &eye_position); #endif if (!GetEyeAngles(pEntity, &eye_angles)) { return -2; } Vector aim_dir; AngleVectors(eye_angles, &aim_dir); VectorNormalize(aim_dir); Vector vec_end = eye_position + aim_dir * 8000; Ray_t ray; ray.Init(eye_position, vec_end); trace_t tr; CTraceFilterSimple simple(pEdict->GetIServerEntity()); enginetrace->TraceRay(ray, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &simple, &tr); if (tr.fraction == 1.0f || tr.m_pEnt == NULL) { return -1; } int ent_ref = gamehelpers->EntityToBCompatRef(tr.m_pEnt); int ent_index = gamehelpers->ReferenceToIndex(ent_ref); IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index); if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame()) { return -1; } else if (only_players && pTargetPlayer == NULL) { return -1; } return ent_ref; }
bool SamplePlugin::Hook_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) { META_LOG(g_PLAPI, "Hook_ClientConnect(%d, \"%s\", \"%s\")", IndexOfEdict(pEntity), pszName, pszAddress); return true; }
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); } }
//--------------------------------------------------------------------------------- // Purpose: Check if player can pickup weapon or not //--------------------------------------------------------------------------------- bool ManiWeaponMgr::CanPickUpWeapon(CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon) { if (war_mode) return true; if (mani_weapon_restrict_prevent_pickup.GetInt() == 0) return true; if (gpManiWarmupTimer->KnivesOnly()) return true; edict_t *pEdict = serverents->BaseEntityToEdict((CBasePlayer *) pPlayer); if (!pEdict) return true; #if defined ( GAME_CSGO ) int index = IndexOfEdict(pEdict); #else int index = engine->IndexOfEdict(pEdict); #endif if (index < 1 || index > max_players) return true; if (ignore_hook[index - 1]) { return true; } const char *weapon_name = CBaseCombatWeapon_GetName(pWeapon); // Find index for (int i = 0; i < MAX_WEAPONS_USED; i++) { if ( !weapons[i] ) break; // for DS tool and listen servers ... order of processing different if (strcmp(weapons[i]->GetWeaponName(), weapon_name) != 0) continue; if (weapons[i]->GetDisplayID() == 0) continue; player_t player; player.index = index; if (!FindPlayerByIndex(&player)) break; int reason, limit, ratio; if (!weapons[i]->CanBuy(&player, 0, reason, limit, ratio)) { if (next_message[player.index - 1] < gpGlobals->curtime) { ShowRestrictReason(&player, weapons[i], reason, limit, ratio); next_message[player.index - 1] = gpGlobals->curtime + 1.2; } return false; } break; } return true; }
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); } }
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue) #endif // SE_DOTA { IPluginFunction *pCallback = NULL; cell_t value = 0; List<ConVarQuery>::iterator iter; for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end(); iter++) { ConVarQuery &query = (*iter); if (query.cookie == cookie) { pCallback = query.pCallback; value = query.value; break; } } if (pCallback) { cell_t ret; pCallback->PushCell(cookie); #if SOURCE_ENGINE == SE_DOTA pCallback->PushCell(player.Get()); #else pCallback->PushCell(IndexOfEdict(pPlayer)); #endif pCallback->PushCell(result); pCallback->PushString(cvarName); if (result == eQueryCvarValueStatus_ValueIntact) { pCallback->PushString(cvarValue); } else { pCallback->PushString("\0"); } pCallback->PushCell(value); pCallback->Execute(&ret); m_ConVarQueries.erase(iter); } }
void SamplePlugin::Hook_ClientSettingsChanged(edict_t *pEdict) { if (playerinfomanager) { IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(pEdict); const char *name = engine->GetClientConVarValue(IndexOfEdict(pEdict), "name"); if (playerinfo != NULL && name != NULL && strcmp(engine->GetPlayerNetworkIDString(pEdict), "BOT") != 0 && playerinfo->GetName() != NULL && strcmp(name, playerinfo->GetName()) == 0) { char msg[128]; MM_Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName()); engine->ClientPrintf(pEdict, msg); } } }
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); } }
static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) { ValvePassInfo pass[4]; InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); InitPass(pass[2], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); InitPass(pass[3], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); if (!CreateBaseCall("CreateEntityByName", ValveCall_Static, &pass[3], pass, 3, &pCall)) { return pContext->ThrowNativeError("\"CreateEntityByName\" not supported by this mod"); } else if (!pCall) { return pContext->ThrowNativeError("\"CreateEntityByName\" wrapper failed to initialized"); } } CBaseEntity *pEntity = NULL; START_CALL(); DECODE_VALVE_PARAM(1, vparams, 0); DECODE_VALVE_PARAM(2, vparams, 1); *(bool *)(vptr + 8) = true; FINISH_CALL_SIMPLE(&pEntity); if (pEntity == NULL) { return -1; } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict) { return -1; } return IndexOfEdict(pEdict); }
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; }
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params) { static ValveCall *pCall = NULL; if (!pCall) { ValvePassInfo pass[3]; InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL|VDECODE_FLAG_ALLOWWORLD); InitPass(pass[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL); InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); if (!CreateBaseCall("FindEntityByClassname", ValveCall_EntityList, &pass[2], pass, 2, &pCall)) { return pContext->ThrowNativeError("\"FindEntityByClassname\" not supported by this mod"); } else if (!pCall) { return pContext->ThrowNativeError("\"FindEntityByClassname\" wrapper failed to initialized"); } } CBaseEntity *pEntity; START_CALL(); *(void **)vptr = g_EntList; DECODE_VALVE_PARAM(1, vparams, 0); DECODE_VALVE_PARAM(2, vparams, 1); FINISH_CALL_SIMPLE(&pEntity); if (pEntity == NULL) { return -1; } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict) { return -1; } return IndexOfEdict(pEdict); }
void CHookManager::PlayerRunCmd(CUserCmd *ucmd, IMoveHelper *moveHelper) { if (m_usercmdsFwd->GetFunctionCount() == 0) { RETURN_META(MRES_IGNORED); } CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity); if (!pEntity) { RETURN_META(MRES_IGNORED); } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict) { RETURN_META(MRES_IGNORED); } int client = IndexOfEdict(pEdict); cell_t result = 0; /* Impulse is a byte so we copy it back manually */ cell_t impulse = ucmd->impulse; cell_t vel[3] = {sp_ftoc(ucmd->forwardmove), sp_ftoc(ucmd->sidemove), sp_ftoc(ucmd->upmove)}; cell_t angles[3] = {sp_ftoc(ucmd->viewangles.x), sp_ftoc(ucmd->viewangles.y), sp_ftoc(ucmd->viewangles.z)}; cell_t mouse[2] = {ucmd->mousedx, ucmd->mousedy}; m_usercmdsFwd->PushCell(client); m_usercmdsFwd->PushCellByRef(&ucmd->buttons); m_usercmdsFwd->PushCellByRef(&impulse); m_usercmdsFwd->PushArray(vel, 3, SM_PARAM_COPYBACK); m_usercmdsFwd->PushArray(angles, 3, SM_PARAM_COPYBACK); m_usercmdsFwd->PushCellByRef(&ucmd->weaponselect); m_usercmdsFwd->PushCellByRef(&ucmd->weaponsubtype); m_usercmdsFwd->PushCellByRef(&ucmd->command_number); m_usercmdsFwd->PushCellByRef(&ucmd->tick_count); m_usercmdsFwd->PushCellByRef(&ucmd->random_seed); m_usercmdsFwd->PushArray(mouse, 2, SM_PARAM_COPYBACK); m_usercmdsFwd->Execute(&result); ucmd->impulse = impulse; ucmd->forwardmove = sp_ctof(vel[0]); ucmd->sidemove = sp_ctof(vel[1]); ucmd->upmove = sp_ctof(vel[2]); ucmd->viewangles.x = sp_ctof(angles[0]); ucmd->viewangles.y = sp_ctof(angles[1]); ucmd->viewangles.z = sp_ctof(angles[2]); ucmd->mousedx = mouse[0]; ucmd->mousedy = mouse[1]; if (result == Pl_Handled) { RETURN_META(MRES_SUPERCEDE); } RETURN_META(MRES_IGNORED); }
void SamplePlugin::Hook_ClientDisconnect(edict_t *pEntity) { META_LOG(g_PLAPI, "Hook_ClientDisconnect(%d)", IndexOfEdict(pEntity)); }
static cell_t SDKCall(IPluginContext *pContext, const cell_t *params) { ValveCall *vc; HandleError err; HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); if ((err = handlesys->ReadHandle(params[1], g_CallHandle, &sec, (void **)&vc)) != HandleError_None) { return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err); } unsigned char *ptr = vc->stk_get(); unsigned int numparams = (unsigned)params[0]; unsigned int startparam = 2; /* Do we need to write a thispointer? */ if (vc->thisinfo) { switch (vc->type) { case ValveCall_Entity: case ValveCall_Player: { if (startparam > numparams) { vc->stk_put(ptr); return pContext->ThrowNativeError("Expected 1 parameter for entity pointer; found none"); } if (DecodeValveParam(pContext, params[startparam], vc, vc->thisinfo, ptr) == Data_Fail) { vc->stk_put(ptr); return 0; } startparam++; } break; case ValveCall_GameRules: { if (g_pGameRules == NULL) { vc->stk_put(ptr); return pContext->ThrowNativeError("GameRules unsupported or not available; file a bug report"); } void *gamerules = *g_pGameRules; if (gamerules == NULL) { vc->stk_put(ptr); return pContext->ThrowNativeError("GameRules not available before map is loaded"); } *(void **)ptr = gamerules; } break; case ValveCall_EntityList: { if (g_EntList == NULL) { vc->stk_put(ptr); return pContext->ThrowNativeError("EntityList unsupported or not available; file a bug report"); } *(void **)ptr = g_EntList; } break; } } /* See if we need to skip any more parameters */ unsigned int retparam = startparam; if (vc->retinfo) { if (vc->retinfo->vtype == Valve_String) { startparam += 2; } else if (vc->retinfo->vtype == Valve_Vector || vc->retinfo->vtype == Valve_QAngle) { startparam += 1; } } unsigned int callparams = vc->call->GetParamCount(); bool will_copyback = false; for (unsigned int i=0; i<callparams; i++) { unsigned int p = startparam + i; if (p > numparams) { vc->stk_put(ptr); return pContext->ThrowNativeError("Expected %dth parameter, found none", p); } if (DecodeValveParam(pContext, params[p], vc, &(vc->vparams[i]), ptr) == Data_Fail) { vc->stk_put(ptr); return 0; } if (vc->vparams[i].encflags & VENCODE_FLAG_COPYBACK) { will_copyback = true; } } /* Make the actual call */ vc->call->Execute(ptr, vc->retbuf); /* Do we need to copy anything back? */ if (will_copyback) { for (unsigned int i=0; i<callparams; i++) { if (vc->vparams[i].encflags & VENCODE_FLAG_COPYBACK) { if (EncodeValveParam(pContext, params[startparam + i], vc, &vc->vparams[i], ptr) == Data_Fail) { vc->stk_put(ptr); return 0; } } } } /* Save stack once and for all */ vc->stk_put(ptr); /* Figure out how to decode the return information */ if (vc->retinfo) { if (vc->retinfo->vtype == Valve_String) { if (numparams < 3) { return pContext->ThrowNativeError("Expected arguments (2,3) for string storage"); } cell_t *addr; size_t written; pContext->LocalToPhysAddr(params[retparam+1], &addr); pContext->StringToLocalUTF8(params[retparam], *addr, *(char **)vc->retbuf, &written); return (cell_t)written; } else if (vc->retinfo->vtype == Valve_Vector || vc->retinfo->vtype == Valve_QAngle) { if (numparams < 2) { return pContext->ThrowNativeError("Expected argument (2) for Float[3] storage"); } if (EncodeValveParam(pContext, params[retparam], vc, vc->retinfo, vc->retbuf) == Data_Fail) { return 0; } } else if (vc->retinfo->vtype == Valve_CBaseEntity || vc->retinfo->vtype == Valve_CBasePlayer) { CBaseEntity *pEntity = *(CBaseEntity **)(vc->retbuf); if (!pEntity) { return -1; } edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); if (!pEdict || pEdict->IsFree()) { return -1; } return IndexOfEdict(pEdict); } else if (vc->retinfo->vtype == Valve_Edict) { edict_t *pEdict = *(edict_t **)(vc->retbuf); if (!pEdict || pEdict->IsFree()) { return -1; } return IndexOfEdict(pEdict); } else if (vc->retinfo->vtype == Valve_Bool) { bool *addr = (bool *)vc->retbuf; if (vc->retinfo->flags & PASSFLAG_ASPOINTER) { addr = *(bool **)addr; } return *addr ? 1 : 0; } else { cell_t *addr = (cell_t *)vc->retbuf; if (vc->retinfo->flags & PASSFLAG_ASPOINTER) { addr = *(cell_t **)addr; } return *addr; } } return 0; }
void SamplePlugin::Hook_ClientActive(edict_t *pEntity, bool bLoadGame) { META_LOG(g_PLAPI, "Hook_ClientActive(%d, %d)", IndexOfEdict(pEntity), bLoadGame); }