Esempio n. 1
0
/**
 * HACKHACK: The compiler will generate code for each case we need.
 * Don't remove this, otherwise files that use certain code generations
 *  will have extern problems.  For each case you need, add dummy code
 *  here.
 */
void __WHOA_DONT_CALL_ME_PLZ_K_lol_o_O()
{
	//acsprintf
	atcprintf((cell *)NULL, 0, (const char *)NULL, NULL, NULL, NULL);
	//accprintf
	atcprintf((cell *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
	//ascprintf
	atcprintf((char *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
}
Esempio n. 2
0
char* format_amxstring(AMX *amx, cell *params, int parm, int &len)
{
	static char outbuf[4096];
	cell *addr = get_amxaddr(amx, params[parm++]);
	len = atcprintf(outbuf, sizeof(outbuf)-1, addr, amx, params, &parm);
	return outbuf;
}
static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params)
{
	Handle_t hndl = static_cast<Handle_t>(params[1]);
	HandleError herr;
	HandleSecurity sec;
	FILE *pFile;

	sec.pOwner = NULL;
	sec.pIdentity = g_pCoreIdent;

	if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
		!= HandleError_None)
	{
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
	}

	char *fmt;
	int err;
	if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE)
	{
		pContext->ThrowNativeErrorEx(err, NULL);
		return 0;
	}

	char buffer[2048];
	int arg = 3;
	atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg);
	fprintf(pFile, "%s\n", buffer);

	return 1;
}
Esempio n. 4
0
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
{
	if (!g_pCurNative || (g_pCurNative->amx != amx))
	{
		LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
		return 0;
	}

	if (g_pCurNative->style)
	{
		LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
		return 0;
	}

	int vargPos = static_cast<int>(params[4]);
	int fargPos = static_cast<int>(params[3]);

	cell max = g_Params[0] / sizeof(cell);
	if (vargPos > (int)max + 1)
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
		return 0;
	}
	if (fargPos > (int)max + 1)
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid fmtarg parameter passed: %d", fargPos);
		return 0;
	}

	/* get destination info */
	cell *fmt;
	if (fargPos == 0)
	{
		if (params[0] / sizeof(cell) != 5)
		{
			LogError(amx, AMX_ERR_NATIVE, "Expected fmtarg as fifth parameter, found none");
			return 0;
		}
		fmt = get_amxaddr(amx, params[5]);
	} else {
		fmt = get_amxaddr(g_pCaller, g_Params[fargPos]);
	}
	cell *realdest = get_amxaddr(amx, params[1]);
	size_t maxlen = static_cast<size_t>(params[2]);
	cell *dest = realdest;

	/* if this is necessary... */
	static cell cpbuf[4096];
	dest = cpbuf;

	/* perform format */
	size_t total = atcprintf(dest, maxlen, fmt, g_pCaller, g_Params, &vargPos);

	/* copy back */
	memcpy(realdest, dest, (total+1) * sizeof(cell));

	return total;
}
Esempio n. 5
0
static cell AMX_NATIVE_CALL formatex(AMX *amx, cell *params)
{
	cell *buf = get_amxaddr(amx, params[1]);
	size_t maxlen = static_cast<size_t>(params[2]);
    cell *fmt = get_amxaddr(amx, params[3]);
	int param = 4;
	size_t total = atcprintf(buf, maxlen, fmt, amx, params, &param);
	return static_cast<cell>(total);
}
Esempio n. 6
0
static cell AMX_NATIVE_CALL vformat(AMX *amx, cell *params)
{
	int vargPos = static_cast<int>(params[4]);

	/** get the parent parameter array */
	AMX_HEADER *hdr = (AMX_HEADER *)amx->base;
	cell *local_params = (cell *)(
		(char *)amx->base + (cell)hdr->dat +
		(cell)amx->frm + (2 * sizeof(cell))
		);

	cell max = local_params[0] / sizeof(cell);
	if (vargPos > (int)max + 1)
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
		return 0;
	}
	
	/**
	 * check for bounds clipping
	 */
	cell addr_start = params[1];
	cell addr_end = addr_start + params[2];
	bool copy = false;
	for (int i = vargPos; i <= max; i++)
	{
		//does this clip the bounds?
		if ( (local_params[i] >= addr_start)
			&& (local_params[i] <= addr_end) )
		{
			copy = true;
			break;
		}
	}

	/* get destination info */
	cell *fmt = get_amxaddr(amx, params[3]);
	cell *realdest = get_amxaddr(amx, params[1]);
	size_t maxlen = static_cast<size_t>(params[2]);
	cell *dest = realdest;

	/* if this is necessary... */
	static cell cpbuf[4096];
	if (copy)
		dest = cpbuf;

	/* perform format */
	size_t total = atcprintf(dest, maxlen, fmt, amx, local_params, &vargPos);

	/* copy back */
	if (copy)
	{
		memcpy(realdest, dest, (total+1) * sizeof(cell));
	}

	return total;
}
Esempio n. 7
0
size_t SourceModBase::FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param)
{
	char *fmt;

	pContext->LocalToString(params[param], &fmt);

	int lparam = ++param;

	return atcprintf(buffer, maxlength, fmt, pContext, params, &lparam);
}
Esempio n. 8
0
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
{
	//do an initial run through all this 
	static char outbuf[4096];
	cell *addr = get_amxaddr(amx, params[parm++]);

	len = atcprintf(outbuf, sizeof(outbuf)-1, addr, amx, params, &parm);

	return outbuf;
}
static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params)
{
	char path[PLATFORM_MAX_PATH], *fmt, *buffer;
	int arg = 5;
	pContext->LocalToString(params[2], &buffer);
	pContext->LocalToString(params[4], &fmt);

	atcprintf(path, sizeof(path), fmt, pContext, params, &arg);

	return g_SourceMod.BuildPath(Path_SM_Rel, buffer, params[3], "%s", path);
}
Esempio n. 10
0
static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
{
	char buffer[1024];
	char *fmt;
	int arg = 2;

	pCtx->LocalToString(params[1], &fmt);
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);

	buffer[res++] = '\n';
	buffer[res] = '\0';

	META_CONPRINT(buffer);

	return 1;
}
Esempio n. 11
0
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
{
	int index = params[1];
	if ((index < 0) || (index > g_Players.GetMaxClients()))
	{
		return pCtx->ThrowNativeError("Client index %d is invalid", index);
	}

	CPlayer *pPlayer = NULL;
	if (index != 0)
	{
		pPlayer = g_Players.GetPlayerByIndex(index);
		if (!pPlayer->IsInGame())
		{
			return pCtx->ThrowNativeError("Client %d is not in game", index);
		}
		
		/* Silent fail on bots, engine will crash */
		if (pPlayer->IsFakeClient())
		{
			return 0;
		}
	}

	char buffer[1024];
	char *fmt;
	int arg = 3;

	pCtx->LocalToString(params[2], &fmt);
	size_t res = atcprintf(buffer, sizeof(buffer)-2, fmt, pCtx, params, &arg);

	buffer[res++] = '\n';
	buffer[res] = '\0';

	if (index != 0)
	{
#if SOURCE_ENGINE == SE_DOTA
		engine->ClientPrintf(pPlayer->GetIndex(), buffer);
#else
		engine->ClientPrintf(pPlayer->GetEdict(), buffer);
#endif
	} else {
		META_CONPRINT(buffer);
	}

	return 1;
}
Esempio n. 12
0
static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */
{
	cell *buf = get_amxaddr(amx, params[1]);
	cell *fmt = get_amxaddr(amx, params[3]);
	size_t maxlen = params[2];
	/** 
	 * SPECIAL CASE - check if the buffers overlap.
	 *  some users, for whatever reason, do things like:
	 *  format(buf, 255, buf....
	 *  this is considered "deprecated" but we have to support it.
	 * we do this by checking to see if reading from buf will overlap
	 */
	cell addr_start = params[1];
	cell addr_end = params[1] + maxlen * sizeof(cell);
	cell max = params[0] / sizeof(cell);
	bool copy = false;
	for (cell i = 3; i <= max; i++)
	{
		//does this clip the bounds?!?!? WELL, DOES IT!?!?! i am a loud dog
		if (params[i] >= addr_start && params[i] <= addr_end)
		{
			copy = true;
			break;
		}
	}
	if (copy)
		buf = g_cpbuf;
	int param = 4;
	size_t total = 0;

	
	total = atcprintf(buf, maxlen, fmt, amx, params, &param);

	if (copy)
	{
		/* copy back */
		cell *old = get_amxaddr(amx, params[1]);
		memcpy(old, g_cpbuf, (total+1) * sizeof(cell));
	}
	return total;
}
size_t Translate(char *buffer,
				 size_t maxlen,
				 IPluginContext *pCtx,
				 const char *key,
				 cell_t target,
				 const cell_t *params,
				 int *arg,
				 bool *error)
{
	unsigned int langid;
	*error = false;
	Translation pTrans;
	CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext());
	size_t langcount = pl->GetLangFileCount();
	unsigned int max_params = 0;

try_serverlang:
	if (target == LANG_SERVER)
	{
		langid = g_Translator.GetServerLanguage();
 	}
	else if ((target >= 1) && (target <= g_Players.GetMaxClients()))
	{
		langid = g_Translator.GetClientLanguage(target);
	}
	else
	{
		pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Translation failed: invalid client index %d", target);
		goto error_out;
	}

	if (!TryTranslation(pl, key, langid, langcount, &pTrans))
	{
		if (target != LANG_SERVER && langid != g_Translator.GetServerLanguage())
		{
			target = LANG_SERVER;
			goto try_serverlang;
		}
		else if (langid != LANGUAGE_ENGLISH)
		{
			if (!TryTranslation(pl, key, LANGUAGE_ENGLISH, langcount, &pTrans))
			{
				pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Language phrase \"%s\" not found", key);
				goto error_out;
			}
		}
		else
		{
			pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Language phrase \"%s\" not found", key);
			goto error_out;
		}
	}

	max_params = pTrans.fmt_count;

	if (max_params)
	{
		cell_t new_params[MAX_TRANSLATE_PARAMS];

		/* Check if we're going to over the limit */
		if ((*arg) + (max_params - 1) > (size_t)params[0])
		{
			pCtx->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, 
				"Translation string formatted incorrectly - missing at least %d parameters", 
				((*arg + (max_params - 1)) - params[0])
				);
			goto error_out;
		}

		/* If we need to re-order the parameters, do so with a temporary array.
		 * Otherwise, we could run into trouble with continual formats, a la ShowActivity().
		 */
		memcpy(new_params, params, sizeof(cell_t) * (params[0] + 1));
		ReorderTranslationParams(&pTrans, &new_params[*arg]);

		return atcprintf(buffer, maxlen, pTrans.szPhrase, pCtx, new_params, arg);
	}
	else
	{
		return atcprintf(buffer, maxlen, pTrans.szPhrase, pCtx, params, arg);
	}
	
error_out:
	*error = true;
	return 0;
}
Esempio n. 14
0
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param)
{
	int		arg;
	int		args = params[0] / sizeof(cell);
	D		*buf_p;
	D		ch;
	int		flags;
	int		width;
	int		prec;
	int		n;
	//char	sign;
	const S	*fmt;
	size_t	llen = maxlen;

	buf_p = buffer;
	arg = *param;
	fmt = format;

	while (true)
	{
		// run through the format string until we hit a '%' or '\0'
		for (ch = static_cast<D>(*fmt); 
			llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%');
			fmt++)
		{
			*buf_p++ = static_cast<D>(ch);
			llen--;
		}
		if (ch == '\0' || llen <= 0)
			goto done;

		// skip over the '%'
		fmt++;

		// reset formatting state
		flags = 0;
		width = 0;
		prec = -1;
		//sign = '\0';

rflag:
		ch = static_cast<D>(*fmt++);
reswitch:
		switch(ch)
		{
		case '-':
			flags |= LADJUST;
			goto rflag;
		case '.':
			n = 0;
			while( is_digit( ( ch = static_cast<D>(*fmt++)) ) )
				n = 10 * n + ( ch - '0' );
			prec = n < 0 ? -1 : n;
			goto reswitch;
		case '0':
			flags |= ZEROPAD;
			goto rflag;
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			n = 0;
			do {
				n = 10 * n + ( ch - '0' );
				ch = static_cast<D>(*fmt++);
			} while( is_digit( ch ) );
			width = n;
			goto reswitch;
		case 'c':
			CHECK_ARGS(0);
			*buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg]));
			llen--;
			arg++;
			break;
		case 'b':
			CHECK_ARGS(0);
			AddBinary(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
			arg++;
			break;
		case 'd':
		case 'i':
			CHECK_ARGS(0);
			AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
			arg++;
			break;
		case 'u':
			CHECK_ARGS(0);
			AddUInt(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
			arg++;
			break;
		case 'f':
			CHECK_ARGS(0);
			AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec, flags);
			arg++;
			break;
		case 'X':
			CHECK_ARGS(0);
			flags |= UPPERDIGITS;
			AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
			arg++;
			break;
		case 'x':
			CHECK_ARGS(0);
			AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
			arg++;
			break;
		case 'a':
			{
				CHECK_ARGS(0);
				// %a is passed a pointer directly to a cell string.
				cell* ptr=reinterpret_cast<cell*>(*get_amxaddr(amx, params[arg]));
				if (!ptr)
				{
					LogError(amx, AMX_ERR_NATIVE, "Invalid vector string handle provided (%d)", *get_amxaddr(amx, params[arg]));
					return 0;
				}

				AddString(&buf_p, llen, ptr, width, prec);
				arg++;
				break;
			}
		case 's':
			CHECK_ARGS(0);
			AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
			arg++;
			break;
		case 'L':
		case 'l':
			{
				const char *lang;
				int len;
				if (ch == 'L')
				{
					CHECK_ARGS(1);
					auto currParam = params[arg++];
					lang = playerlang(*get_amxaddr(amx, currParam));
					if (!lang)
						lang = get_amxstring(amx, currParam, 2, len);
				}
				else
				{
					CHECK_ARGS(0);
					lang = playerlang(g_langMngr.GetDefLang());
				}
				const char *key = get_amxstring(amx, params[arg++], 3, len);
				const char *def = translate(amx, lang, key);
				if (!def)
				{
					static char buf[255];
					ke::SafeSprintf(buf, sizeof(buf), "ML_NOTFOUND: %s", key);
					def = buf;
				}
				size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
				buf_p += written;
				llen -= written;
				break;
			}
		case 'N':
			{
				CHECK_ARGS(0);
				cell *addr = get_amxaddr(amx, params[arg]);
				char buffer[255];
				if (*addr)
				{
					CPlayer *player = NULL;

					if (*addr >= 1 && *addr <= gpGlobals->maxClients)
					{
						player = GET_PLAYER_POINTER_I(*addr);
					}

					if (!player || !player->initialized)
					{
						LogError(amx, AMX_ERR_NATIVE, "Client index %d is invalid", *addr);
						return 0;
					}

					const char *auth = GETPLAYERAUTHID(player->pEdict);
					if (!auth || auth[0] == '\0')
					{
						auth = "STEAM_ID_PENDING";
					}

					int userid = GETPLAYERUSERID(player->pEdict);
					ke::SafeSprintf(buffer, sizeof(buffer), "%s<%d><%s><%s>", player->name.chars(), userid, auth, player->team.chars());
				}
				else
				{
					ke::SafeSprintf(buffer, sizeof(buffer), "Console<0><Console><Console>");
				}

				AddString(&buf_p, llen, buffer, width, prec);
				arg++;
				break;
			}
		case 'n':
			{
				CHECK_ARGS(0);
				cell *addr = get_amxaddr(amx, params[arg]);
				const char *name = "Console";

				if (*addr)
				{
					CPlayer *player = NULL;

					if (*addr >= 1 && *addr <= gpGlobals->maxClients)
					{
						player = GET_PLAYER_POINTER_I(*addr);
					}

					if (!player || !player->initialized)
					{
						LogError(amx, AMX_ERR_NATIVE, "Client index %d is invalid", *addr);
						return 0;
					}

					name = player->name.chars();
				}
			
				AddString(&buf_p, llen, name, width, prec);
				arg++;
				break;
			}
		case '%':
			*buf_p++ = static_cast<D>(ch);
			if (!llen)
				goto done;
			llen--;
			break;
		case '\0':
			*buf_p++ = static_cast<D>('%');
			if (!llen)
				goto done;
			llen--;
			goto done;
			break;
		default:
			*buf_p++ = static_cast<D>(ch);
			if (!llen)
				goto done;
			llen--;
			break;
		}
	}

done:
	*buf_p = static_cast<D>(0);
	*param = arg;

	/* if max buffer length consumed, make sure we don't truncate a multi-byte character */
	if (llen <= 0 && *(buf_p - 1) & 1 << 7)
	{
		llen += UTIL_CheckValidChar(buf_p - 1);
		*(buf_p - llen) = static_cast<D>(0);
	}

	return maxlen-llen;
}