mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
937 lines
18 KiB
C++
Executable File
937 lines
18 KiB
C++
Executable File
/* AMX Mod X
|
|
*
|
|
* by the AMX Mod X Development Team
|
|
* originally developed by OLO
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* In addition, as a special exception, the author gives permission to
|
|
* link the code of this program with the Half-Life Game Engine ("HL
|
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
* respects for all of the code used other than the HL Engine and MODs
|
|
* from Valve. If you modify this file, you may extend this exception
|
|
* to your version of the file, but you are not obligated to do so. If
|
|
* you do not wish to do so, delete this exception statement from your
|
|
* version.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include "amxmodx.h"
|
|
|
|
const char* stristr(const char* str, const char* substr)
|
|
{
|
|
register char *needle = (char *)substr;
|
|
register char *prevloc = (char *)str;
|
|
register char *haystack = (char *)str;
|
|
|
|
while (*haystack)
|
|
{
|
|
if (tolower(*haystack) == tolower(*needle))
|
|
{
|
|
haystack++;
|
|
if (!*++needle)
|
|
return prevloc;
|
|
} else {
|
|
haystack = ++prevloc;
|
|
needle = (char *)substr;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char* format_amxstring(AMX *amx, cell *params, int parm, int& len)
|
|
{
|
|
return g_langMngr.FormatAmxString(amx, params, parm, len);
|
|
}
|
|
|
|
int amxstring_len(cell* a)
|
|
{
|
|
register int c = 0;
|
|
|
|
while (a[c])
|
|
++c;
|
|
|
|
return c;
|
|
}
|
|
|
|
cell* get_amxaddr(AMX *amx, cell amx_addr)
|
|
{
|
|
return (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
|
}
|
|
|
|
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
|
|
{
|
|
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
|
cell* start = dest;
|
|
|
|
while (max-- && *source)
|
|
*dest++ = (cell)*source++;
|
|
|
|
*dest = 0;
|
|
|
|
return dest - start;
|
|
}
|
|
|
|
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
|
|
{
|
|
static char buffor[4][3072];
|
|
register cell* source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
|
register char* dest = buffor[id];
|
|
char* start = dest;
|
|
|
|
while ((*dest++=(char)(*source++)));
|
|
|
|
len = --dest - start;
|
|
|
|
return start;
|
|
}
|
|
|
|
void copy_amxmemory(cell* dest, cell* src, int len)
|
|
{
|
|
while (len--)
|
|
*dest++=*src++;
|
|
}
|
|
|
|
|
|
char* parse_arg(char** line, int& state)
|
|
{
|
|
static char arg[3072];
|
|
char* dest = arg;
|
|
state = 0;
|
|
|
|
while (**line)
|
|
{
|
|
if (isspace(**line))
|
|
{
|
|
if (state == 1)
|
|
break;
|
|
else if (!state)
|
|
{
|
|
(*line)++;
|
|
continue;
|
|
}
|
|
}
|
|
else if (state != 2)
|
|
state = 1;
|
|
|
|
if (**line == '"')
|
|
{
|
|
(*line)++;
|
|
|
|
if (state == 2)
|
|
break;
|
|
|
|
state = 2;
|
|
continue;
|
|
}
|
|
|
|
*dest++ = *(*line)++;
|
|
}
|
|
|
|
*dest = '\0';
|
|
return arg;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
|
|
{
|
|
static char buffor[3072];
|
|
cell *a = get_amxaddr(amx, params[1]);
|
|
cell *b = get_amxaddr(amx, params[3]);
|
|
cell *c = get_amxaddr(amx, params[4]);
|
|
int iMain = amxstring_len(a);
|
|
int iWhat = amxstring_len(b);
|
|
int iWith = amxstring_len(c);
|
|
int iPot = iMain + iWith - iWhat;
|
|
|
|
if (iPot >= params[2])
|
|
{
|
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
char *d = buffor;
|
|
cell *x, *y, *z = a, *l = a;
|
|
int p = 0;
|
|
|
|
while (*a)
|
|
{
|
|
if (*a == *b)
|
|
{
|
|
x = a + 1;
|
|
y = b + 1;
|
|
p = 1;
|
|
if (!*y) break;
|
|
|
|
while (*x == *y)
|
|
{
|
|
x++; y++; p++;
|
|
if (!*y) break;
|
|
}
|
|
|
|
if (!*y) break;
|
|
p = 0;
|
|
*d++ = (char)*a++;
|
|
continue;
|
|
}
|
|
*d++ = (char)*a++;
|
|
}
|
|
|
|
if (p)
|
|
{
|
|
while (*c) *d++ = (char)*c++;
|
|
a += p;
|
|
while (*a) *d++ = (char)*a++;
|
|
*d = 0;
|
|
d = buffor;
|
|
while (*d) *z++ = *d++;
|
|
*z = 0;
|
|
return (z - l);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL contain(AMX *amx, cell *params) /* 2 param */
|
|
{
|
|
register cell *a = get_amxaddr(amx, params[2]);
|
|
register cell *b = get_amxaddr(amx, params[1]);
|
|
register cell *c = b;
|
|
cell* str = b;
|
|
cell* substr = a;
|
|
|
|
while (*c)
|
|
{
|
|
if (*c == *a)
|
|
{
|
|
c++;
|
|
if (!*++a)
|
|
return b - str;
|
|
} else {
|
|
c = ++b;
|
|
a = substr;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL containi(AMX *amx, cell *params) /* 2 param */
|
|
{
|
|
register cell *a = get_amxaddr(amx, params[2]);
|
|
register cell *b = get_amxaddr(amx, params[1]);
|
|
register cell *c = b;
|
|
cell* str = b;
|
|
cell* substr = a;
|
|
|
|
while (*c)
|
|
{
|
|
if (tolower(*c) == tolower(*a))
|
|
{
|
|
c++;
|
|
if (!*++a)
|
|
return b - str;
|
|
} else {
|
|
c = ++b;
|
|
a = substr;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL strtonum(AMX *amx, cell *params) /* 1 param */
|
|
{
|
|
int iLen;
|
|
return atoi(get_amxstring(amx, params[1], 0, iLen));
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL numtostr(AMX *amx, cell *params) /* 3 param */
|
|
{
|
|
char szTemp[32];
|
|
sprintf(szTemp, "%d", (int)params[1]);
|
|
return set_amxstring(amx, params[2], szTemp, params[3]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL str_to_float(AMX *amx, cell *params)
|
|
{
|
|
cell *str = get_amxaddr(amx, params[1]);
|
|
|
|
bool neg = false;
|
|
unsigned long part1 = 0;
|
|
|
|
if (*str == '-')
|
|
{
|
|
neg = true;
|
|
++str;
|
|
}
|
|
else if (*str == '+')
|
|
++str;
|
|
|
|
while (*str)
|
|
{
|
|
if (*str == '.')
|
|
{
|
|
++str;
|
|
break;
|
|
}
|
|
|
|
if (*str < '0' || *str > '9')
|
|
{
|
|
REAL fl = neg ? -static_cast<REAL>(part1) : static_cast<REAL>(part1);
|
|
return amx_ftoc(fl);
|
|
}
|
|
|
|
part1 *= 10;
|
|
part1 += *str - '0';
|
|
|
|
++str;
|
|
}
|
|
|
|
unsigned long part2 = 0;
|
|
unsigned long div = 1;
|
|
|
|
while (*str)
|
|
{
|
|
if (*str < '0' || *str > '9')
|
|
break;
|
|
|
|
part2 *= 10;
|
|
part2 += *str - '0';
|
|
div *= 10;
|
|
++str;
|
|
}
|
|
|
|
REAL fl = static_cast<REAL>(part1) + (static_cast<REAL>(part2) / div);
|
|
|
|
if (neg)
|
|
fl = -fl;
|
|
|
|
return amx_ftoc(fl);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL float_to_str(AMX *amx, cell *params)
|
|
{
|
|
char szTemp[32];
|
|
sprintf(szTemp, "%f", amx_ctof(params[1]));
|
|
return set_amxstring(amx, params[2], szTemp, params[3]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL add(AMX *amx, cell *params) /* 4 param */
|
|
{
|
|
cell *src = get_amxaddr(amx, params[3]);
|
|
cell *dest = get_amxaddr(amx, params[1]);
|
|
cell *start = dest;
|
|
int c = params[2], d = params[4];
|
|
|
|
while (*dest && c--)
|
|
++dest;
|
|
|
|
if (d)
|
|
{
|
|
while (c-- && d-- && *src)
|
|
*dest++ =* src++;
|
|
*dest = 0;
|
|
|
|
return (dest - start);
|
|
}
|
|
|
|
while (c-- && *src)
|
|
*dest++ =* src++;
|
|
*dest = 0;
|
|
|
|
return (dest-start);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL copy(AMX *amx, cell *params) /* 4 param */
|
|
{
|
|
cell *src = get_amxaddr(amx, params[3]);
|
|
cell *dest = get_amxaddr(amx, params[1]);
|
|
cell *start = dest;
|
|
int c = params[2];
|
|
|
|
while (c-- && *src)
|
|
*dest++ =* src++;
|
|
*dest = 0;
|
|
|
|
return (dest - start);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL copyc(AMX *amx, cell *params) /* 4 param */
|
|
{
|
|
cell *src = get_amxaddr(amx, params[3]);
|
|
cell *dest = get_amxaddr(amx, params[1]);
|
|
cell *start = dest;
|
|
int c = params[2];
|
|
cell ch = params[4];
|
|
|
|
while (c-- && *src && *src != ch)
|
|
*dest++ =* src++;
|
|
*dest = 0;
|
|
|
|
return (dest - start);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL setc(AMX *amx, cell *params) /* 4 param */
|
|
{
|
|
cell *src = get_amxaddr(amx, params[1]);
|
|
int c = params[2];
|
|
cell ch = params[3];
|
|
|
|
while (c--)
|
|
*src++ = ch;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL equal(AMX *amx, cell *params) /* 3 param */
|
|
{
|
|
cell *a = get_amxaddr(amx, params[1]);
|
|
cell *b = get_amxaddr(amx, params[2]);
|
|
int c = params[3];
|
|
|
|
if (c)
|
|
{
|
|
while (--c && *a && (*a == *b))
|
|
++a, ++b;
|
|
return (*a-*b)?0:1;
|
|
}
|
|
|
|
int ret;
|
|
|
|
while (!(ret = *a - *b) && *b)
|
|
++a, ++b;
|
|
|
|
return ret ? 0 : 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
|
|
{
|
|
cell *a = get_amxaddr(amx, params[1]);
|
|
cell *b = get_amxaddr(amx, params[2]);
|
|
int f, l, c = params[3];
|
|
|
|
if (c)
|
|
{
|
|
do
|
|
{
|
|
f = tolower(*a++);
|
|
l = tolower(*b++);
|
|
} while (--c && l && f && f == l);
|
|
|
|
return (f - l) ? 0 : 1;
|
|
}
|
|
|
|
do
|
|
{
|
|
f = tolower(*a++);
|
|
l = tolower(*b++);
|
|
} while (f && f == l);
|
|
|
|
return (f - l) ? 0 : 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */
|
|
{
|
|
int len;
|
|
return set_amxstring(amx, params[1], format_amxstring(amx, params, 3, len), params[2]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */
|
|
{
|
|
int inum = *params / sizeof(cell), iarg = 2, c;
|
|
char* arg, *parse = get_amxstring(amx, params[1], 0, c);
|
|
cell *cptr;
|
|
int state;
|
|
|
|
while (*parse)
|
|
{
|
|
arg = parse_arg(&parse,state);
|
|
|
|
if (state)
|
|
{
|
|
if (inum <= iarg)
|
|
return ((iarg - 2)>>1);
|
|
|
|
cptr = get_amxaddr(amx, params[iarg++]);
|
|
c = *get_amxaddr(amx, params[iarg++]);
|
|
|
|
while (c-- && *arg)
|
|
*cptr++ = (cell)*arg++;
|
|
*cptr = 0;
|
|
}
|
|
}
|
|
|
|
return ((iarg - 2)>>1);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL strtolower(AMX *amx, cell *params) /* 1 param */
|
|
{
|
|
cell *cptr = get_amxaddr(amx, params[1]);
|
|
cell *begin = cptr;
|
|
|
|
while (*cptr)
|
|
{
|
|
*cptr = tolower(*cptr);
|
|
cptr++;
|
|
}
|
|
|
|
return cptr - begin;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL strtoupper(AMX *amx, cell *params) /* 1 param */
|
|
{
|
|
cell *cptr = get_amxaddr(amx, params[1]);
|
|
cell *begin = cptr;
|
|
|
|
while (*cptr)
|
|
{
|
|
*cptr = toupper(*cptr);
|
|
cptr++;
|
|
}
|
|
|
|
return cptr - begin;
|
|
}
|
|
|
|
int fo_numargs(AMX *amx)
|
|
{
|
|
unsigned char *data = amx->base + (int)((AMX_HEADER *)amx->base)->dat;
|
|
cell bytes= *(cell *)(data + (int)amx->frm + 2 * sizeof(cell));
|
|
return (int)(bytes / sizeof(cell));
|
|
}
|
|
|
|
int fo_getargnum(AMX *amx, int pos)
|
|
{
|
|
unsigned char *data = amx->base + (int)((AMX_HEADER *)amx->base)->dat;
|
|
cell value = *(cell *)(data + (int)amx->frm + (pos + 3) * sizeof(cell));
|
|
return *(cell *)(data + (int)value);
|
|
}
|
|
|
|
float fo_getargfloat(AMX *amx, int pos)
|
|
{
|
|
unsigned char *data = amx->base + (int)((AMX_HEADER *)amx->base)->dat;
|
|
cell value = *(cell *)(data + (int)amx->frm + (pos + 3) * sizeof(cell));
|
|
cell number = *(cell *)(data + (int)value);
|
|
return *(REAL *)((void *)&number);
|
|
}
|
|
|
|
char* fo_getargstr(AMX *amx, int swap, int pos)
|
|
{
|
|
unsigned char *data = amx->base + (int)((AMX_HEADER *)amx->base)->dat;
|
|
cell src_value= *(cell *)(data + (int)amx->frm + (pos + 3) * sizeof(cell));
|
|
cell value;
|
|
static char buffer[2][3072];
|
|
char* b = buffer[swap];
|
|
int a = 0;
|
|
|
|
do
|
|
{
|
|
value = src_value + a++ * sizeof(cell);
|
|
value = *(cell *)(data + (int)value);
|
|
*b++ = static_cast<char>(value);
|
|
} while (value);
|
|
|
|
return buffer[swap];
|
|
}
|
|
|
|
char* format_arguments(AMX *amx, int parm, int& len)
|
|
{
|
|
static char buffer[2][3072];
|
|
static char format[16];
|
|
char *ptr, *arg, *dest = *buffer;
|
|
char *src = fo_getargstr(amx, 0, parm++);
|
|
int numparam = fo_numargs(amx);
|
|
|
|
while (*src)
|
|
{
|
|
if (*src == '%' && *(src + 1))
|
|
{
|
|
ptr = format;
|
|
*ptr++ = *src++;
|
|
|
|
if (*src == '%')
|
|
{
|
|
*dest++ = *src++;
|
|
continue;
|
|
}
|
|
|
|
while (!isalpha(*ptr++ = *src++));
|
|
|
|
*ptr='\0';
|
|
if (numparam < parm) continue;
|
|
arg = buffer[1];
|
|
|
|
switch (*(ptr - 1))
|
|
{
|
|
case 's': sprintf(arg, format, fo_getargstr(amx, 1, parm++)); break;
|
|
case 'f': case 'g': sprintf(arg, format, fo_getargfloat(amx, parm++)); break;
|
|
default: sprintf(arg, format, fo_getargnum(amx, parm++));
|
|
}
|
|
|
|
while (*arg) *dest++ = *arg++;
|
|
continue;
|
|
}
|
|
*dest++ = *src++;
|
|
}
|
|
|
|
*dest = '\0';
|
|
len = dest - *buffer;
|
|
|
|
return *buffer;
|
|
}
|
|
|
|
//added by BAILOPAN for jtp10181
|
|
//takes a string and breaks it into a 1st param and rest params
|
|
//different from strbreak because it's more crafted for control
|
|
static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
|
|
{
|
|
int left_pos = 0;
|
|
int right_pos = 0;
|
|
unsigned int i = 0;
|
|
bool done_flag = false;
|
|
int len = 0;
|
|
|
|
//string[]
|
|
char *string = get_amxstring(amx, params[1], 0, len);
|
|
//left[]
|
|
char *left = new char[len + 1];
|
|
//right[]
|
|
char *right = new char[len + 1];
|
|
int leftMax = params[3];
|
|
int rightMax = params[5];
|
|
//token
|
|
char token = static_cast<char>(params[6]);
|
|
//trim
|
|
int trim = params[7];
|
|
|
|
for (i = 0; i < (unsigned int)len; i++)
|
|
{
|
|
if (trim && !done_flag)
|
|
{
|
|
if (isspace(string[i]))
|
|
{
|
|
while (isspace(string[++i]));
|
|
done_flag = true;
|
|
}
|
|
}
|
|
|
|
if (!done_flag && string[i] == token)
|
|
{
|
|
done_flag = true;
|
|
i++;
|
|
}
|
|
|
|
if (done_flag)
|
|
{
|
|
right[right_pos++] = string[i];
|
|
} else {
|
|
left[left_pos++] = string[i];
|
|
}
|
|
}
|
|
|
|
right[right_pos] = 0;
|
|
left[left_pos] = 0;
|
|
set_amxstring(amx, params[2], left, leftMax);
|
|
set_amxstring(amx, params[4], right, rightMax);
|
|
delete [] left;
|
|
delete [] right;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//added by BAILOPAN
|
|
//Takes a string and breaks it into a 1st param and rest params
|
|
//strbreak(String[], First[], FirstLen, Rest[], RestLen)
|
|
static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
|
|
{
|
|
bool quote_flag = false;
|
|
bool done_flag = false;
|
|
int left_pos = 0;
|
|
int right_pos = 0;
|
|
int l = 0;
|
|
unsigned int i = 0;
|
|
char hold = '"';
|
|
|
|
char *string = get_amxstring(amx, params[1], 0, l);
|
|
char *left = new char[strlen(string) + 1];
|
|
char *right = new char[strlen(string) + 1];
|
|
int LeftMax = params[3];
|
|
int RightMax = params[5];
|
|
|
|
for (i = 0; i < (unsigned int)l; i++)
|
|
{
|
|
if (string[i] == '"' && !quote_flag)
|
|
{
|
|
quote_flag = true;
|
|
}
|
|
else if (string[i] == '"' && quote_flag)
|
|
{
|
|
quote_flag = false;
|
|
}
|
|
|
|
if (isspace(string[i]) && !quote_flag && !done_flag)
|
|
{
|
|
done_flag = true;
|
|
i++;
|
|
}
|
|
|
|
if (!done_flag && string[i]!='"')
|
|
{
|
|
if (left_pos < LeftMax)
|
|
{
|
|
left[left_pos] = string[i];
|
|
|
|
if (left[left_pos] == '\'')
|
|
{
|
|
left[left_pos] = hold;
|
|
}
|
|
|
|
left_pos++;
|
|
} else {
|
|
done_flag = true;
|
|
}
|
|
} else {
|
|
if (right_pos < RightMax && string[i]!='"')
|
|
{
|
|
right[right_pos] = string[i];
|
|
|
|
if (right[right_pos] == '\'')
|
|
{
|
|
right[right_pos] = hold;
|
|
}
|
|
|
|
right_pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
left[left_pos] = '\0';
|
|
right[right_pos] = '\0';
|
|
set_amxstring(amx, params[2], left, params[3]);
|
|
set_amxstring(amx, params[4], right, params[5]);
|
|
delete [] left;
|
|
delete [] right;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL format_args(AMX *amx, cell *params)
|
|
{
|
|
int len;
|
|
int pos = params[3];
|
|
|
|
if (pos < 0)
|
|
{
|
|
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
return 0;
|
|
}
|
|
|
|
char* string = format_arguments(amx, pos, len); // indexed from 0
|
|
return set_amxstring(amx, params[1], string, params[2]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL is_digit(AMX *amx, cell *params)
|
|
{
|
|
return isdigit(params[1]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL is_alnum(AMX *amx, cell *params)
|
|
{
|
|
return isalnum(params[1]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL is_space(AMX *amx, cell *params)
|
|
{
|
|
return isspace(params[1]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL is_alpha(AMX *amx, cell *params)
|
|
{
|
|
return isalpha(params[1]);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
|
|
{
|
|
int len = 0;
|
|
cell *str = get_amxaddr(amx, params[1]);
|
|
|
|
if (!isalpha((char)str[0]) || !(str[0] & (1<<5)))
|
|
return 0;
|
|
str[0] &= ~(1<<5);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
|
|
{
|
|
int len;
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
|
|
|
return strlen(str);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
|
{
|
|
cell *asdf = get_amxaddr(amx, params[1]);
|
|
cell *cptr = asdf;
|
|
int len = 0;
|
|
while (*cptr++) len++;
|
|
int flag = 0, incr = 0;
|
|
register int i = 0;
|
|
|
|
for (i = len - 1; i >= 0; i--)
|
|
{
|
|
if (!isspace(asdf[i]))
|
|
{
|
|
break;
|
|
} else {
|
|
asdf[i] = 0;
|
|
len--;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (isspace(asdf[i]) && !flag)
|
|
{
|
|
incr++;
|
|
if (incr + i < len)
|
|
asdf[i] = asdf[incr + i];
|
|
} else {
|
|
if (!flag)
|
|
flag = 1;
|
|
if (incr)
|
|
asdf[i] = asdf[incr+i];
|
|
}
|
|
}
|
|
asdf[len] = 0;
|
|
|
|
return incr;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL n_strcat(AMX *amx, cell *params)
|
|
{
|
|
cell *cdest, *csrc;
|
|
|
|
cdest = get_amxaddr(amx, params[1]);
|
|
csrc = get_amxaddr(amx, params[2]);
|
|
int num = params[3];
|
|
|
|
while (*cdest && num)
|
|
{
|
|
cdest++;
|
|
num--;
|
|
}
|
|
|
|
if (!num)
|
|
return 0;
|
|
|
|
while (*csrc && num)
|
|
{
|
|
*cdest++ = *csrc++;
|
|
num--;
|
|
}
|
|
*cdest = 0;
|
|
|
|
return params[3] - num;
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
|
|
{
|
|
int len;
|
|
char *str1 = get_amxstring(amx, params[1], 0, len);
|
|
char *str2 = get_amxstring(amx, params[2], 1, len);
|
|
|
|
if (params[1])
|
|
return stricmp(str1, str2);
|
|
else
|
|
return strcmp(str1, str2);
|
|
}
|
|
|
|
static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
|
|
{
|
|
int len;
|
|
char *str = get_amxstring(amx, params[1], 0, len);
|
|
int sublen;
|
|
char *sub = get_amxstring(amx, params[2], 1, sublen);
|
|
|
|
bool found = false;
|
|
bool igcase = params[3] ? true : false;
|
|
|
|
if (igcase)
|
|
{
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
if (str[i] & (1<<5))
|
|
str[i] &= ~(1<<5);
|
|
}
|
|
for (int i = 0; i < sublen; i++)
|
|
{
|
|
if (str[i] & (1<<5))
|
|
str[i] &= ~(1<<5);
|
|
}
|
|
}
|
|
|
|
if (params[4] > len)
|
|
return -1;
|
|
|
|
char *pos = &(str[params[4]]);
|
|
char *find = strstr(str, sub);
|
|
|
|
if (!find)
|
|
return -1;
|
|
|
|
return (find - str);
|
|
}
|
|
|
|
AMX_NATIVE_INFO string_Natives[] =
|
|
{
|
|
{"add", add},
|
|
{"contain", contain},
|
|
{"containi", containi},
|
|
{"copy", copy},
|
|
{"copyc", copyc},
|
|
{"equal", equal},
|
|
{"equali", equali},
|
|
{"format", format},
|
|
{"format_args", format_args},
|
|
{"isdigit", is_digit},
|
|
{"isalnum", is_alnum},
|
|
{"isspace", is_space},
|
|
{"isalpha", is_alpha},
|
|
{"num_to_str", numtostr},
|
|
{"numtostr", numtostr},
|
|
{"parse", parse},
|
|
{"replace", replace},
|
|
{"setc", setc},
|
|
{"strbreak", strbreak},
|
|
{"strtolower", strtolower},
|
|
{"strtoupper", strtoupper},
|
|
{"str_to_num", strtonum},
|
|
{"strtonum", strtonum},
|
|
{"trim", amx_trim},
|
|
{"ucfirst", amx_ucfirst},
|
|
{"strtok", amx_strtok},
|
|
{"strlen", amx_strlen},
|
|
{"strcat", n_strcat},
|
|
{"strfind", n_strfind},
|
|
{"strcmp", n_strcmp},
|
|
{"str_to_float", str_to_float},
|
|
{"float_to_str", float_to_str},
|
|
{NULL, NULL }
|
|
};
|