Beispiel #1
0
static void
EnterMemoryScope(ke::Vector<MemoryScope>& frame)
{
  if (frame.empty())
    frame.append(MemoryScope{0});
  else
    frame.append(MemoryScope{frame.back().scope_id + 1});
}
Beispiel #2
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;
}
Beispiel #3
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();
}
Beispiel #4
0
pstruct_t*
pstructs_add(const char *name)
{
  auto p = ke::MakeUnique<pstruct_t>(name);
  sStructs.append(ke::Move(p));
  return sStructs.back().get();
}
Beispiel #5
0
funcenum_t *funcenums_add(const char *name)
{
  auto e = ke::MakeUnique<funcenum_t>();

  strcpy(e->name, name);
  e->tag = gTypes.defineFunction(name, e.get())->tagid();

  sFuncEnums.append(ke::Move(e));
  return sFuncEnums.back().get();
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
0
methodmap_t*
methodmap_add(methodmap_t* parent, LayoutSpec spec, const char* name)
{
  auto map = ke::MakeUnique<methodmap_t>(parent, spec, name);

  if (spec == Layout_MethodMap && parent) {
    if (parent->nullable)
      map->nullable = parent->nullable;
    if (parent->keyword_nullable)
      map->keyword_nullable = parent->keyword_nullable;
  }

  if (spec == Layout_MethodMap)
    map->tag = gTypes.defineMethodmap(name, map.get())->tagid();
  else
    map->tag = gTypes.defineObject(name)->tagid();
  sMethodmaps.append(ke::Move(map));

  return sMethodmaps.back().get();
}
Beispiel #10
0
static cell AMX_NATIVE_CALL create_kvd(AMX *amx, cell *params)
{
    KVD_Wrapper *kvdw;
    if (g_FreeKVDWs.empty()) {
        kvdw = new KVD_Wrapper;
    } else {
        kvdw = g_FreeKVDWs.popCopy();
    }

    kvdw->cls = "";
    kvdw->kvd.szClassName = const_cast<char*>(kvdw->cls.chars());
    kvdw->key = "";
    kvdw->kvd.szKeyName = const_cast<char*>(kvdw->key.chars());
    kvdw->val = "";
    kvdw->kvd.szValue = const_cast<char*>(kvdw->val.chars());
    kvdw->kvd.fHandled = 0;

    g_KVDWs.append(kvdw);

    return reinterpret_cast<cell>(kvdw);
}
Beispiel #11
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();
}
void InitDetours()
{
	IsValidTargetDetour   = DETOUR_CREATE_MEMBER_FIXED(Observer_IsValidTarget, Util::FindAddress(FUNC_ISVALIDTARGET));
	ObserverSetModeDetour = DETOUR_CREATE_MEMBER_FIXED(Observer_SetMode      , Util::FindAddress(FUNC_SETMODE));

#if defined(KE_LINUX)

	void *SetModePart2Address = Util::FindAddress(FUNC_SETMODE2);

	if (ObserverSetModeDetour && IsValidTargetDetour && SetModePart2Address)
	{
		SetModePart2 = reinterpret_cast<SetModePart2Fn>(SetModePart2Address);

#elif defined(KE_WINDOWS) || defined(KE_MACOSX)

	if (ObserverSetModeDetour && IsValidTargetDetour)
	{
#endif
		IsValidTargetDetour->EnableDetour();
		ObserverSetModeDetour->EnableDetour();
	}
	else
	{
		if (!IsValidTargetDetour)
		{
			ErrorLogs.append("CBasePlayer::Observer_IsValidTarget is not available.");
		}

		if (!ObserverSetModeDetour)
		{
			ErrorLogs.append("CBasePlayer::Observer_SetMode is not available.");
		}

	#if defined(KE_LINUX)

		if (!SetModePart2Address)
		{
			ErrorLogs.append("CBasePlayer::Observer_SetMode (second part) is not available.");
		}
	#endif

		ErrorLogs.append("Some functions are not availble, module has been disabled.");

		DestroyDetours();
	}
}

void DestroyDetours()
{
	if (IsValidTargetDetour)
	{
		IsValidTargetDetour->Destroy();
		IsValidTargetDetour = nullptr;
	}

	if (ObserverSetModeDetour)
	{
		ObserverSetModeDetour->Destroy();
		ObserverSetModeDetour = nullptr;
	}
}
Beispiel #13
0
bool loadDatabase()
{
	const auto isDatabaseLoaded = HandleDB.filename != nullptr;

	if (isDatabaseLoaded)
	{
		return true;
	}

	const char *databases[] =
	{
		"City",
		"Country" // Is the default shipped database with AMXX.
	};

	const auto modName = MF_GetModname();
	const auto dataDir = MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data");

	char file[260];
	auto status = -1;

	for (auto& database : databases)
	{
		// MF_BuildPathname not used because backslash
		// makes CreateFileMapping failing under windows.

		ke::SafeSprintf(file, sizeof file, "%s/%s/GeoLite2-%s.mmdb", modName, dataDir, database);

		status = MMDB_open(file, MMDB_MODE_MMAP, &HandleDB);

		if (status == MMDB_SUCCESS)
		{
			break;
		}

		if (status != MMDB_FILE_OPEN_ERROR)
		{
			MF_Log("Could not open %s - %s", file, MMDB_strerror(status));

			if (status == MMDB_IO_ERROR)
			{
				MF_Log("    IO error: %s", strerror(errno));
			}
		}
	}

	if (status != MMDB_SUCCESS)
	{
		MF_Log("Could not find GeoIP2 databases. Disabled natives.");
		return false;
	}

	MF_Log("Database info: %s %i.%i",
		   HandleDB.metadata.description.descriptions[0]->description,
		   HandleDB.metadata.binary_format_major_version,
		   HandleDB.metadata.binary_format_minor_version);

	// Retrieve supported languages.
	for (size_t i = 0; i < HandleDB.metadata.languages.count; i++)
	{
		LangList.append(ke::AString(HandleDB.metadata.languages.names[i]));
	}

	return true;
}