// native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0); static cell AMX_NATIVE_CALL ArraySort(AMX* amx, cell* params) { cell handle = params[1]; CellArray* vec = ArrayHandles.lookup(handle); if (!vec) { LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle); return 0; } int len; char* funcName = get_amxstring(amx, params[2], 0, len); // MySortFunc(Array:array, item1, item2, const data[], data_size) int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); if (func < 0) { LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcName); return 0; } size_t arraysize = vec->size(); size_t blocksize = vec->blocksize(); cell *array = vec->base(); ArraySort_s oldinfo = SortInfo; SortInfo.func = func; SortInfo.array_base = array; SortInfo.array_bsize = static_cast<cell>(blocksize); SortInfo.array_hndl = handle; SortInfo.data = params[3]; SortInfo.size = params[4]; qsort(array, arraysize, blocksize * sizeof(cell), SortArrayList); SortInfo = oldinfo; unregisterSPForward(func); return 1; }
static cell_t sm_SortADTArrayCustom(IPluginContext *pContext, const cell_t *params) { CellArray *cArray; HandleError err; HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&cArray)) != HandleError_None) { return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); } IPluginFunction *pFunction = pContext->GetFunctionById(params[2]); if (!pFunction) { return pContext->ThrowNativeError("Function %x is not a valid function", params[2]); } size_t arraysize = cArray->size(); size_t blocksize = cArray->blocksize(); cell_t *array = cArray->base(); sort_infoADT oldinfo = g_SortInfoADT; g_SortInfoADT.pFunc = pFunction; g_SortInfoADT.array_base = array; g_SortInfoADT.array_bsize = (cell_t) blocksize; g_SortInfoADT.array_hndl = params[1]; g_SortInfoADT.hndl = params[3]; qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_custom); g_SortInfoADT = oldinfo; return 1; }
static cell_t sm_SortADTArray(IPluginContext *pContext, const cell_t *params) { CellArray *cArray; HandleError err; HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&cArray)) != HandleError_None) { return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); } cell_t order = params[2]; if (order == Sort_Random) { sort_adt_random(cArray); return 1; } cell_t type = params[3]; size_t arraysize = cArray->size(); size_t blocksize = cArray->blocksize(); cell_t *array = cArray->base(); if (type == Sort_Integer) { if (order == Sort_Ascending) { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_ints_asc); } else { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_ints_desc); } } else if (type == Sort_Float) { if (order == Sort_Ascending) { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_floats_asc); } else { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_floats_desc); } } else if (type == Sort_String) { if (order == Sort_Ascending) { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_strings_asc); } else { qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_strings_desc); } } return 1; }
CellArray *UpdateMapList(CellArray *pUseArray, const char *name, int *pSerial, unsigned int flags) { int change_serial; CellArray *pNewArray = NULL; bool success, free_new_array; free_new_array = false; if ((success = GetMapList(&pNewArray, name, &change_serial)) == false) { if ((flags & MAPLIST_FLAG_NO_DEFAULT) != MAPLIST_FLAG_NO_DEFAULT) { /* If this list failed, and it's not the default, try the default. */ if (strcmp(name, "default") != 0) { success = GetMapList(&pNewArray, name, &change_serial); } /* If either of the last two conditions failed, try again if we can. */ if (!success && strcmp(name, "mapcyclefile") != 0) { success = GetMapList(&pNewArray, "mapcyclefile", &change_serial); } } } /* If there was a success, and the serial has not changed, bail out. */ if (success && *pSerial == change_serial) { return NULL; } /** * If there was a success but no map list, we need to look in the maps folder. * If there was a failure and the flag is specified, we need to look in the maps folder. */ if ((success && pNewArray == NULL) || (!success && ((flags & MAPLIST_FLAG_MAPSFOLDER) == MAPLIST_FLAG_MAPSFOLDER))) { pNewArray = new CellArray(64); free_new_array = true; cell_t *blk; FileFindHandle_t findHandle; const char *fileName = bridge->filesystem->FindFirstEx("maps/*.bsp", "GAME", &findHandle); while (fileName) { char buffer[PLATFORM_MAX_PATH]; UTIL_StripExtension(fileName, buffer, sizeof(buffer)); if (!gamehelpers->IsMapValid(buffer)) { fileName = bridge->filesystem->FindNext(findHandle); continue; } if ((blk = pNewArray->push()) == NULL) { fileName = bridge->filesystem->FindNext(findHandle); continue; } strncopy((char *)blk, buffer, 255); fileName = bridge->filesystem->FindNext(findHandle); } bridge->filesystem->FindClose(findHandle); /* Remove the array if there were no items. */ if (pNewArray->size() == 0) { delete pNewArray; pNewArray = NULL; } else { qsort(pNewArray->base(), pNewArray->size(), pNewArray->blocksize() * sizeof(cell_t), sort_maps_in_adt_array); } change_serial = -1; } /* If there is still no array by this point, bail out. */ if (pNewArray == NULL) { *pSerial = -1; return NULL; } *pSerial = change_serial; /* If there is no input array, return something temporary. */ if (pUseArray == NULL) { if (free_new_array) { return pNewArray; } else { return pNewArray->clone(); } } /* Clear the input array if necessary. */ if ((flags & MAPLIST_FLAG_CLEARARRAY) == MAPLIST_FLAG_CLEARARRAY) { pUseArray->clear(); } /* Copy. */ cell_t *blk_dst; cell_t *blk_src; for (size_t i = 0; i < pNewArray->size(); i++) { blk_dst = pUseArray->push(); blk_src = pNewArray->at(i); strncopy((char *)blk_dst, (char *)blk_src, pUseArray->blocksize() * sizeof(cell_t)); } /* Free resources if necessary. */ if (free_new_array) { delete pNewArray; } /* Return the array we were given. */ return pUseArray; }
// native ArraySortEx(Array:array, const comparefunc[], data[]="", data_size=0); static cell AMX_NATIVE_CALL ArraySortEx(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; } int len; char* funcName = get_amxstring(amx, params[2], 0, len); int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); if (!func) { LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcName); return 0; } size_t arraysize = vec->size(); size_t blocksize = vec->blocksize(); cell *array = vec->base(); cell amx_addr1 = 0, amx_addr2 = 0, *phys_addr = NULL; if (blocksize > 1) { int err; if ((err = amx_Allot(amx, blocksize, &amx_addr1, &phys_addr)) != AMX_ERR_NONE || ( err = amx_Allot(amx, blocksize, &amx_addr2, &phys_addr)) != AMX_ERR_NONE) { LogError(amx, err, "Ran out of memory"); return 0; } } ArraySort_s oldinfo = SortInfo; SortInfo.func = func; SortInfo.array_base = array; SortInfo.array_bsize = static_cast<cell>(blocksize); SortInfo.array_hndl = params[1]; SortInfo.data = params[3]; SortInfo.size = params[4]; SortInfo.amx = amx; SortInfo.addr1 = amx_addr1; SortInfo.addr2 = amx_addr2; qsort(array, arraysize, blocksize * sizeof(cell), blocksize > 1 ? SortArrayListExArray : SortArrayListExCell); SortInfo = oldinfo; if (blocksize > 1) { amx_Release(amx, amx_addr1); amx_Release(amx, amx_addr2); } unregisterSPForward(func); return 1; }
CellArray *UpdateMapList(CellArray *pUseArray, const char *name, int *pSerial, unsigned int flags) { int change_serial; CellArray *pNewArray = NULL; bool success, free_new_array; free_new_array = false; if ((success = GetMapList(&pNewArray, name, &change_serial)) == false) { if ((flags & MAPLIST_FLAG_NO_DEFAULT) != MAPLIST_FLAG_NO_DEFAULT) { /* If this list failed, and it's not the default, try the default. */ if (strcmp(name, "default") != 0) { success = GetMapList(&pNewArray, name, &change_serial); } /* If either of the last two conditions failed, try again if we can. */ if (!success && strcmp(name, "mapcyclefile") != 0) { success = GetMapList(&pNewArray, "mapcyclefile", &change_serial); } } } /* If there was a success, and the serial has not changed, bail out. */ if (success && *pSerial == change_serial) { return NULL; } /** * If there was a success but no map list, we need to look in the maps folder. * If there was a failure and the flag is specified, we need to look in the maps folder. */ if ((success && pNewArray == NULL) || (!success && ((flags & MAPLIST_FLAG_MAPSFOLDER) == MAPLIST_FLAG_MAPSFOLDER))) { char path[255]; IDirectory *pDir; pNewArray = new CellArray(64); free_new_array = true; g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "maps"); if ((pDir = g_LibSys.OpenDirectory(path)) != NULL) { char *ptr; cell_t *blk; char buffer[PLATFORM_MAX_PATH]; while (pDir->MoreFiles()) { if (!pDir->IsEntryFile() || strcmp(pDir->GetEntryName(), ".") == 0 || strcmp(pDir->GetEntryName(), "..") == 0) { pDir->NextEntry(); continue; } strncopy(buffer, pDir->GetEntryName(), sizeof(buffer)); if ((ptr = strstr(buffer, ".bsp")) == NULL || ptr[4] != '\0') { pDir->NextEntry(); continue; } *ptr = '\0'; if (!engine->IsMapValid(buffer)) { pDir->NextEntry(); continue; } if ((blk = pNewArray->push()) == NULL) { pDir->NextEntry(); continue; } strncopy((char *)blk, buffer, 255); pDir->NextEntry(); } g_LibSys.CloseDirectory(pDir); } /* Remove the array if there were no items. */ if (pNewArray->size() == 0) { delete pNewArray; pNewArray = NULL; } else { qsort(pNewArray->base(), pNewArray->size(), pNewArray->blocksize() * sizeof(cell_t), sort_maps_in_adt_array); } change_serial = -1; } /* If there is still no array by this point, bail out. */ if (pNewArray == NULL) { *pSerial = -1; return NULL; } *pSerial = change_serial; /* If there is no input array, return something temporary. */ if (pUseArray == NULL) { if (free_new_array) { return pNewArray; } else { return pNewArray->clone(); } } /* Clear the input array if necessary. */ if ((flags & MAPLIST_FLAG_CLEARARRAY) == MAPLIST_FLAG_CLEARARRAY) { pUseArray->clear(); } /* Copy. */ cell_t *blk_dst; cell_t *blk_src; for (size_t i = 0; i < pNewArray->size(); i++) { blk_dst = pUseArray->push(); blk_src = pNewArray->at(i); strncopy((char *)blk_dst, (char *)blk_src, pUseArray->blocksize() * sizeof(cell_t)); } /* Free resources if necessary. */ if (free_new_array) { delete pNewArray; } /* Return the array we were given. */ return pUseArray; }