static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *params) { IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]); if (player == NULL) { return pContext->ThrowNativeError("Invalid client index %d", params[1]); } if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", params[1]); } Vector pos; serverClients->ClientEarPosition(player->GetEdict(), &pos); cell_t *addr; pContext->LocalToPhysAddr(params[2], &addr); addr[0] = sp_ftoc(pos.x); addr[1] = sp_ftoc(pos.y); addr[2] = sp_ftoc(pos.z); return 1; }
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params) { int client = params[1]; IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); if (!pPlayer) { return pContext->ThrowNativeError("Invalid client index %d", client); } else if (!pPlayer->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } edict_t *pEdict = pPlayer->GetEdict(); CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL; /* We always set the angles for backwards compatibility -- * The original function had no return value. */ QAngle angles; bool got_angles = false; if (pEntity != NULL) { got_angles = GetEyeAngles(pEntity, &angles); } cell_t *addr; pContext->LocalToPhysAddr(params[2], &addr); addr[0] = sp_ftoc(angles.x); addr[1] = sp_ftoc(angles.y); addr[2] = sp_ftoc(angles.z); return got_angles ? 1 : 0; }
DataStatus DecodeValveParam(IPluginContext *pContext, cell_t param, const ValveCall *pCall, const ValvePassInfo *data, void *_buffer) { void *buffer = (unsigned char *)_buffer + data->offset; switch (data->vtype) { case Valve_Vector: { cell_t *addr; int err; err = pContext->LocalToPhysAddr(param, &addr); unsigned char *mem = (unsigned char *)buffer; if (data->type == PassType_Basic) { /* Store the object in the next N bytes, and store * a pointer to that object right beforehand. */ Vector **realPtr = (Vector **)buffer; if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { *realPtr = NULL; return Data_Okay; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else { mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; *realPtr = (Vector *)mem; } } if (err != SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); return Data_Fail; } /* Use placement new to initialize the object cleanly * This has no destructor so we don't need to do * DestroyValveParam() or something :] */ Vector *v = new (mem) Vector( sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])); return Data_Okay; } case Valve_QAngle: { cell_t *addr; int err; err = pContext->LocalToPhysAddr(param, &addr); unsigned char *mem = (unsigned char *)buffer; if (data->type == PassType_Basic) { /* Store the object in the next N bytes, and store * a pointer to that object right beforehand. */ QAngle **realPtr = (QAngle **)buffer; if (addr == pContext->GetNullRef(SP_NULL_VECTOR)) { if (!(data->decflags & VDECODE_FLAG_ALLOWNULL)) { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } else { *realPtr = NULL; return Data_Okay; } } else { mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; *realPtr = (QAngle *)mem; } } if (err != SP_ERROR_NONE) { pContext->ThrowNativeErrorEx(err, "Could not read plugin data"); return Data_Fail; } /* Use placement new to initialize the object cleanly * This has no destructor so we don't need to do * DestroyValveParam() or something :] */ QAngle *v = new (mem) QAngle( sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2])); return Data_Okay; } case Valve_CBasePlayer: { CBaseEntity *pEntity = NULL; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } int index = gamehelpers->ReferenceToIndex(param); if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1) { return Data_Fail; } if (index >= 1 && index <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(index); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEntity = gamehelpers->ReferenceToEntity(param); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEntity = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else { pContext->ThrowNativeError("Entity index %d is not a valid client", param); return Data_Fail; } CBaseEntity **ebuf = (CBaseEntity **)buffer; *ebuf = pEntity; return Data_Okay; } case Valve_CBaseEntity: { CBaseEntity *pEntity = NULL; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } int index = gamehelpers->ReferenceToIndex(param); if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1) { return Data_Fail; } if (index >= 1 && index <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(index); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEntity = gamehelpers->ReferenceToEntity(param); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEntity = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else if (index == 0) { if (data->decflags & VDECODE_FLAG_ALLOWWORLD) { pEntity = gamehelpers->ReferenceToEntity(0); } else { pContext->ThrowNativeError("World not allowed"); return Data_Fail; } } else { pEntity = gamehelpers->ReferenceToEntity(param); if (!pEntity) { pContext->ThrowNativeError("Entity %d is not valid", param); return Data_Fail; } } CBaseEntity **ebuf = (CBaseEntity **)buffer; *ebuf = pEntity; return Data_Okay; } case Valve_Edict: { edict_t *pEdict; if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (param >= 1 && param <= playerhelpers->GetMaxClients()) { IGamePlayer *player = playerhelpers->GetGamePlayer(param); if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME) && !player->IsConnected()) { pContext->ThrowNativeError("Client %d is not connected", param); return Data_Fail; } else if (!player->IsInGame()) { pContext->ThrowNativeError("Client %d is not in game", param); return Data_Fail; } pEdict = player->GetEdict(); } else if (param == -1) { if (data->decflags & VDECODE_FLAG_ALLOWNULL) { pEdict = NULL; } else { pContext->ThrowNativeError("NULL not allowed"); return Data_Fail; } } else if (param == 0) { if (data->decflags & VDECODE_FLAG_ALLOWWORLD) { pEdict = PEntityOfEntIndex(0); } else { pContext->ThrowNativeError("World not allowed"); return Data_Fail; } } else { pEdict = PEntityOfEntIndex(param); if (!pEdict || pEdict->IsFree()) { pContext->ThrowNativeError("Entity %d is not valid or is freed", param); return Data_Fail; } } edict_t **ebuf = (edict_t **)buffer; *ebuf = pEdict; return Data_Okay; } case Valve_POD: case Valve_Float: { if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (data->flags & PASSFLAG_ASPOINTER) { *(void **)buffer = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset; buffer = *(void **)buffer; } *(cell_t *)buffer = param; return Data_Okay; } case Valve_Bool: { if (data->decflags & VDECODE_FLAG_BYREF) { cell_t *addr; pContext->LocalToPhysAddr(param, &addr); param = *addr; } if (data->flags & PASSFLAG_ASPOINTER) { *(bool **)buffer = (bool *)((unsigned char *)_buffer + pCall->stackEnd + data->obj_offset); buffer = *(bool **)buffer; } *(bool *)buffer = param ? true : false; return Data_Okay; } case Valve_String: { char *addr; pContext->LocalToString(param, &addr); *(char **)buffer = addr; return Data_Okay; } } return Data_Fail; }
static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params) { static bool s_slap_supported = false; static bool s_slap_setup = false; static ICallWrapper *s_teleport = NULL; static int s_health_offs = 0; static int s_sound_count = 0; static int s_frag_offs = 0; if (!s_slap_setup) { int tries = 0; s_slap_setup = true; if (IsTeleportSupported()) { tries++; } if (IsGetVelocitySupported()) { tries++; } /* Setup health */ if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs) { tries++; } if (tries == 3) { s_slap_supported = true; const char *key; if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL) { s_sound_count = atoi(key); } } } if (!s_slap_supported) { return pContext->ThrowNativeError("This function is not supported on this mod"); } /* First check if the client is valid */ int client = params[1]; IGamePlayer *player = playerhelpers->GetGamePlayer(client); if (!player) { return pContext->ThrowNativeError("Client %d is not valid", client); } else if (!player->IsInGame()) { return pContext->ThrowNativeError("Client %d is not in game", client); } edict_t *pEdict = player->GetEdict(); CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity(); /* See if we should be taking away health */ bool should_slay = false; if (params[2]) { #if SOURCE_ENGINE != SE_DARKMESSIAH int *health = (int *)((char *)pEntity + s_health_offs); if (*health - params[2] <= 0) { *health = 1; should_slay = true; } else { *health -= params[2]; } #else float *health = (float *)((char *)pEntity + s_health_offs); if (*health - (float)params[2] <= 0) { *health = 1.0f; should_slay = true; } else { *health -= (float)params[2]; } #endif } /* Teleport in a random direction - thank you, Mani!*/ Vector velocity; GetVelocity(pEntity, &velocity, NULL); velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1); velocity.z += rand() % 200 + 100; Teleport(pEntity, NULL, NULL, &velocity); /* Play a random sound */ if (params[3] && s_sound_count > 0) { char name[48]; const char *sound_name; cell_t player_list[256], total_players = 0; int maxClients = playerhelpers->GetMaxClients(); int r = (rand() % s_sound_count) + 1; snprintf(name, sizeof(name), "SlapSound%d", r); if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL) { IGamePlayer *other; for (int i=1; i<=maxClients; i++) { other = playerhelpers->GetGamePlayer(i); if (other->IsInGame()) { player_list[total_players++] = i; } } const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin(); CellRecipientFilter rf; rf.SetToReliable(true); rf.Initialize(player_list, total_players); engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos); } } if (!s_frag_offs) { const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags"); if (frag_prop) { datamap_t *pMap = gamehelpers->GetDataMap(pEntity); typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop); if (pType != NULL) { s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL]; } } if (!s_frag_offs) { s_frag_offs = -1; } } int old_frags = 0; if (s_frag_offs > 0) { old_frags = *(int *)((char *)pEntity + s_frag_offs); } /* Force suicide */ if (should_slay) { pluginhelpers->ClientCommand(pEdict, "kill\n"); } if (s_frag_offs > 0) { *(int *)((char *)pEntity + s_frag_offs) = old_frags; } return 1; }
bool SDKTools::ProcessCommandTarget(cmd_target_info_t *info) { IGamePlayer *pAdmin = info->admin ? playerhelpers->GetGamePlayer(info->admin) : NULL; if (strcmp(info->pattern, "@aim") == 0) { /* The server can't aim, of course. */ if (pAdmin == NULL) { return false; } int player_index; if ((player_index = GetClientAimTarget(pAdmin->GetEdict(), true)) < 1) { info->reason = COMMAND_TARGET_NONE; info->num_targets = 0; return true; } IGamePlayer *pTarget = playerhelpers->GetGamePlayer(player_index); if (pTarget == NULL) { info->reason = COMMAND_TARGET_NONE; info->num_targets = 0; return true; } info->reason = playerhelpers->FilterCommandTarget(pAdmin, pTarget, info->flags); if (info->reason != COMMAND_TARGET_VALID) { info->num_targets = 0; return true; } info->targets[0] = player_index; info->num_targets = 1; info->reason = COMMAND_TARGET_VALID; info->target_name_style = COMMAND_TARGETNAME_RAW; snprintf(info->target_name, info->target_name_maxlength, "%s", pTarget->GetName()); return true; } else if (strcmp(info->pattern, "@spec") == 0) { const char *teamname = tools_GetTeamName(1); if (strcasecmp(teamname, "spectator") != 0) return false; info->num_targets = 0; for (int i = 1; i <= playerhelpers->GetMaxClients(); i++) { IGamePlayer *player = playerhelpers->GetGamePlayer(i); if (player == NULL || !player->IsInGame()) continue; IPlayerInfo *plinfo = player->GetPlayerInfo(); if (plinfo == NULL) continue; if (plinfo->GetTeamIndex() == 1 && playerhelpers->FilterCommandTarget(pAdmin, player, info->flags) == COMMAND_TARGET_VALID) { info->targets[info->num_targets++] = i; } } info->reason = info->num_targets > 0 ? COMMAND_TARGET_VALID : COMMAND_TARGET_EMPTY_FILTER; info->target_name_style = COMMAND_TARGETNAME_ML; snprintf(info->target_name, info->target_name_maxlength, "all spectators"); return true; } return false; }