Added pseudo dynamic array natives.
Changed some of the "..." tags to "any".
This commit is contained in:
@ -41,6 +41,8 @@
|
||||
#include <sqlx>
|
||||
#endif
|
||||
|
||||
new Vector:AdminList;
|
||||
|
||||
new AdminCount;
|
||||
|
||||
new PLUGINNAME[] = "AMX Mod X"
|
||||
@ -108,6 +110,11 @@ public plugin_init()
|
||||
|
||||
server_cmd("exec %s/amxx.cfg", configsDir) // Execute main configuration file
|
||||
server_cmd("exec %s/sql.cfg", configsDir)
|
||||
|
||||
// Create a vector of 5 cells to store the info.
|
||||
AdminList=vector_create(5);
|
||||
|
||||
|
||||
#if defined USING_SQL
|
||||
server_cmd("amx_sqladmins")
|
||||
#else
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <messages>
|
||||
#include <vector>
|
||||
#include <sorting>
|
||||
#include <array>
|
||||
|
||||
/* Function is called just after server activation.
|
||||
* Good place for configuration loading, commands and cvars registration. */
|
||||
@ -97,16 +98,16 @@ native get_localinfo(const info[],output[],len);
|
||||
native show_motd(player,const message[],const header[]="");
|
||||
|
||||
/* Sends message to player. Set index to 0 to send text globaly. */
|
||||
native client_print(index,type,const message[],{Float,Sql,Result,_}:...);
|
||||
native client_print(index,type,const message[],any:...);
|
||||
|
||||
/* Sends message to player by engine. Set index to 0 to send text globaly. */
|
||||
native engclient_print(player,type,const message[],{Float,Sql,Result,_}:...);
|
||||
native engclient_print(player,type,const message[],any:...);
|
||||
|
||||
/* Sends message to console. */
|
||||
native console_print(id,const message[],{Float,Sql,Result,_}:...);
|
||||
native console_print(id,const message[],any:...);
|
||||
|
||||
/* Sends command to console. */
|
||||
native console_cmd(id,const cmd[],{Float,Sql,Result,_}:...);
|
||||
native console_cmd(id,const cmd[],any:...);
|
||||
|
||||
/* Registers event on which a given function will be called
|
||||
* Flags:
|
||||
@ -141,7 +142,7 @@ native register_logevent(const function[], argsnum, ... );
|
||||
native set_hudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2,channel=4);
|
||||
|
||||
/* Displays HUD message to given player. */
|
||||
native show_hudmessage(index,const message[],{Float,Sql,Result,_}:...);
|
||||
native show_hudmessage(index,const message[],any:...);
|
||||
|
||||
/* Displays menu. Keys have bit values (key 1 is (1<<0), key 5 is (1<<4) etc.). */
|
||||
native show_menu(index,keys,const menu[], time = -1, const title[] = "");
|
||||
@ -150,7 +151,7 @@ native show_menu(index,keys,const menu[], time = -1, const title[] = "");
|
||||
* When you are asking for string the array and length is needed (read_data(2,name,len)).
|
||||
* Integer is returned by function (new me = read_data(3)).
|
||||
* Float is set in second parameter (read_data(3,value)). */
|
||||
native read_data(value, {Float,Sql,Result,_}:... );
|
||||
native read_data(value, any:... );
|
||||
|
||||
/* Returns number of values in client message. */
|
||||
native read_datanum();
|
||||
@ -171,7 +172,7 @@ native parse_loguser(const text[], name[], nlen, &userid = -2, authid[] = "", al
|
||||
|
||||
/* Prints message to server console.
|
||||
* You may use text formating (f.e. server_print("%-32s %.2f!","hello",7.345)) */
|
||||
native server_print(const message[], {Float,Sql,Result,_}:...);
|
||||
native server_print(const message[], any:...);
|
||||
|
||||
/* Returns 1 or 0. */
|
||||
native is_map_valid(const mapname[]);
|
||||
@ -305,13 +306,13 @@ native user_kill(index,flag=0);
|
||||
* ... - optional parameters
|
||||
* Return value:
|
||||
* always 0 */
|
||||
native log_amx(const string[], {Float,Sql,Result,_}:...);
|
||||
native log_amx(const string[], any:...);
|
||||
|
||||
/* Sends message to standard HL logs. */
|
||||
native log_message(const message[],{Float,Sql,Result,_}:...);
|
||||
native log_message(const message[],any:...);
|
||||
|
||||
/* Sends log message to specified file. */
|
||||
native log_to_file(const file[],const message[],{Float,Sql,Result,_}:...);
|
||||
native log_to_file(const file[],const message[],any:...);
|
||||
|
||||
/* Returns number of players put in server.
|
||||
* If flag is set then also connecting are counted. */
|
||||
@ -367,7 +368,7 @@ native find_player(const flags[], ... );
|
||||
native remove_quotes(text[]);
|
||||
|
||||
/* Executes command on player. */
|
||||
native client_cmd(index,const command[],{Float,Sql,Result,_}:...);
|
||||
native client_cmd(index,const command[],any:...);
|
||||
|
||||
/* This is an emulation of a client command (commands aren't send to client!).
|
||||
* It allows to execute some commands on players and bots.
|
||||
@ -376,7 +377,7 @@ native client_cmd(index,const command[],{Float,Sql,Result,_}:...);
|
||||
native engclient_cmd(index,const command[],const arg1[]="",const arg2[]="");
|
||||
|
||||
/* Executes command on a server console. */
|
||||
native server_cmd(const command[],{Float,Sql,Result,_}:...);
|
||||
native server_cmd(const command[],any:...);
|
||||
|
||||
/* Sets a cvar to given value. */
|
||||
native set_cvar_string(const cvar[],const value[]);
|
||||
@ -991,7 +992,7 @@ native CreateHudSyncObj(num=0, ...);
|
||||
* You must use set_hudmessage, although the channel parameter is
|
||||
* entirely ignored.
|
||||
*/
|
||||
native ShowSyncHudMsg(target, syncObj, const fmt[], {Float,Sql,Result,_}:...);
|
||||
native ShowSyncHudMsg(target, syncObj, const fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Clears the display on a HudSync Object. This is essentially the same
|
||||
|
250
plugins/include/array.inc
Normal file
250
plugins/include/array.inc
Normal file
@ -0,0 +1,250 @@
|
||||
#if defined _array_included
|
||||
#endinput
|
||||
#endif
|
||||
|
||||
#define _array_included
|
||||
|
||||
/**
|
||||
* These arrays are intended to be used for a form of global storage without
|
||||
* requiring a #define that needs to be increased each time a person needs more
|
||||
* storage.
|
||||
* These are not designed to be used as a replacement for normal arrays, as
|
||||
* normal arrays are faster and should be used whenever possible.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a handle to a dynamically sized array.
|
||||
* It is very important that the cellsize you provide matches up with the buffer sizes
|
||||
* that you pass with subsequent Array{Get,Set,Push} calls.
|
||||
*
|
||||
* @param cellsize How many cells each entry in the array is.
|
||||
* @param reserved How many blank entries are created immediately when the array is created. These entries are not valid to read from until called with ArraySet.
|
||||
* @return Handle to the array.
|
||||
*/
|
||||
native Array:ArrayCreate(cellsize=1, reserved=32);
|
||||
|
||||
/**
|
||||
* Clears all entries from the array.
|
||||
*
|
||||
* @param which The array to clear.
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
native ArrayClear(Array:which);
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the array.
|
||||
*
|
||||
* @param which The array to check.
|
||||
* @return How many elements are in the array.
|
||||
*/
|
||||
native ArraySize(Array:which);
|
||||
|
||||
/**
|
||||
* Returns data within an array.
|
||||
* Make sure the output buffer matches the size the array was created with!
|
||||
*
|
||||
* @param which The array to retrieve the item from.
|
||||
* @param item The item to retrieve (zero-based).
|
||||
* @param output The output buffer to write.
|
||||
*/
|
||||
native ArrayGetArray(Array:which, item, any:output[]);
|
||||
|
||||
/**
|
||||
* Returns a single cell of data from an array.
|
||||
* Use this only with arrays that were created with a cellsize of 1!
|
||||
*
|
||||
* @param which The array to retrieve the item from.
|
||||
* @param item The item to retrieve (zero-based).
|
||||
* @param output The variable to store the value in.
|
||||
*/
|
||||
native ArrayGetCell(Array:which, item, &any:output);
|
||||
|
||||
/**
|
||||
* Returns a string value from an array.
|
||||
*
|
||||
* @param which The array to retrieve the item from.
|
||||
* @param item The item to retrieve (zero-based).
|
||||
* @param output The variable to store the value in.
|
||||
* @param size Character size of the output buffer.
|
||||
*/
|
||||
native ArrayGetString(Array:which, item, output[], size);
|
||||
|
||||
/**
|
||||
* Sets an item's data with that of a local buffer.
|
||||
* The buffer size must match what the cellsize that the array was created with!
|
||||
* The item must already exist, use ArrayPushArray to create a new item within the array.
|
||||
*
|
||||
* @param which The array to set the item from within.
|
||||
* @param item The item to set (zero-based).
|
||||
* @param input The input buffer to store.
|
||||
*/
|
||||
native ArraySetArray(Array:which, item, const any:input[]);
|
||||
|
||||
/**
|
||||
* Sets an array's single cell value. Use this only on array that were created with a cellsize of 1!
|
||||
* The item must already exist, use ArrayPushCell to create a new item within the array.
|
||||
*
|
||||
* @param which The array to set the item from within.
|
||||
* @param item The item to set (zero-based).
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArraySetCell(Array:which, item, any:input);
|
||||
|
||||
/**
|
||||
* Sets a string value from an array.
|
||||
* The stored string will be truncated if it is longer than the cellsize the array was created with!
|
||||
* The item must already exist, use ArrayPushString to create a new item within the array.
|
||||
*
|
||||
* @param which The array to set the item from within.
|
||||
* @param item The item to set (zero-based).
|
||||
* @param input The string to set the item as.
|
||||
*/
|
||||
native ArraySetString(Array:which, item, const input[]);
|
||||
|
||||
/**
|
||||
* Creates a new item at the end of the array and sets its data with that of a local buffer.
|
||||
* The buffer size must match what the cellsize that the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param input The input buffer to store.
|
||||
*/
|
||||
native ArrayPushArray(Array:which, const any:input[]);
|
||||
|
||||
/**
|
||||
* Creates a new item and sets the array's single cell value.
|
||||
* Use this only on array that were created with a cellsize of 1!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArrayPushCell(Array:which, any:input);
|
||||
|
||||
/**
|
||||
* Creates a new element in the array and sets its value to the input buffer.
|
||||
* The stored string will be truncated if it is longer than the cellsize the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param input The string to set the item as.
|
||||
*/
|
||||
native ArrayPushString(Array:which, const input[]);
|
||||
|
||||
/**
|
||||
* Inserts an item after the selected item. All items beyond it get shifted up 1 space.
|
||||
* The buffer size must match what the cellsize that the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert after.
|
||||
* @param input The input buffer to store.
|
||||
*/
|
||||
native ArrayInsertArrayAfter(Array:which, item, const any:input[]);
|
||||
|
||||
/**
|
||||
* Inserts an item after the selected item. All items beyond it get shifted up 1 space.
|
||||
* Use this only on an array that was created with a cellsize of 1!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert after.
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArrayInsertCellAfter(Array:which, item, any:input);
|
||||
|
||||
/**
|
||||
* Inserts an item after the selected item. All items beyond it get shifted up 1 space.
|
||||
* The stored string will be truncated if it is longer than the cellsize the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert after.
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArrayInsertStringAfter(Array:which, item, const input[]);
|
||||
|
||||
/**
|
||||
* Inserts an item before the selected item. All items beyond it, and the selected item get shifted up 1 space.
|
||||
* The buffer size must match what the cellsize that the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert before.
|
||||
* @param input The input buffer to store.
|
||||
*/
|
||||
native ArrayInsertArrayBefore(Array:which, item, const any:input[]);
|
||||
|
||||
/**
|
||||
* Inserts an item before the selected item. All items beyond it, and the selected item get shifted up 1 space.
|
||||
* Use this only on an array that was created with a cellsize of 1!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert after.
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArrayInsertCellBefore(Array:which, item, const any:input);
|
||||
|
||||
/**
|
||||
* Inserts an item before the selected item. All items beyond it, and the selected item get shifted up 1 space.
|
||||
* The stored string will be truncated if it is longer than the cellsize the array was created with!
|
||||
*
|
||||
* @param which The array to add the item to.
|
||||
* @param item The item to insert before.
|
||||
* @param input The value to set.
|
||||
*/
|
||||
native ArrayInsertStringBefore(Array:which, item, const input[]);
|
||||
|
||||
/**
|
||||
* Swaps the position of two items.
|
||||
*
|
||||
* @param which The array that contains the items.
|
||||
* @param item1 The first item to swap.
|
||||
* @param item2 The second item to swap.
|
||||
*/
|
||||
native ArraySwap(Array:which, item1, item2);
|
||||
|
||||
/**
|
||||
* Deletes an item from the array. All items beyond it get shifted down 1 space.
|
||||
*
|
||||
* @param which The array that contains the item to delete.
|
||||
* @param item The item to delete.
|
||||
*/
|
||||
native ArrayDeleteItem(Array:which, item);
|
||||
|
||||
/**
|
||||
* Creates a handle that is passable to a format compliant routine for printing as a string (with the %S parameter).
|
||||
* It is suggested to pass the function directly as a parameter to the format routine.
|
||||
* The array contents must be a null-terminated string!
|
||||
*
|
||||
* An example usage: client_print(id, print_chat, "%S", ArrayGetStringHandle(MessageArray, i));
|
||||
*
|
||||
* @param which The array the string is stored in.
|
||||
* @param item Which item to print the string value of.
|
||||
* @return Handle to the item directly. Do not use or save stale handles.
|
||||
*/
|
||||
native DoNotUse:ArrayGetStringHandle(Array:which, item);
|
||||
|
||||
/**
|
||||
* Destroys the array, and resets the handle to 0 to prevent accidental usage after it is destroyed.
|
||||
*
|
||||
* @param which The array to destroy.
|
||||
*/
|
||||
native ArrayDestroy(&Array:which);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Similar to sorting.inc's CustomSort.
|
||||
* The sorting algorithm then uses your comparison function to sort the data.
|
||||
* The function is called in the following manner:
|
||||
*
|
||||
* public MySortFunc(Array:array, item1, item2, const data[], data_size)
|
||||
*
|
||||
* array - Array handle in its current un-sorted state.
|
||||
* item1, item2 - Current item pair being compared
|
||||
* data[] - Extra data array you passed to the sort func.
|
||||
* data_size - Size of extra data you passed to the sort func.
|
||||
*
|
||||
* Your function should return:
|
||||
* -1 if item1 should go before item2
|
||||
* 0 if item1 and item2 are equal
|
||||
* 1 if item1 should go after item2
|
||||
* Note that the parameters after item2 are all optional and you do not need to specify them.
|
||||
*
|
||||
* Note that unlike the sorting.inc versions, the array passed to the callback is not in mid-sorted state.
|
||||
*/
|
||||
native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0);
|
@ -22,7 +22,7 @@
|
||||
#pragma library engine
|
||||
#endif
|
||||
|
||||
native traceresult(type,{Float,Sql,Result,_}:...);
|
||||
native traceresult(type,any:...);
|
||||
|
||||
/* Registers a client impulse to a function. Function is passed the ID of the user. */
|
||||
native register_impulse(impulse, const function[]);
|
||||
@ -39,7 +39,7 @@ native register_think(const Classname[], const function[]);
|
||||
*/
|
||||
|
||||
/* Precaches an event. */
|
||||
native precache_event(type, const Name[], {Float,Sql,Result,_}:...);
|
||||
native precache_event(type, const Name[], any:...);
|
||||
|
||||
/* set/get a user's speak flags */
|
||||
native set_speak(iIndex, iSpeakFlags);
|
||||
@ -174,11 +174,11 @@ native playback_event(flags,invoker,eventindex,Float:delay,const Float:origin[3]
|
||||
/* Gets parameters sent from CmdStart.
|
||||
Note that you will receive modified values if any other plugin have
|
||||
changed them. */
|
||||
native get_usercmd(type,{Float,Sql,Result,_}:...);
|
||||
native get_usercmd(type,any:...);
|
||||
|
||||
/* Sets the parameters sent from CmdStart.
|
||||
Note that your changes will be seen by any other plugin doing get_usercmd() */
|
||||
native set_usercmd(type,{Float,Sql,Result,_}:...);
|
||||
native set_usercmd(type,any:...);
|
||||
|
||||
/* Converts a string offset into a real string. Some of the forwards in fakemeta
|
||||
uses string offsets. (FM_CreateNamedEntity) */
|
||||
|
@ -31,10 +31,10 @@
|
||||
* new ptr, classname[32]
|
||||
* pev(entid, pev_classname, ptr, classname, 31)
|
||||
*/
|
||||
native pev(_index,_value,{Float,Sql,Result,_}:...);
|
||||
native pev(_index,_value,any:...);
|
||||
|
||||
/* Sets entvar data for an entity. Use the pev_* enum */
|
||||
native set_pev(_index,_value,{Float,Sql,Result,_}:...);
|
||||
native set_pev(_index,_value,any:...);
|
||||
|
||||
/* returns 0 if ent is invalid, >0 if valid
|
||||
* (1 == valid, 2 == valid+pvPrivateData valid)
|
||||
@ -50,7 +50,7 @@ native pev_valid(entindex);
|
||||
* new ptr = pev(id, pev_viewmodel)
|
||||
* global_get(glb_pStringBase, ptr, model, 127)
|
||||
*/
|
||||
native global_get(_value, {Float,Sql,Result,_}:...);
|
||||
native global_get(_value, any:...);
|
||||
|
||||
/* Returns an integer from private data. _linuxdiff is added into the _Offset if it's used on a linux server. */
|
||||
native get_pdata_int(_index,_Offset,_linuxdiff=5);
|
||||
@ -77,7 +77,7 @@ native register_forward(_forwardType,const _function[],_post=0);
|
||||
native unregister_forward(_forwardType, registerId, post=0);
|
||||
|
||||
/* Returns data for metamod */
|
||||
native forward_return(type,{Float,Sql,Result,_}:...);
|
||||
native forward_return(type,any:...);
|
||||
|
||||
/* Returns the original return value of an engine function.
|
||||
* This is only valid in forwards that were registered as post.
|
||||
@ -89,7 +89,7 @@ native forward_return(type,{Float,Sql,Result,_}:...);
|
||||
native get_orig_retval({Float,_}:...);
|
||||
|
||||
native engfunc(type,{Float,Sql,Result,AlertType,_}:...);
|
||||
native dllfunc(type,{Float,Sql,Result,_}:...);
|
||||
native dllfunc(type,any:...);
|
||||
|
||||
//only use this with functions that pass a Trace
|
||||
// get: zero extra params - return int, one extra param = byref float or vector
|
||||
|
@ -83,7 +83,7 @@ native fgets(file, buffer[], maxlength);
|
||||
native fputs(file, const text[]);
|
||||
|
||||
//Writes a line to the file
|
||||
native fprintf(file, const fmt[], {Float,Sql,Result,_}:...);
|
||||
native fprintf(file, const fmt[], any:...);
|
||||
|
||||
//Sets the current position in a file (see SEEK_ values above)
|
||||
native fseek(file, position, start);
|
||||
@ -97,7 +97,7 @@ native fputc(file, data);
|
||||
native fungetc(file, data);
|
||||
|
||||
//Return the size of a file
|
||||
native filesize(const filename[], {Float,Sql,Result,_}:...);
|
||||
native filesize(const filename[], any:...);
|
||||
|
||||
//Attempts to remove a directory.
|
||||
//Note that you cannot remove a directory that has files on most
|
||||
|
@ -18,7 +18,7 @@ stock is_entity(id)
|
||||
return is_valid_ent(id);
|
||||
|
||||
/* The end of the native is buffered incase the plugin is including an NS_VERSION (no longer supported), ignore it */
|
||||
stock get_build(classname[], value, number=0,{Float,Sql,Result,_}:...)
|
||||
stock get_build(classname[], value, number=0,any:...)
|
||||
return ns_get_build(classname, value, number);
|
||||
|
||||
stock get_private_i(index, offset, linuxdiff=5)
|
||||
|
@ -34,7 +34,7 @@ native add(dest[],len,const src[],max=0);
|
||||
* slower, so you should using a source string that is the same as
|
||||
* the destination.
|
||||
*/
|
||||
native format(output[] ,len ,const format[] , {Float,Sql,Result,_}:...);
|
||||
native format(output[] ,len ,const format[] , any:...);
|
||||
|
||||
/* Same as format(), except does not perform a "copy back" check.
|
||||
* This means formatex() is faster, but DOES NOT ALLOW this type
|
||||
@ -45,7 +45,7 @@ native format(output[] ,len ,const format[] , {Float,Sql,Result,_}:...);
|
||||
* This is because the output is directly stored into "buffer",
|
||||
* rather than copied back at the end.
|
||||
*/
|
||||
native formatex(output[] ,len ,const format[] , {Float,Sql,Result,_}:...);
|
||||
native formatex(output[] ,len ,const format[] , any:...);
|
||||
|
||||
/* Replacement for format_args. Much faster and %L compatible.
|
||||
* This works exactly like vsnprintf() from C.
|
||||
|
456
plugins/testsuite/arraytest.sma
Normal file
456
plugins/testsuite/arraytest.sma
Normal file
@ -0,0 +1,456 @@
|
||||
#include <amxmodx>
|
||||
|
||||
|
||||
new __testnumber;
|
||||
new errcount;
|
||||
new __testfunc[32];
|
||||
new __testfuncnum;
|
||||
|
||||
enum TestType
|
||||
{
|
||||
TT_Equal = 0,
|
||||
TT_LessThan,
|
||||
TT_GreaterThan,
|
||||
TT_LessThanEqual,
|
||||
TT_GreaterThanEqual,
|
||||
TT_NotEqual
|
||||
};
|
||||
|
||||
new TestWords[6][] = {
|
||||
"==",
|
||||
"<",
|
||||
">",
|
||||
"<=",
|
||||
">=",
|
||||
"!="
|
||||
};
|
||||
|
||||
|
||||
|
||||
stock test(A,B=0,TestType:Type=TT_Equal)
|
||||
{
|
||||
++__testnumber;
|
||||
|
||||
new passed=0;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case TT_Equal: if (A==B) passed=1;
|
||||
case TT_LessThan: if (A<B) passed=1;
|
||||
case TT_GreaterThan: if (A>B) passed=1;
|
||||
case TT_LessThanEqual: if (A<=B) passed=1;
|
||||
case TT_GreaterThanEqual: if (A>=B) passed=1;
|
||||
case TT_NotEqual: if (A!=B) passed=1;
|
||||
}
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
log_amx("Failed test #%d (%d %s %d)",__testnumber,A,TestWords[_:Type],B);
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
stock starttests(const startfunc[])
|
||||
{
|
||||
__testnumber=0;
|
||||
errcount=0;
|
||||
__testfuncnum=1;
|
||||
server_print("Starting tests...");
|
||||
formatex(__testfunc,sizeof(__testfunc)-1,"%s",startfunc);
|
||||
|
||||
new func[32];
|
||||
formatex(func,sizeof(func)-1,"%s%d",__testfunc,__testfuncnum++);
|
||||
set_task(0.1,func);
|
||||
}
|
||||
|
||||
stock showres()
|
||||
{
|
||||
if (errcount==0)
|
||||
{
|
||||
new func[32];
|
||||
formatex(func,sizeof(func)-1,"%s%d",__testfunc,__testfuncnum++);
|
||||
if (get_func_id(func)==-1)
|
||||
{
|
||||
server_print("All tests ok!");
|
||||
}
|
||||
else
|
||||
{
|
||||
server_print("Test ok, moving on...");
|
||||
|
||||
set_task(0.1,func);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
server_print("Test failed, aborting.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_srvcmd("arraytest","arraytest");
|
||||
}
|
||||
|
||||
public arraytest()
|
||||
{
|
||||
starttests("arraytest");
|
||||
}
|
||||
public arraytest1()
|
||||
{
|
||||
server_print("Testing 1000 iterations of 1-cell arrays...");
|
||||
|
||||
new Float:f;
|
||||
new Array:a=ArrayCreate(1);
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
f=float(i);
|
||||
ArrayPushCell(a,f);
|
||||
}
|
||||
new Float:r;
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
f=float(i);
|
||||
ArrayGetCell(a,i,r);
|
||||
|
||||
// This is normally bad for float "casting", but in this case it should be fine.
|
||||
test(_:f, _:r);
|
||||
|
||||
|
||||
// Reset with inversed values
|
||||
new g=_:f;
|
||||
g=~g;
|
||||
|
||||
ArraySetCell(a,i,g);
|
||||
|
||||
ArrayGetCell(a,i,r);
|
||||
|
||||
test(g, _:r);
|
||||
|
||||
}
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
stock bool:checkarray(const a[], const b[], size)
|
||||
{
|
||||
while (size--)
|
||||
{
|
||||
if (a[size]!=b[size])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
stock invarray(a[],size)
|
||||
{
|
||||
while (size--)
|
||||
{
|
||||
a[size] = ~a[size];
|
||||
}
|
||||
|
||||
}
|
||||
public arraytest2()
|
||||
{
|
||||
server_print("Testing 1000 iterations of 40-cell arrays...");
|
||||
|
||||
new Array:a=ArrayCreate(40);
|
||||
new buff[40];
|
||||
new buffb[40];
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
arrayset(buff,i,sizeof(buff));
|
||||
|
||||
ArrayPushArray(a, buff);
|
||||
}
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
arrayset(buff, i, sizeof(buff));
|
||||
|
||||
ArrayGetArray(a, i, buffb);
|
||||
|
||||
test(_:checkarray(buff,buffb,sizeof(buff)),1);
|
||||
|
||||
// Now overwrite the array with inversed value
|
||||
invarray(buff,sizeof(buff));
|
||||
|
||||
ArraySetArray(a, i, buff);
|
||||
|
||||
ArrayGetArray(a, i, buffb);
|
||||
|
||||
test(_:checkarray(buff,buffb,sizeof(buff)),1);
|
||||
}
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
public arraytest3()
|
||||
{
|
||||
server_print("Testing 1000 iterations of strings...");
|
||||
|
||||
// The string is 10 long, the string we're trying to pass is 20 long.
|
||||
|
||||
new Array:a=ArrayCreate(10);
|
||||
|
||||
new buff[20]="1234567890abcdefghi";
|
||||
new buffb[20];
|
||||
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
ArrayPushString(a, buff);
|
||||
}
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
ArrayGetString(a, i, buffb, sizeof(buffb)-1);
|
||||
|
||||
test(strcmp(buffb,"123456789"),0);
|
||||
|
||||
ArraySetString(a, i, "9876543210");
|
||||
|
||||
ArrayGetString(a, i, buffb, sizeof(buffb)-1);
|
||||
|
||||
test(strcmp(buffb,"987654321"),0);
|
||||
|
||||
buffb[0]=0;
|
||||
|
||||
formatex(buffb,sizeof(buffb)-1,"%S", ArrayGetStringHandle(a, i));
|
||||
|
||||
test(strcmp(buffb, "987654321"),0);
|
||||
}
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
|
||||
public sortcallback(Array:a, b, c)
|
||||
{
|
||||
static stra[40];
|
||||
static strb[40];
|
||||
|
||||
ArrayGetString(a, b, stra, sizeof(stra)-1);
|
||||
ArrayGetString(a, c, strb, sizeof(strb)-1);
|
||||
return strcmp(stra,strb);
|
||||
}
|
||||
public arraytest4()
|
||||
{
|
||||
server_print("Testing sorting function...");
|
||||
|
||||
new Array:a=ArrayCreate(40);
|
||||
|
||||
ArrayPushString(a, "z");
|
||||
ArrayPushString(a, "yz");
|
||||
ArrayPushString(a, "xyz");
|
||||
ArrayPushString(a, "wxyz");
|
||||
ArrayPushString(a, "vwxyz");
|
||||
ArrayPushString(a, "uvwxyz");
|
||||
ArrayPushString(a, "tuvwxyz");
|
||||
ArrayPushString(a, "stuvwxyz");
|
||||
ArrayPushString(a, "rstuvwxyz");
|
||||
ArrayPushString(a, "qrstuvwxyz");
|
||||
ArrayPushString(a, "pqrstuvwxyz");
|
||||
ArrayPushString(a, "opqrstuvwxyz");
|
||||
ArrayPushString(a, "nopqrstuvwxyz");
|
||||
ArrayPushString(a, "mnopqrstuvwxyz");
|
||||
ArrayPushString(a, "lmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "klmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "jklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "ijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "hijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "ghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "fghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "efghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "defghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "cdefghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "bcdefghijklmnopqrstuvwxyz");
|
||||
ArrayPushString(a, "abcdefghijklmnopqrstuvwxyz");
|
||||
|
||||
new OldSize=ArraySize(a);
|
||||
|
||||
ArraySort(a, "sortcallback");
|
||||
|
||||
test(ArraySize(a),OldSize);
|
||||
|
||||
new buff[40];
|
||||
|
||||
ArrayGetString(a,0,buff,sizeof(buff)-1);
|
||||
|
||||
test(strcmp(buff,"abcdefghijklmnopqrstuvwxyz"),0);
|
||||
|
||||
ArrayGetString(a,25,buff,sizeof(buff)-1);
|
||||
|
||||
test(strcmp(buff,"z"),0);
|
||||
|
||||
|
||||
new start='a';
|
||||
|
||||
for (new i=0;i<OldSize;i++)
|
||||
{
|
||||
ArrayGetString(a,i,buff,sizeof(buff)-1)
|
||||
|
||||
test(buff[0],start++);
|
||||
}
|
||||
|
||||
showres();
|
||||
}
|
||||
public arraytest5()
|
||||
{
|
||||
server_print("Testing ArrayDeleteItem()...");
|
||||
new Array:a=ArrayCreate(1);
|
||||
|
||||
new v;
|
||||
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
ArrayPushCell(a, i);
|
||||
}
|
||||
for (new i=ArraySize(a) - 1; i>=0 ; i--)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
ArrayDeleteItem(a, i);
|
||||
}
|
||||
}
|
||||
test(ArraySize(a), 500);
|
||||
for (new i=0; i< 500; i++)
|
||||
{
|
||||
ArrayGetCell(a, i, v);
|
||||
|
||||
// All items should be incrementing odd numbers
|
||||
test(((i + 1) * 2) - 1, v);
|
||||
|
||||
// All remaining entries should be odd
|
||||
test((v & 1), 1);
|
||||
}
|
||||
ArrayDestroy(a);
|
||||
|
||||
a=ArrayCreate(1);
|
||||
// Repeat the same test, but check even numbers
|
||||
for (new i=0; i<1000; i++)
|
||||
{
|
||||
ArrayPushCell(a, i);
|
||||
}
|
||||
for (new i=ArraySize(a) - 1; i>=0 ; i--)
|
||||
{
|
||||
if (i % 2 == 1)
|
||||
{
|
||||
ArrayDeleteItem(a, i);
|
||||
}
|
||||
}
|
||||
test(ArraySize(a), 500);
|
||||
for (new i=0; i< 500; i++)
|
||||
{
|
||||
ArrayGetCell(a, i, v);
|
||||
|
||||
// All items should be incrementing even numbers
|
||||
test(((i + 1) * 2) - 2, v);
|
||||
|
||||
// All remaining entries should be even
|
||||
test((v & 1), 0);
|
||||
}
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
public arraytest6()
|
||||
{
|
||||
server_print("Testing ArrayInsertCellAfter()...");
|
||||
|
||||
new Array:a=ArrayCreate(1);
|
||||
|
||||
for (new i=0; i<10;i++)
|
||||
{
|
||||
ArrayPushCell(a, i);
|
||||
new item=ArraySize(a)-1;
|
||||
for (new j=0; j<10; j++)
|
||||
{
|
||||
ArrayInsertCellAfter(a, item + j, j);
|
||||
}
|
||||
}
|
||||
|
||||
test(ArraySize(a), 110);
|
||||
|
||||
new v;
|
||||
for (new i=0; i<110; i++)
|
||||
{
|
||||
ArrayGetCell(a, i, v);
|
||||
|
||||
test(v, i / 10);
|
||||
for (new j=0; j<10; j++)
|
||||
{
|
||||
ArrayGetCell(a, ++i, v);
|
||||
test(v, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
public arraytest7()
|
||||
{
|
||||
server_print("Testing ArrayInsertCellBefore()...");
|
||||
|
||||
new Array:a=ArrayCreate(1);
|
||||
|
||||
for (new i=0; i<10;i++)
|
||||
{
|
||||
ArrayPushCell(a, i);
|
||||
new item=ArraySize(a)-1;
|
||||
for (new j=0; j<10; j++)
|
||||
{
|
||||
ArrayInsertCellBefore(a, item, j);
|
||||
}
|
||||
}
|
||||
|
||||
test(ArraySize(a), 110);
|
||||
|
||||
new v;
|
||||
for (new i=0; i<110; i++)
|
||||
{
|
||||
for (new j=9; j>=0; j--)
|
||||
{
|
||||
ArrayGetCell(a, i++, v);
|
||||
test(v, j);
|
||||
}
|
||||
|
||||
ArrayGetCell(a, i, v);
|
||||
|
||||
test(v, (i - 10) / 10);
|
||||
}
|
||||
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
||||
public arraytest8()
|
||||
{
|
||||
server_print("Testing ArraySwap()...");
|
||||
new Array:a=ArrayCreate(1);
|
||||
|
||||
for (new i=0; i<10; i++)
|
||||
{
|
||||
ArrayPushCell(a, i);
|
||||
}
|
||||
for (new i=0; i<5; i++)
|
||||
{
|
||||
ArraySwap(a, i, (10 - (i + 1)));
|
||||
}
|
||||
new v;
|
||||
for (new i=0; i<5; i++)
|
||||
{
|
||||
ArrayGetCell(a, i, v);
|
||||
|
||||
test(v, (10 - (i + 1)));
|
||||
}
|
||||
|
||||
ArrayDestroy(a);
|
||||
|
||||
showres();
|
||||
}
|
Reference in New Issue
Block a user