示例#1
0
static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
{
    if (params[1])
    {
        return playerhelpers->GetNumPlayers();
    }

    int maxplayers = playerhelpers->GetMaxClients();
    int count = 0;
    for (int i = 1; i <= maxplayers; ++i)
    {
        IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
        if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
        {
            count++;
        }
    }

    return (playerhelpers->GetNumPlayers() + count);
}
示例#2
0
static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
{
    int client = params[1];
    IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
    if (!pPlayer)
    {
        return pContext->ThrowNativeError("Client index %d is invalid", client);
    }
    if (!pPlayer->IsConnected())
    {
        return pContext->ThrowNativeError("Client %d is not connected", client);
    }

    AdminId id;
    if ((id = pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
    {
        return 0;
    }

    return adminsys->GetAdminFlags(id, Access_Effective);
}
示例#3
0
static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
{
    int client = params[1];
    IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
    if (!pPlayer)
    {
        return pContext->ThrowNativeError("Client index %d is invalid", client);
    }
    if (!pPlayer->IsConnected())
    {
        return pContext->ThrowNativeError("Client %d is not connected", client);
    }
    if (!adminsys->IsValidAdmin(params[2]) && params[2] != INVALID_ADMIN_ID)
    {
        return pContext->ThrowNativeError("AdminId %x is invalid", params[2]);
    }

    pPlayer->SetAdminId(params[2], params[3] ? true : false);

    return 1;
}
示例#4
0
static cell_t sm_GetStatCell(IPluginContext *pContext, const cell_t *params)
{
	ISteamGameServerStats *pStats = GetServerStatsPointer();

	if (pStats == NULL)
	{
		return 0;
	}

	int client = gamehelpers->ReferenceToIndex(params[1]);
	IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client); /* Man, including GameHelpers and PlayerHelpers for this native :(. */
	if (pPlayer == NULL || pPlayer->IsConnected() == false)
	{
		return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
	}
	
	char *pName;
	pContext->LocalToString(params[2], &pName);

	cell_t *pValue;
	pContext->LocalToPhysAddr(params[3], &pValue);
	CSteamID checkid = CreateCommonCSteamID(pPlayer, params, 4, 5);
	return pStats->GetUserStat(checkid, pName, pValue) ? 1 : 0;
}
示例#5
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;
}
示例#6
0
static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params)
{
	if (iserver == NULL)
	{
		return pContext->ThrowNativeError("IServer interface not supported, file a bug report.");
	}

	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
	IClient *pClient = iserver->GetClient(params[1] - 1);

	if (player == NULL || pClient == NULL)
	{
		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
	}
	if (!player->IsConnected())
	{
		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
	}

	static ValveCall *pCall = NULL;
	if (!pCall)
	{
		ValvePassInfo params[2];
		InitPass(params[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
		InitPass(params[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);

		if (!CreateBaseCall("SetUserCvar", ValveCall_Entity, NULL, params, 2, &pCall))
		{
			return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod");
		}
		else if (!pCall)
		{
			return pContext->ThrowNativeError("\"SetUserCvar\" wrapper failed to initialized");
		}
	}

/* TODO: Use UpdateUserSettings function for all engines */
#if SOURCE_ENGINE == SE_DARKMESSIAH
	static ValveCall *pUpdateSettings = NULL;
	if (!pUpdateSettings)
	{
		if (!CreateBaseCall("UpdateUserSettings", ValveCall_Entity, NULL, NULL, 0, &pUpdateSettings))
		{
			return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod");
		}
		else if (!pUpdateSettings)
		{
			return pContext->ThrowNativeError("\"SetUserCvar\" wrapper failed to initialized");
		}
	}
#else
	static int changedOffset = -1;

	if (changedOffset == -1)
	{	
		if (!g_pGameConf->GetOffset("InfoChanged", &changedOffset))
		{
			return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod");
		}
	}
#endif

	unsigned char *CGameClient = (unsigned char *)pClient - 4;

	START_CALL();
	/* Not really a CBaseEntity* but this works */
	CBaseEntity **ebuf = (CBaseEntity **)vptr;
	*ebuf = (CBaseEntity *)CGameClient;
	DECODE_VALVE_PARAM(2, vparams, 0);
	DECODE_VALVE_PARAM(3, vparams, 1);
	FINISH_CALL_SIMPLE(NULL);

#if SOURCE_ENGINE == SE_DARKMESSIAH
	unsigned char *args = pUpdateSettings->stk_get();
	*(void **)args = CGameClient;
	pUpdateSettings->call->Execute(args, NULL);
	pUpdateSettings->stk_put(args);
#else
	uint8_t* changed = (uint8_t *)(CGameClient + changedOffset);
	*changed = 1;
#endif

	return 1;
}
示例#7
0
static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authType, cell_t local_addr, size_t bytes, bool validate)
{
    pCtx->StringToLocal(local_addr, bytes, "STEAM_ID_STOP_IGNORING_RETVALS");

    if ((index < 1) || (index > playerhelpers->GetMaxClients()))
    {
        return pCtx->ThrowNativeError("Client index %d is invalid", index);
    }

    IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(index);
    if (!pPlayer->IsConnected())
    {
        return pCtx->ThrowNativeError("Client %d is not connected", index);
    }

    const char *authstr;

    switch (authType)
    {
    case AuthIdType::Engine:
        authstr = pPlayer->GetAuthString(validate);
        if (!authstr || authstr[0] == '\0')
        {
            return 0;
        }

        pCtx->StringToLocal(local_addr, bytes, authstr);
        break;
    case AuthIdType::Steam2:
        authstr = pPlayer->GetSteam2Id(validate);
        if (!authstr || authstr[0] == '\0')
        {
            return 0;
        }

        pCtx->StringToLocal(local_addr, bytes, authstr);
        break;
    case AuthIdType::Steam3:
        authstr = pPlayer->GetSteam3Id(validate);
        if (!authstr || authstr[0] == '\0')
        {
            return 0;
        }

        pCtx->StringToLocal(local_addr, bytes, authstr);
        break;

    case AuthIdType::SteamId64:
    {
        if (pPlayer->IsFakeClient() || gamehelpers->IsLANServer())
        {
            return 0;
        }

        uint64_t steamId = pPlayer->GetSteamId64(validate);
        if (steamId == 0)
        {
            return 0;
        }

        char szAuth[64];
        snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);

        pCtx->StringToLocal(local_addr, bytes, szAuth);
    }
    break;
    }

    return 1;
}
示例#8
0
static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
{
    int value;
    int client;
    int target;
    IGamePlayer *pTarget;
    AdminId aidTarget;
    const char *identity[2] = { "Console", "ADMIN" };

    client = params[1];
    target = params[2];

    if ((pTarget = playerhelpers->GetGamePlayer(target)) == NULL)
    {
        return pContext->ThrowNativeError("Invalid client index %d", target);
    }
    if (!pTarget->IsConnected())
    {
        return pContext->ThrowNativeError("Client %d not connected", target);
    }

    value = bridge->GetActivityFlags();

    if (client != 0)
    {
        IGamePlayer *pPlayer;

        if ((pPlayer = playerhelpers->GetGamePlayer(client)) == NULL)
        {
            return pContext->ThrowNativeError("Invalid client index %d", client);
        }
        if (!pPlayer->IsConnected())
        {
            return pContext->ThrowNativeError("Client %d not connected", client);
        }

        identity[0] = pPlayer->GetName();

        AdminId id = pPlayer->GetAdminId();
        if (id == INVALID_ADMIN_ID
                || !adminsys->GetAdminFlag(id, Admin_Generic, Access_Effective))
        {
            identity[1] = "PLAYER";
        }
    }

    int mode = 1;
    bool bShowActivity = false;

    if ((aidTarget = pTarget->GetAdminId()) == INVALID_ADMIN_ID
            || !adminsys->GetAdminFlag(aidTarget, Admin_Generic, Access_Effective))
    {
        /* Treat this as a normal user */
        if ((value & kActivityNonAdmins) || (value & kActivityNonAdminsNames))
        {
            if ((value & 2) || (target == client))
            {
                mode = 0;
            }
            bShowActivity = true;
        }
    }
    else
    {
        /* Treat this as an admin user */
        bool is_root = adminsys->GetAdminFlag(aidTarget, Admin_Root, Access_Effective);
        if ((value & kActivityAdmins)
                || (value & kActivityAdminsNames)
                || ((value & kActivityRootNames) && is_root))
        {
            if ((value & kActivityAdminsNames) || ((value & kActivityRootNames) && is_root) || (target == client))
            {
                mode = 0;
            }
            bShowActivity = true;
        }
    }

    /* Otherwise, send it back to the script. */
    pContext->StringToLocalUTF8(params[3], params[4], identity[mode], NULL);

    return bShowActivity ? 1 : 0;
}
示例#9
0
static cell_t _ShowActivity2(IPluginContext *pContext,
                             const cell_t *params,
                             const char *tag,
                             cell_t fmt_param)
{
    char message[255];
    char buffer[255];
    int value = bridge->GetActivityFlags();
    unsigned int replyto = playerhelpers->GetReplyTo();
    int client = params[1];

    const char *name = "Console";
    const char *sign = "ADMIN";
    if (client != 0)
    {
        IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
        if (!pPlayer || !pPlayer->IsConnected())
        {
            return pContext->ThrowNativeError("Client index %d is invalid", client);
        }
        name = pPlayer->GetName();
        AdminId id = pPlayer->GetAdminId();
        if (id == INVALID_ADMIN_ID
                || !adminsys->GetAdminFlag(id, Admin_Generic, Access_Effective))
        {
            sign = "PLAYER";
        }

        g_pSM->SetGlobalTarget(client);
        {
            DetectExceptions eh(pContext);
            g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
            if (eh.HasException())
                return 0;
        }

        /* We don't display directly to the console because the chat text
        * simply gets added to the console, so we don't want it to print
        * twice.
        */
        g_pSM->Format(message, sizeof(message), "%s%s", tag, buffer);
        gamehelpers->TextMsg(client, TEXTMSG_DEST_CHAT, message);
    }
    else
    {
        g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
        {
            DetectExceptions eh(pContext);
            g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
            if (eh.HasException())
                return 0;
        }

        g_pSM->Format(message, sizeof(message), "%s%s\n", tag, buffer);
        bridge->ConPrint(message);
    }

    if (value == kActivityNone)
    {
        return 1;
    }

    int maxClients = playerhelpers->GetMaxClients();
    for (int i = 1; i <= maxClients; i++)
    {
        IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
        if (!pPlayer->IsInGame()
                || pPlayer->IsFakeClient()
                || i == client)
        {
            continue;
        }
        AdminId id = pPlayer->GetAdminId();
        g_pSM->SetGlobalTarget(i);
        if (id == INVALID_ADMIN_ID
                || !adminsys->GetAdminFlag(id, Admin_Generic, Access_Effective))
        {
            /* Treat this as a normal user */
            if ((value & kActivityNonAdmins) || (value & kActivityNonAdminsNames))
            {
                const char *newsign = sign;
                if ((value & kActivityNonAdminsNames))
                {
                    newsign = name;
                }

                {
                    DetectExceptions eh(pContext);
                    g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
                    if (eh.HasException())
                        return 0;
                }

                g_pSM->Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
                gamehelpers->TextMsg(i, TEXTMSG_DEST_CHAT, message);
            }
        }
        else
        {
            /* Treat this as an admin user */
            bool is_root = adminsys->GetAdminFlag(id, Admin_Root, Access_Effective);
            if ((value & kActivityAdmins)
                    || (value & kActivityAdminsNames)
                    || ((value & kActivityRootNames) && is_root))
            {
                const char *newsign = sign;
                if ((value & kActivityAdminsNames) || ((value & kActivityRootNames) && is_root))
                {
                    newsign = name;
                }

                {
                    DetectExceptions eh(pContext);
                    g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, fmt_param);
                    if (eh.HasException())
                        return 0;
                }

                g_pSM->Format(message, sizeof(message), "%s%s: %s", tag, newsign, buffer);
                gamehelpers->TextMsg(i, TEXTMSG_DEST_CHAT, message);
            }
        }
    }

    return 1;
}