void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{
	sp_native_t *native;
	uint32_t i, native_count;
	IPluginContext *pContext;

	pContext = pPlugin->GetBaseContext();

	/* Generate a new serial ID, mark our dependencies with it. */
	g_mark_serial++;
	pPlugin->PropagateMarkSerial(g_mark_serial);

	native_count = pContext->GetNativesNum();
	for (i = 0; i < native_count; i++)
	{
		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
			continue;

		// If we're already bound, no need to do anything else.
		if (native->status == SP_NATIVE_BOUND)
			continue;

		/* Otherwise, the native must be in our cache. */
		Ref<Native> pEntry = FindNative(native->name);
		if (!pEntry)
			continue;

		if (bCoreOnly && pEntry->owner != &g_CoreNatives)
			continue;

		BindNativeToPlugin(pPlugin, native, i, pEntry);
	}
}
Exemple #2
0
void CNativeOwner::UnbindWeakRef(const WeakNative &ref)
{
    IPluginContext *pContext;

    pContext = ref.pl->GetBaseContext();
    pContext->GetRuntime()->UpdateNativeBinding(
        ref.idx,
        nullptr,
        0,
        nullptr);
}
Exemple #3
0
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{
	NativeEntry *pEntry;
	sp_native_t *native;
	uint32_t i, native_count;
	IPluginContext *pContext;

	pContext = pPlugin->GetBaseContext();

	/* Generate a new serial ID, mark our dependencies with it. */
	g_mark_serial++;
	pPlugin->PropogateMarkSerial(g_mark_serial);

	native_count = pContext->GetNativesNum();
	for (i = 0; i < native_count; i++)
	{
		if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
		{
			continue;
		}

		/* If we're bound, check if there is a replacement available.  
		 * If not, this native is totally finalized.
		 */
		if (native->status == SP_NATIVE_BOUND)
		{
			pEntry = (NativeEntry *)native->user;
			assert(pEntry != NULL);
			if (pEntry->replacement.owner == NULL
				|| (pEntry->replacement.owner != NULL 
				&&  pEntry->replacement.func == native->pfn))
			{
				continue;
			}
		}
		/* Otherwise, the native must be in our cache. */
		else if ((pEntry = FindNative(native->name)) == NULL)
		{
			continue;
		}

		if (bCoreOnly && pEntry->owner != g_pCoreNatives)
		{
			continue;
		}

		BindNativeToPlugin(pPlugin, native, i, pEntry);
	}
}
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref<Native> &entry)
{
	if (!entry->owner)
		return;

	IPluginContext *pContext = pPlugin->GetBaseContext();

	uint32_t i;
	if (pContext->FindNativeByName(entry->name(), &i) != SP_ERROR_NONE)
		return;

	sp_native_t *native;
	if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
		return;

	if (native->status == SP_NATIVE_BOUND)
		return;

	BindNativeToPlugin(pPlugin, native, i, entry);
}
char * GetMyinfoVar(char *var)
{
    unsigned int idx = NULL;
    if (strcmp(var, "name") == 0)
        idx = cinfo->name;
    else if (strcmp(var, "description") == 0)
        idx = cinfo->description;
    else if (strcmp(var, "author") == 0)
        idx = cinfo->author;
    else if (strcmp(var, "version") == 0)
        idx = cinfo->version;
    else if (strcmp(var, "url") == 0)
        idx = cinfo->url;

    char *value = new char[512];
    IPluginContext *ctx = g_Plugin->GetDefaultContext();
    ctx->LocalToString(idx, (char **)&value);

    return value;
}
Exemple #6
0
int sort2d_amx_custom(const void *elem1, const void *elem2)
{
    cell_t c1 = *(cell_t *)elem1;
    cell_t c2 = *(cell_t *)elem2;

    cell_t c1_addr = g_SortInfo.array_addr + (c1 * sizeof(cell_t)) + g_SortInfo.array_remap[c1];
    cell_t c2_addr = g_SortInfo.array_addr + (c2 * sizeof(cell_t)) + g_SortInfo.array_remap[c2];

    IPluginContext *pContext = g_SortInfo.pFunc->GetParentContext();
    cell_t *c1_r, *c2_r;
    pContext->LocalToPhysAddr(c1_addr, &c1_r);
    pContext->LocalToPhysAddr(c2_addr, &c2_r);

    cell_t result = 0;
    g_SortInfo.pFunc->PushCell(c1_addr);
    g_SortInfo.pFunc->PushCell(c2_addr);
    g_SortInfo.pFunc->PushCell(g_SortInfo.array_addr);
    g_SortInfo.pFunc->PushCell(g_SortInfo.hndl);
    g_SortInfo.pFunc->Execute(&result);

    return result;
}
Exemple #7
0
void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist)
{
	List<CmdHook *>::iterator iter = cmdlist.begin();

	while (iter != cmdlist.end())
	{
		CmdHook *pHook = (*iter);
		IPluginContext *pContext = pHook->pf->GetParentContext();
		IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
		CmdList *pList = NULL;
		
		//gaben
		if (!pPlugin->GetProperty("CommandList", (void **)&pList, false) || !pList)
		{
			continue;
		}

		CmdList::iterator p_iter = pList->begin();
		while (p_iter != pList->end())
		{
			PlCmdInfo &cmd = (*p_iter);
			if (cmd.pHook == pHook)
			{
				p_iter = pList->erase(p_iter);
			}
			else
			{
				p_iter++;
			}
		}

		delete pHook->pAdmin;
		delete pHook;
		
		iter = cmdlist.erase(iter);
	}
}
Exemple #8
0
void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
{
	/* Whoa, first get its information struct */
	ConCmdInfo *pInfo;

	if (!m_Cmds.retrieve(name, &pInfo))
		return;

	CmdHookList::iterator iter = pInfo->hooks.begin();
	while (iter != pInfo->hooks.end())
	{
		CmdHook *hook = *iter;

		IPluginContext *pContext = hook->pf->GetParentContext();
		IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());

		// The list is guaranteed to exist.
		PluginHookList *list;
		pPlugin->GetProperty("CommandList", (void **)&list, false);
		for (PluginHookList::iterator hiter = list->begin(); hiter != list->end(); hiter++)
		{
			if (*hiter == hook)
			{
				list->erase(hiter);
				break;
			}
		}

		if (hook->admin)
			hook->admin->group->hooks.remove(hook);

		iter = pInfo->hooks.erase(iter);
		delete hook;
	}

	RemoveConCmd(pInfo, name, is_read_safe, false);
}
void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction)
{
	ConVarInfo *pInfo;
	IChangeableForward *pForward;
	IPluginContext *pContext = pFunction->GetParentContext();

	/* Find the convar in the lookup trie */
	if (convar_cache_lookup(pConVar->GetName(), &pInfo))
	{
		/* Get the forward */
		pForward = pInfo->pChangeForward;

		/* If the forward doesn't exist, we can't unhook anything */
		if (!pForward)
		{
			pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName());
			return;
		}

		/* Remove the function from the forward's list */
		if (!pForward->RemoveFunction(pFunction))
		{
			pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", pConVar->GetName());
			return;
		}

		/* If the forward now has 0 functions in it... */
		if (pForward->GetFunctionCount() == 0 &&
			!ConVarReentrancyGuard::IsCvarInChain(pConVar))
		{
			/* Free this forward */
			forwardsys->ReleaseForward(pForward);
			pInfo->pChangeForward = NULL;
		}
	}
}
Exemple #10
0
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
{
	uint32_t i;
	sp_native_t *native;
	IPluginContext *pContext;

	pContext = pPlugin->GetBaseContext();

	if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
	{
		return;
	}
	if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
	{
		return;
	}

	if (native->status == SP_NATIVE_BOUND)
	{
		return;
	}

	BindNativeToPlugin(pPlugin, native, i, pEntry);
}
int NativeInvoker::Invoke(cell_t *result)
{
	int err = SP_ERROR_NONE;

	if (pContext == NULL)
	{
		return SP_ERROR_INVALID_NATIVE;
	}

	if (m_errorstate != SP_ERROR_NONE)
	{
		err = m_errorstate;
		Cancel();
		return err;
	}

	cell_t tresult;

	if (result == NULL)
	{
		result = &tresult;
	}

	//This is for re-entrancy!
	IPluginContext *ctx = pContext;
	cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
	cell_t *temp_params = &_temp_params[1];
	ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
	unsigned int numparams = m_curparam;
	unsigned int i;
	bool docopies = true;

	if (numparams)
	{
		//Save the info locally, then reset it for re-entrant calls.
		memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
	}
	m_curparam = 0;
	pContext = NULL;

	/* Initialize 0th parameter */
	_temp_params[0] = numparams;

	/* Browse the parameters and build arrays */
	for (i = 0; i < numparams; i++)
	{
		/* Is this marked as an array? */
		if (temp_info[i].marked)
		{
			if (!temp_info[i].str.is_sz)
			{
				/* Allocate a normal/generic array */
				if ((err = ctx->HeapAlloc(temp_info[i].size, 
										  &temp_info[i].local_addr,
										  &temp_info[i].phys_addr))
					!= SP_ERROR_NONE)
				{
					break;
				}
				if (temp_info[i].orig_addr)
				{
					memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
				}
			}
			else
			{
				/* Calculate cells required for the string */
				size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);

				/* Allocate the buffer */
				if ((err = ctx->HeapAlloc(cells,
										  &temp_info[i].local_addr,
										  &temp_info[i].phys_addr))
					!= SP_ERROR_NONE)
				{
					break;
				}
				/* Copy original string if necessary */
				if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
				{
					/* Cut off UTF-8 properly */
					if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
					{
						if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr, 
														  temp_info[i].size, 
														  (const char *)temp_info[i].orig_addr,
														  NULL))
							!= SP_ERROR_NONE)
						{
							break;
						}
					}
					/* Copy a binary blob */
					else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
					{
						memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
					}
					/* Copy ASCII characters */
					else
					{
						if ((err = ctx->StringToLocal(temp_info[i].local_addr,
													  temp_info[i].size,
													  (const char *)temp_info[i].orig_addr))
							!= SP_ERROR_NONE)
						{
							break;
						}
					}
				}
			} /* End array/string calculation */
			/* Update the pushed parameter with the byref local address */
			temp_params[i] = temp_info[i].local_addr;
		}
		else
		{
			/* Just copy the value normally */
			temp_params[i] = m_params[i];
		}
	}

	/* Make the call if we can */
	if (err == SP_ERROR_NONE)
	{
		*result = native(ctx, _temp_params);
		if (ctx->GetLastNativeError() != SP_ERROR_NONE)
		{
			docopies = false;
			ctx->ClearLastNativeError();
		}
	}
	else
	{
		docopies = false;
	}

	/* i should be equal to the last valid parameter + 1 */
	while (i--)
	{
		if (!temp_info[i].marked)
		{
			continue;
		}

		if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
		{
			if (temp_info[i].orig_addr)
			{
				if (temp_info[i].str.is_sz)
				{
					memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);

				}
				else
				{
					if (temp_info[i].size == 1)
					{
						*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
					}
					else
					{
						memcpy(temp_info[i].orig_addr, 
							temp_info[i].phys_addr, 
							temp_info[i].size * sizeof(cell_t));
					}
				}
			}
		}

		if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
		{
			return err;
		}
	}

	return err;
}
Exemple #12
0
void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results)
{
    if (!m_pVoteResults)
    {
        /* Call MenuAction_VoteEnd instead.  See if there are any extra winners. */
        unsigned int num_items = 1;
        for (unsigned int i=1; i<results->num_items; i++)
        {
            if (results->item_list[i].count != results->item_list[0].count)
            {
                break;
            }
            num_items++;
        }

        /* See if we need to pick a random winner. */
        unsigned int winning_item;
        if (num_items > 1)
        {
            /* Yes, we do. */
            srand(time(NULL));
            winning_item = rand() % num_items;
            winning_item = results->item_list[winning_item].item;
        } else {
            /* No, take the first. */
            winning_item = results->item_list[0].item;
        }

        unsigned int total_votes = results->num_votes;
        unsigned int winning_votes = results->item_list[0].count;

        DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF));
    } else {
        IPluginContext *pContext = m_pVoteResults->GetParentContext();
        bool no_call = false;
        int err;

        /* First array */
        cell_t client_array_address = -1;
        cell_t *client_array_base = NULL;
        cell_t client_array_size = results->num_clients + (results->num_clients * 2);
        if (client_array_size)
        {
            if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base))
                    != SP_ERROR_NONE)
            {
                logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
                no_call = true;
            } else {
                cell_t target_offs = sizeof(cell_t) * results->num_clients;
                cell_t *cur_index = client_array_base;
                cell_t *cur_array;
                for (unsigned int i=0; i<results->num_clients; i++)
                {
                    /* Copy the array index */
                    *cur_index = target_offs;
                    /* Get the current array address */
                    cur_array = (cell_t *)((char *)cur_index + target_offs);
                    /* Store information */
                    cur_array[0] = results->client_list[i].client;
                    cur_array[1] = results->client_list[i].item;
                    /* Adjust for the new target by subtracting one indirection
                     * and adding one array.
                     */
                    target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
                    cur_index++;
                }
            }
        }

        /* Second array */
        cell_t item_array_address = -1;
        cell_t *item_array_base = NULL;
        cell_t item_array_size = results->num_items + (results->num_items * 2);
        if (item_array_size)
        {
            if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
                    != SP_ERROR_NONE)
            {
                logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
                no_call = true;
            } else {
                cell_t target_offs = sizeof(cell_t) * results->num_items;
                cell_t *cur_index = item_array_base;
                cell_t *cur_array;
                for (unsigned int i=0; i<results->num_items; i++)
                {
                    /* Copy the array index */
                    *cur_index = target_offs;
                    /* Get the current array address */
                    cur_array = (cell_t *)((char *)cur_index + target_offs);
                    /* Store information */
                    cur_array[0] = results->item_list[i].item;
                    cur_array[1] = results->item_list[i].count;
                    /* Adjust for the new target by subtracting one indirection
                     * and adding one array.
                     */
                    target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
                    cur_index++;
                }
            }
        }

        /* Finally, push everything */
        if (!no_call)
        {
            m_pVoteResults->PushCell(menu->GetHandle());
            m_pVoteResults->PushCell(results->num_votes);
            m_pVoteResults->PushCell(results->num_clients);
            m_pVoteResults->PushCell(client_array_address);
            m_pVoteResults->PushCell(results->num_items);
            m_pVoteResults->PushCell(item_array_address);
            m_pVoteResults->Execute(NULL);
        }

        /* Free what we allocated, in reverse order as required */
        if (item_array_address != -1)
        {
            pContext->HeapPop(item_array_address);
        }
        if (client_array_address != -1)
        {
            pContext->HeapPop(client_array_address);
        }
    }
}