Ejemplo n.º 1
0
// native Array:ArrayClone(Array:which);
static cell AMX_NATIVE_CALL ArrayClone(AMX* amx, cell* params)
{
	CellArray* vec = HandleToVector(amx, params[1]);

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

	CellArray *clonevec = vec->clone();

	// Scan through the vector list to see if any are NULL.
	// NULL means the vector was previously destroyed.
	for (unsigned int i = 0; i < VectorHolder.length(); ++i)
	{
		if (VectorHolder[i] == NULL)
		{
			VectorHolder[i] = clonevec;
			return i + 1;
		}
	}

	VectorHolder.append(clonevec);

	return VectorHolder.length();
}
Ejemplo n.º 2
0
void
genheapfree(int stop_id)
{
  for (size_t i = sHeapScopes.length() - 1; i < sHeapScopes.length(); i--) {
    const MemoryScope& scope = sHeapScopes[i];
    if (scope.scope_id <= stop_id)
      break;
    modheap_for_scope(scope);
  }
}
Ejemplo n.º 3
0
void
genstackfree(int stop_id)
{
  for (size_t i = sStackScopes.length() - 1; i < sStackScopes.length(); i--) {
    const MemoryScope& scope = sStackScopes[i];
    if (scope.scope_id <= stop_id)
      break;
    modstk_for_scope(scope);
  }
}
Ejemplo n.º 4
0
int GetPEL()
{
	for (int i=0; i<(int)PEL.length(); i++)
	{
		if (PEL[i]->isFree())
			return i;
	}

	RegEx *x = new RegEx();
	PEL.append(x);

	return (int)PEL.length() - 1;
}
Ejemplo n.º 5
0
//Makes a new menu handle (-1 for failure)
//native csdm_makemenu(title[]);
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
{
	int len;
	char *title = get_amxstring(amx, params[1], 0, len);
	validate_menu_text(title);
	char *handler = get_amxstring(amx, params[2], 1, len);

	int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
	
	if (func == -1)
	{
		LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
		return 0;
	}

	Menu *pMenu = new Menu(title, amx, func);

	if (g_MenuFreeStack.empty())
	{
		g_NewMenus.append(pMenu);
		pMenu->thisId = (int)g_NewMenus.length() - 1;
	} else {
		int pos = g_MenuFreeStack.front();
		g_MenuFreeStack.pop();
		g_NewMenus[pos] = pMenu;
		pMenu->thisId = pos;
	}

	return pMenu->thisId;
}
Ejemplo n.º 6
0
// native regex_substr(Regex:id, str_id, buffer[], maxLen);
static cell AMX_NATIVE_CALL regex_substr(AMX *amx, cell *params)
{
	int id = params[1]-1;
	if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree())
	{
		MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id);
		return 0;
	}

	RegEx *x = PEL[id];
	static char buffer[16384]; // Same as AMXX buffer.

	size_t length;
	size_t maxLength = ke::Min<size_t>(params[4], sizeof(buffer) - 1);

	const char *ret = x->GetSubstring(params[2], buffer, maxLength, &length);

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

	if (length >= maxLength && ret[length - 1] & 1 << 7)
	{
		maxLength -= UTIL_CheckValidChar((char *)ret + length - 1);
	}

	MF_SetAmxString(amx, params[3], ret, maxLength);

	return 1;
}
Ejemplo n.º 7
0
Menu *get_menu_by_id(int id)
{
	if (id < 0 || size_t(id) >= g_NewMenus.length() || !g_NewMenus[id])
		return NULL;

	return g_NewMenus[id];
}
Ejemplo n.º 8
0
//native regex_replace(Regex:pattern, string[], maxLen, const replace[], flags = REGEX_FORMAT_DEFAULT, &errcode = 0);
static cell AMX_NATIVE_CALL regex_replace(AMX *amx, cell *params)
{
	int id = params[1] - 1;
	if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree())
	{
		MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id);
		return 0;
	}

	int textLen, replaceLen;
	char *text = MF_GetAmxString(amx, params[2], 0, &textLen);
	const char *replace = MF_GetAmxString(amx, params[4], 1, &replaceLen);

	cell *erroCode = MF_GetAmxAddr(amx, params[6]);

	RegEx *x = PEL[id]; 
	int e = x->Replace(text, params[3] + 1, replace, replaceLen, params[5]);

	if (e == -1)
	{
		*erroCode = x->mErrorOffset;
		x->ClearMatch();
		return -2;
	}
	else if (e == 0)
	{
		*erroCode = 0;
		x->ClearMatch();
		return 0;
	}

	MF_SetAmxString(amx, params[2], text, params[3]);

	return e;
}
Ejemplo n.º 9
0
void pfnTouch(edict_t *pToucher, edict_t *pTouched)
{
	unsigned int i = 0;
	int retVal = 0;
	const char *ptrClass = STRING(pToucher->v.classname);
	const char *ptdClass = STRING(pTouched->v.classname);
	int ptrIndex = ENTINDEX(pToucher);
	int ptdIndex = ENTINDEX(pTouched);
	META_RES res=MRES_IGNORED;
	for (i=0; i<Touches.length(); i++)
	{
		if (Touches[i]->Toucher.isVoid())
		{
			if (Touches[i]->Touched.isVoid())
			{
				retVal = MF_ExecuteForward(Touches[i]->Forward, (cell)ptrIndex, (cell)ptdIndex);
				if (retVal & 2/*PLUGIN_HANDLED_MAIN*/)
					RETURN_META(MRES_SUPERCEDE);
				else if (retVal)
					res=MRES_SUPERCEDE;
			} else if (Touches[i]->Touched.compare(ptdClass)==0) {
				retVal = MF_ExecuteForward(Touches[i]->Forward, (cell)ptrIndex, (cell)ptdIndex);
				if (retVal & 2/*PLUGIN_HANDLED_MAIN*/)
					RETURN_META(MRES_SUPERCEDE);
				else if (retVal)
					res=MRES_SUPERCEDE;
			}
		} else if (Touches[i]->Toucher.compare(ptrClass)==0) {
			if (Touches[i]->Touched.isVoid())
			{
				retVal = MF_ExecuteForward(Touches[i]->Forward, (cell)ptrIndex, (cell)ptdIndex);
				if (retVal & 2/*PLUGIN_HANDLED_MAIN*/)
					RETURN_META(MRES_SUPERCEDE);
				else if (retVal)
					res=MRES_SUPERCEDE;
			} else if (Touches[i]->Touched.compare(ptdClass)==0) {
				retVal = MF_ExecuteForward(Touches[i]->Forward, (cell)ptrIndex, (cell)ptdIndex);
				if (retVal & 2/*PLUGIN_HANDLED_MAIN*/)
					RETURN_META(MRES_SUPERCEDE);
				else if (retVal)
					res=MRES_SUPERCEDE;
			}
		}
	}
	/* Execute pfnTouch forwards */
	if (pfnTouchForward != -1) {
		retVal = MF_ExecuteForward(pfnTouchForward, (cell)ptrIndex, (cell)ptdIndex);
		if (retVal)
			RETURN_META(MRES_SUPERCEDE);
	}
	if (VexdTouchForward != -1) {
		retVal = MF_ExecuteForward(VexdTouchForward, (cell)ptrIndex, (cell)ptdIndex);
		if (retVal)
			RETURN_META(MRES_SUPERCEDE);
	}

	RETURN_META(res);
}
Ejemplo n.º 10
0
void ClearPluginLibraries()
{
	ClearLibraries(LibSource_Plugin);
	for (size_t i=0; i<g_RegNatives.length(); i++)
	{
		delete [] g_RegNatives[i]->pfn;
		delete g_RegNatives[i];
	}
	g_RegNatives.clear();
}
Ejemplo n.º 11
0
void OnAmxxDetach()
{
	for (int i = 0; i<(int)PEL.length(); i++)
	{
		if (PEL[i])
		{
			delete PEL[i];
			PEL[i] = 0;
		}
	}

	PEL.clear();
}
Ejemplo n.º 12
0
void ClearMenus()
{
	for (size_t i = 0; i < g_NewMenus.length(); i++)
	{
		delete g_NewMenus[i];
	}
	
	g_NewMenus.clear();
	while (!g_MenuFreeStack.empty())
	{
		g_MenuFreeStack.pop();
	}
}
Ejemplo n.º 13
0
// Array:ArrayCreate(cellsize=1, reserved=32);
static cell AMX_NATIVE_CALL ArrayCreate(AMX* amx, cell* params)
{
	// params[1] (cellsize) is how big in cells each element is.
	// this MUST be greater than 0!
	int cellsize = params[1];

	// params[2] (reserved) is how many elements to allocate
	// immediately when the list is created.
	int reserved = params[2];

	if (cellsize <= 0)
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid array size (%d)", cellsize);
		return -1;
	}

	if (reserved < 0)
	{
		reserved = 0;
	}

	// Scan through the vector list to see if any are NULL.
	// NULL means the vector was previously destroyed.
	for (unsigned int i=0; i < VectorHolder.length(); ++i)
	{
		if (VectorHolder[i]==NULL)
		{
			VectorHolder[i] = new CellArray(cellsize, reserved);
			return i + 1;
		}
	}

	// None are NULL, create a new vector
	CellArray* NewVector = new CellArray(cellsize, reserved);
	
	VectorHolder.append(NewVector);

	return VectorHolder.length();
}
Ejemplo n.º 14
0
//register_native(const name[], const handler[])
static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
{
	if (!g_Initialized)
		amxx_DynaInit((void *)(amxx_DynaCallback));

	g_Initialized = true;

	int len;
	char *name = get_amxstring(amx, params[1], 0, len);
	char *func = get_amxstring(amx, params[2], 1, len);

	int idx, err;
	if ( (err=amx_FindPublic(amx, func, &idx)) != AMX_ERR_NONE)
	{
		LogError(amx, err, "Function \"%s\" was not found", func);
		return 0;
	}

	regnative *pNative = new regnative;
	pNative->amx = amx;
	pNative->func = idx;
	
	//we'll apply a safety buffer too
	//make our function
	int size = amxx_DynaCodesize();
#if defined(_WIN32)
	DWORD temp;
	pNative->pfn = new char[size + 10];
	VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
#elif defined(__GNUC__)
# if defined(__APPLE__)
	pNative->pfn = (char *)valloc(size+10);
# else
	pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
# endif
	mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
#endif

	int id = (int)g_RegNatives.length();
	
	amxx_DynaMake(pNative->pfn, id);
	pNative->func = idx;
	pNative->style = params[3];

	g_RegNatives.append(pNative);

	pNative->name = name;

	return 1;
}
Ejemplo n.º 15
0
AMX_NATIVE_INFO *BuildNativeTable()
{
	if (g_RegNatives.length() < 1)
	{
		return NULL;
	}

	AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.length() + 1];

	AMX_NATIVE_INFO info;
	regnative *pNative;
	for (size_t i=0; i<g_RegNatives.length(); i++)
	{
		pNative = g_RegNatives[i];
		info.name = pNative->name.chars();
		info.func = (AMX_NATIVE)((void *)(pNative->pfn));
		pNatives[i] = info;
	}
	pNatives[g_RegNatives.length()].name = NULL;
	pNatives[g_RegNatives.length()].func = NULL;

	//this needs to be deleted
	return pNatives;
}
Ejemplo n.º 16
0
cell match_c(AMX *amx, cell *params, bool all)
{
	int id = params[2] - 1;

	if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree())
	{
		MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id);
		return 0;
	}

	int len;
	const char *str = MF_GetAmxString(amx, params[1], 0, &len);
	cell *errorCode = MF_GetAmxAddr(amx, params[3]);

	RegEx *x = PEL[id];

	int e;
	if (all)
		e = x->MatchAll(str);
	else
		e = x->Match(str);

	if (e == -1)
	{
		/* there was a match error.  move on. */
		*errorCode = x->mErrorOffset;

		/* only clear the match results, since the regex object
		may still be referenced later */
		x->ClearMatch();
		return -2;
	}
	else if (e == 0) 
	{
		*errorCode = 0;

		/* only clear the match results, since the regex object
		may still be referenced later */
		x->ClearMatch();
		return 0;
	}
	else 
	{
		*errorCode = x->Count();
		return x->Count();
	}
}
Ejemplo n.º 17
0
static cell AMX_NATIVE_CALL regex_free(AMX *amx, cell *params)
{
	cell *c = MF_GetAmxAddr(amx, params[1]);
	int id = *c;
	*c = 0;
	id -= 1;
	if (id >= (int)PEL.length() || id < 0 || PEL[id]->isFree())
	{
		MF_LogError(amx, AMX_ERR_NATIVE, "Invalid regex handle %d", id);
		return 0;
	}

	RegEx *x = PEL[id];
	x->Clear();

	return 1;
}
Ejemplo n.º 18
0
static cell AMX_NATIVE_CALL free_kvd(AMX *amx, cell *params) {
    if (params[1] == 0) {
        return 0;
    }

    KVD_Wrapper *kvdw = reinterpret_cast<KVD_Wrapper *>(params[1]);

    for (size_t i = 0; i < g_KVDWs.length(); ++i) {
        if (g_KVDWs[i] == kvdw) {
            g_KVDWs.remove(i);
            g_FreeKVDWs.append(kvdw);

            return 1;
        }
    }

    return 0;
}
Ejemplo n.º 19
0
void CmdStart(const edict_t *player, const struct usercmd_s *_cmd, unsigned int random_seed)
{
	unsigned int i = 0;
	int retVal = 0;
	edict_t *pEntity = (edict_t *)player;
	g_cmd = (struct usercmd_s *)_cmd;
	int origImpulse = g_cmd->impulse; // incase a plugin alters it
	for (i=0; i<Impulses.length(); i++)
	{
		if (Impulses[i]->Check == g_cmd->impulse)
		{
			retVal = MF_ExecuteForward(Impulses[i]->Forward, (cell)ENTINDEX(pEntity), (cell)origImpulse);
			
			// don't return SUPERCEDE in any way here, 
			// we don't want to break client_impulse forward and access to cmd with [g/s]et_usercmd
			if (retVal)
				g_cmd->impulse = 0;
		}
	}

	// client_impulse
	if (ClientImpulseForward != -1 && origImpulse != 0) 
	{
		retVal = MF_ExecuteForward(ClientImpulseForward, (cell)ENTINDEX(pEntity), (cell)origImpulse);

		if (retVal)
			g_cmd->impulse = 0;
	}

	// client_CmdStart
	if (CmdStartForward != -1)
	{
		incmd = true;
		retVal = MF_ExecuteForward(CmdStartForward, (cell)ENTINDEX(pEntity));
		incmd = false;

		if (retVal)
			RETURN_META(MRES_SUPERCEDE);
	}

	RETURN_META(MRES_IGNORED);
}
Ejemplo n.º 20
0
void Think(edict_t *pent)
{
	unsigned int i = 0;
	const char *cls = STRING(pent->v.classname);
	META_RES res=MRES_IGNORED;
	int retVal=0;
	for (i=0; i<Thinks.length(); i++)
	{
		if (Thinks[i]->Class.compare(cls)==0)
		{
			retVal=MF_ExecuteForward(Thinks[i]->Forward, (cell)ENTINDEX(pent));
			if (retVal & 2/*PLUGIN_HANDLED_MAIN*/)
				RETURN_META(MRES_SUPERCEDE);
			else if (retVal)
				res=MRES_SUPERCEDE;
		}
	}
	retVal=MF_ExecuteForward(pfnThinkForward, (cell)ENTINDEX(pent));
	if (retVal)
		res=MRES_SUPERCEDE;

	RETURN_META(res);
}
Ejemplo n.º 21
0
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
{
	if (idx < 0 || idx >= (int)g_RegNatives.length())
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
		return 0;
	}

	regnative *pNative = g_RegNatives[idx];
	int numParams = params[0] / sizeof(cell);

	if (numParams > CALLFUNC_MAXPARAMS)
	{
		LogError(amx, AMX_ERR_NATIVE, "Called dynanative with too many parameters (%d)", CALLFUNC_MAXPARAMS);
		return 0;
	}

	CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
	CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);

	if (!pNativePlugin->isExecutable(pNative->func))
	{
		LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
		pPlugin->setStatus(ps_paused);
		return 0;
	}

	/* Save old values on ZE STACK */
	AMX *pSaveCaller = g_pCaller;
	cell saveParams[CALLFUNC_MAXPARAMS];
	regnative *pSaveNative = g_pCurNative;
	int saveError = g_CurError;

	if (pSaveNative)
	{
		for (ucell i = 0; i <= g_Params[0] / sizeof(cell); i++)
		{
			saveParams[i] = g_Params[i];
		}
	}

	/* Save current info */
	g_CurError = AMX_ERR_NONE;
	g_pCaller = amx;
	g_pCurNative = pNative;

	int err = 0;
	cell ret = 0;
	if (pNative->style == 0)
	{
		amx_Push(pNative->amx, numParams);
		amx_Push(pNative->amx, pPlugin->getId());
		for (int i=numParams; i>=0; i--)
		{
			g_Params[i] = params[i];
		}
	} else if (pNative->style == 1) {
		/**
		 * use dJeyL's system .. very clever!
		 * NOTE: clever, but doesn't work at all since the JIT does bounds checking
		 * this should REALLY be deprecated
		 */
		for (int i=numParams; i>=1; i--)
		{
			amx_Push(pNative->amx, params[i]);
		}
	}

	Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
	if (pDebugger)
	{
		pDebugger->BeginExec();
	}

	err=amx_Exec(pNative->amx, &ret, pNative->func);

	if (err != AMX_ERR_NONE)
	{
		if (pDebugger && pDebugger->ErrorExists())
		{
			//don't care
		} else if (err != -1) {
			//nothing logged the error
			LogError(pNative->amx, err, NULL);
		}
		pNative->amx->error = AMX_ERR_NONE;
		//furthermore, log an error in the parent plugin.
		LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
	} else if (g_CurError != AMX_ERR_NONE) {
		LogError(amx, g_CurError, g_errorStr);
	}

	if (pDebugger)
	{
		pDebugger->EndExec();
	}

	/* Restore everything */
	g_pCurNative = pSaveNative;
	g_CurError = saveError;
	g_pCaller = pSaveCaller;
	if (pSaveNative)
	{
		for (ucell i = 0; i <= saveParams[0] / sizeof(cell); i++)
		{
			g_Params[i] = saveParams[i];
		}
	}

	return ret;
}
Ejemplo n.º 22
0
static cell AMX_NATIVE_CALL set_kvd(AMX *amx, cell *params)
{
    KVD_Wrapper *kvdw = nullptr;
    KeyValueData *kvd = nullptr;

    KVD_Wrapper *tmpw = reinterpret_cast<KVD_Wrapper *>(params[1]);
    if (params[1] == 0 || tmpw == &g_kvd_glb) {
        kvdw = &g_kvd_glb;
        kvd = &(kvdw->kvd);
    } else {
        for (size_t i = 0; i < g_KVDWs.length(); ++i) {
            if (g_KVDWs[i] == tmpw) {
                kvdw = tmpw;
                kvd = &(kvdw->kvd);
            }
        }

        if (kvdw == nullptr) {
            kvdw = &g_kvd_ext;
            kvd = reinterpret_cast<KeyValueData *>(tmpw);
        }
    }

    if (*params / sizeof(cell) < 3)
    {
        MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
        return 0;
    }

    cell *ptr = MF_GetAmxAddr(amx, params[3]);
    int len;

    switch (params[2])
    {
    case KV_fHandled:
    {
        kvd->fHandled = (int)*ptr;
        return 1;
        break;
    }
    case KV_ClassName:
    {
        kvdw->cls = MF_GetAmxString(amx, params[3], 0, &len);
        kvd->szClassName = const_cast<char *>(kvdw->cls.chars());
        return 1;
        break;
    }
    case KV_KeyName:
    {
        kvdw->key = MF_GetAmxString(amx, params[3], 0, &len);
        kvd->szKeyName = const_cast<char *>(kvdw->key.chars());
        return 1;
        break;
    }
    case KV_Value:
    {
        kvdw->val = MF_GetAmxString(amx, params[3], 0, &len);
        kvd->szValue = const_cast<char *>(kvdw->val.chars());
        return 1;
        break;
    }
    }

    MF_LogError(amx, AMX_ERR_NATIVE, "Invalid KeyValueData member: %d", params[2]);

    return 0;
}