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 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 *find = strstr(str + params[4], sub); if (!find) return -1; return (find - str); }
static cell AMX_NATIVE_CALL replace_stringex(AMX *amx, cell *params) { int len; size_t maxlength = (size_t)params[2]; char *text = get_amxstring(amx, params[1], 0, len); const char *search = get_amxstring(amx, params[3], 1, len); const char *replace = get_amxstring(amx, params[4], 2, len); size_t searchLen = (params[5] == -1) ? strlen(search) : (size_t)params[5]; size_t replaceLen = (params[6] == -1) ? strlen(replace) : (size_t)params[6]; bool caseSensitive = params[7] ? true : false; if (searchLen == 0) { LogError(amx, AMX_ERR_NATIVE, "Cannot replace searches of empty strings."); return -1; } char *ptr = UTIL_ReplaceEx(text, maxlength + 1, search, searchLen, replace, replaceLen, caseSensitive); // + EOS if (ptr == NULL) { return -1; } set_amxstring(amx, params[1], ptr, maxlength); return ptr - text; }
//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; }
//Adds an item to the menu (returns current item count - 1) //native menu_additem(menu, const name[], const command[]="", access=0); static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params) { int len; char *name, *cmd; int access; GETMENU(params[1]); if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10) { LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items."); return 0; } name = get_amxstring(amx, params[2], 0, len); validate_menu_text(name); cmd = get_amxstring(amx, params[3], 1, len); access = params[4]; menuitem *pItem = pMenu->AddItem(name, cmd, access); pItem->handler = params[5]; return 1; }
// native TrieSetString(Trie:handle, const key[], const data[], bool:replace = true); static cell AMX_NATIVE_CALL TrieSetString(AMX *amx, cell *params) { CellTrie *t = TrieHandles.lookup(params[1]); if (!t) { LogError(amx, AMX_ERR_NATIVE, "Invalid map handle provided (%d)", params[1]); return 0; } int len; const char *key = get_amxstring(amx, params[2], 0, len); const char *value = get_amxstring(amx, params[3], 1, len); StringHashMap<Entry>::Insert i = t->map.findForAdd(key); if (!i.found()) { if (!t->map.add(i, key)) { return 0; } i->value.setString(value); return 1; } // Old plugin doesn't have 'replace' parameter. if (*params / sizeof(cell) == 4 && !params[4]) { return 0; } i->value.setString(value); return 1; }
// native INI_SetReaders(INIParser:smc, const kvFunc[], const nsFunc[] = "" ); static cell AMX_NATIVE_CALL INI_SetReaders(AMX *amx, cell *params) { ParseInfo *p = g_TextParsersHandles.lookup(params[1]); if (p == NULL) { LogError(amx, AMX_ERR_NATIVE, "Invalid INI parse handle (%d)", params[1]); return 0; } int kvLength = 0, nsLength = 0; const char *funcName = NULL; if ((funcName = get_amxstring(amx, params[2], 0, kvLength)) && kvLength) { p->key_value = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_STRING, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); } if (kvLength && (funcName = get_amxstring(amx, params[3], 1, nsLength)) && nsLength) { p->new_section = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); } if (p->key_value == -1 || (nsLength && p->new_section == -1)) { LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", funcName, g_plugins.findPluginFast(amx)->getName()); return 0; } return 1; }
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx, cell *params) { int iLen; g_vault.put(get_amxstring(amx, params[1], 0, iLen), get_amxstring(amx, params[2], 1, iLen)); g_vault.saveVault(); return 1; }
static cell AMX_NATIVE_CALL n_strncmp(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[4]) return strncmp(str1, str2, (size_t)params[3]); else return strncasecmp(str1, str2, (size_t)params[3]); }
//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.size(); amxx_DynaMake(pNative->pfn, id); pNative->func = idx; pNative->style = params[3]; g_RegNatives.push_back(pNative); pNative->name.assign(name); return 1; }
// native GameConfig:LoadGameConfigFile(const file[]); static cell AMX_NATIVE_CALL LoadGameConfigFile(AMX *amx, cell *params) { int length; const char *filename = get_amxstring(amx, params[1], 0, length); IGameConfig *config = nullptr; char error[128]; if (!ConfigManager.LoadGameConfigFile(filename, &config, error, sizeof(error))) { LogError(amx, AMX_ERR_NATIVE, "Unable to open %s: %s", filename, error); return 0; } int handle = GameConfigHandle.create(); auto configHandle = GameConfigHandle.lookup(handle); if (!configHandle) { return 0; } configHandle->m_config = config; return handle; }
// native bool:INI_ParseFile(INIParser:handle, const file[], &line = 0, &col = 0, any:data = 0); static cell AMX_NATIVE_CALL INI_ParseFile(AMX *amx, cell *params) { ParseInfo *p = TextParsersHandles.lookup(params[1]); if (!p) { LogError(amx, AMX_ERR_NATIVE, "Invalid INI parse handle (%d)", params[1]); return 0; } int length; const char *file = build_pathname("%s", get_amxstring(amx, params[2], 0, length)); if (*params / sizeof(cell) >= 5) { p->data = params[5]; } unsigned int line, col; bool result = textparsers->ParseFile_INI(file, p, &line, &col); *get_amxaddr(amx, params[3]) = line; *get_amxaddr(amx, params[4]) = col; return result; }
static cell AMX_NATIVE_CALL get_char_bytes(AMX *amx, cell *params) { int len; char *str = get_amxstring(amx, params[1], 0, len); return UTIL_GetUTF8CharBytes(str); };
// native ArraySetString(Array:which, item, const input[]); static cell AMX_NATIVE_CALL ArraySetString(AMX* amx, cell* params) { CellArray* vec = ArrayHandles.lookup(params[1]); if (!vec) { LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", params[1]); return 0; } size_t idx = (size_t)params[2]; if (idx >= vec->size()) { LogError(amx, AMX_ERR_NATIVE, "Invalid index %d (count: %d)", idx, vec->size()); return 0; } cell *blk = vec->at(idx); int len; char *str = get_amxstring(amx, params[3], 0, len); return strncopy(blk, str, ke::Min((size_t)len + 1, vec->blocksize())); }
// native INI_SetRawLine(INIParser:handle, const func[]); static cell AMX_NATIVE_CALL INI_SetRawLine(AMX *amx, cell *params) { ParseInfo *p = TextParsersHandles.lookup(params[1]); if (!p) { LogError(amx, AMX_ERR_NATIVE, "Invalid INI parse handle (%d)", params[1]); return 0; } int length = 0; const char *funcName = nullptr; if ((funcName = get_amxstring(amx, params[2], 0, length)) && length) { p->raw_line = registerSPForwardByName(amx, funcName, FP_CELL, FP_STRING, FP_CELL, FP_CELL, FP_DONE); } if (p->raw_line == -1) { LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", funcName, g_plugins.findPluginFast(amx)->getName()); return 0; } return 1; }
static cell AMX_NATIVE_CALL ewrite_string(AMX *amx, cell *params) /* 1 param */ { int a; g_pEngTable->pfnWriteString(get_amxstring(amx, params[1], 3, a)); return 1; }
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); }
// native PushStackString(Stack:handle, const value[]); static cell AMX_NATIVE_CALL PushStackString(AMX* amx, cell* params) { CellArray* vec = ArrayHandles.lookup(params[1]); if (!vec) { LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", params[1]); return 0; } cell *blk = vec->push(); if (!blk) { LogError(amx, AMX_ERR_NATIVE, "Failed to grow stack"); return 0; } int len; const char *value = get_amxstring(amx, params[2], 0, len); strncopy(blk, value, vec->blocksize()); return 1; }
static cell AMX_NATIVE_CALL set_native_filter(AMX *amx, cell *params) { Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER]; if (!pHandler) { Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); AMXXLOG_Error("[AMXX] Plugin not initialized correctly."); return 0; } if (!pHandler->IsNativeFiltering()) { //we can only initialize this during PRENIT if (! (amx->flags & AMX_FLAG_PRENIT) ) return 0; } int len; char *func = get_amxstring(amx, params[1], 0, len); int err = pHandler->SetNativeFilter(func); if (err != AMX_ERR_NONE) { Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); AMXXLOG_Error("[AMXX] Function not found: %s", function); return 0; } return 1; }
static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */ { int a; WRITE_STRING(get_amxstring(amx, params[1], 3, a)); 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); }
// native SMC_SetParseEnd(SMCParser:handle, const func[]); static cell AMX_NATIVE_CALL SMC_SetParseEnd(AMX *amx, cell *params) { ParseInfo *p = g_TextParsersHandles.lookup(params[1]); if (p == NULL) { LogError(amx, AMX_ERR_NATIVE, "Invalid SMC parse handle (%d)", params[1]); return 0; } int length = 0; const char *funcName = NULL; if ((funcName = get_amxstring(amx, params[2], 0, length)) && length) { p->parse_end = registerSPForwardByName(amx, funcName, FP_CELL, FP_CELL, FP_CELL, FP_DONE); } if (p->parse_end == -1) { LogError(amx, AMX_ERR_NATIVE, "Function is not present (function \"%s\") (plugin \"%s\")", funcName, g_plugins.findPluginFast(amx)->getName()); return 0; } return 1; }
// native bool:TrieGetString(Trie:handle, const key[], buff[], len, &size = 0); static cell AMX_NATIVE_CALL TrieGetString(AMX *amx, cell *params) { CellTrie *t = TrieHandles.lookup(params[1]); if (!t) { LogError(amx, AMX_ERR_NATIVE, "Invalid map handle provided (%d)", params[1]); return 0; } if (params[4] < 0) { LogError(amx, AMX_ERR_NATIVE, "Invalid buffer size (%d)", params[4]); return 0; } int len; const char *key = get_amxstring(amx, params[2], 0, len); cell *pSize = get_amxaddr(amx, params[5]); StringHashMap<Entry>::Result r = t->map.find(key); if (!r.found() || !r->value.isString()) { return 0; } *pSize = (cell)set_amxstring_utf8(amx, params[3], r->value.chars(), strlen(r->value.chars()), params[4]); return 1; }
// native SMCError:SMC_ParseFile(SMCParser:handle, const file[], &line = 0, &col = 0, any:data = 0); static cell AMX_NATIVE_CALL SMC_ParseFile(AMX *amx, cell *params) { ParseInfo *p = TextParsersHandles.lookup(params[1]); if (!p) { LogError(amx, AMX_ERR_NATIVE, "Invalid SMC parse handle (%d)", params[1]); return 0; } if (*params / sizeof(cell) >= 5) { p->data = params[5]; } int length; const char *file = build_pathname("%s", get_amxstring(amx, params[2], 0, length)); SMCStates states; SMCError p_err = textparsers->ParseFile_SMC(file, p, &states); *get_amxaddr(amx, params[3]) = states.line; *get_amxaddr(amx, params[4]) = states.col; return static_cast<cell>(p_err); }
// native bool:TrieGetCell(Trie:handle, const key[], &any:value); static cell AMX_NATIVE_CALL TrieGetCell(AMX *amx, cell *params) { CellTrie *t = TrieHandles.lookup(params[1]); if (!t) { LogError(amx, AMX_ERR_NATIVE, "Invalid map handle provided (%d)", params[1]); return 0; } int len; const char *key = get_amxstring(amx, params[2], 0, len); StringHashMap<Entry>::Result r = t->map.find(key); if (!r.found()) { return 0; } cell *ptr = get_amxaddr(amx, params[3]); if (r->value.isCell()) { *ptr = r->value.cell_(); return 1; } return 0; }
static cell AMX_NATIVE_CALL menu_addtext(AMX *amx, cell *params) { GETMENU(params[1]); if (params[2] && (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)) { LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items."); return 0; } if (!pMenu->m_Items.length()) { LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items."); return 0; } menuitem *item = pMenu->m_Items[pMenu->m_Items.length() - 1]; BlankItem a; int len; a.SetText(get_amxstring(amx, params[2], 0, len)); if (params[3] == 1) a.SetEatNumber(true); else a.SetEatNumber(false); item->blanks.append(ke::Move(a)); return 1; }
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx, cell *params) { int iLen; g_vault.remove(get_amxstring(amx, params[1], 0, iLen)); g_vault.saveVault(); return 1; }
static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params) { int len; char *lib = get_amxstring(amx, params[1], 0, len); AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx)); return 1; }
char *get_amxstring_null(AMX *amx, cell amx_addr, int id, int& len) { if (get_amxaddr(amx, amx_addr) == g_plugins.findPluginFast(amx)->getNullStringOfs()) { return nullptr; } return get_amxstring(amx, amx_addr, id, len); }
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx, cell *params) { int iLen; const char* key = get_amxstring(amx, params[1], 0, iLen); if (params[3]) return set_amxstring(amx, params[2], g_vault.get(key), params[3]); return g_vault.get_number(key); }
//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_utf8(amx, params[2], left, strlen(left), leftMax); set_amxstring_utf8(amx, params[4], right, strlen(right), rightMax); delete [] left; delete [] right; return 1; }