| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760 |
- /**--------------------------------------------------------------------------**\
- ================================
- Y Sever Includes - Commands Core
- ================================
- Description:
- Runs commands registered with the system and calls the required functions.
- Also handles alternate names and prefixes. Based very loosely on dcmd.
- Legal:
- Version: MPL 1.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is the YSI commands include.
-
- The Initial Developer of the Original Code is Alex "Y_Less" Cole.
- Portions created by the Initial Developer are Copyright (C) 2011
- the Initial Developer. All Rights Reserved.
-
- Contributors:
- ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
-
- Thanks:
- JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
- ZeeX - Very productive conversations.
- koolk - IsPlayerinAreaEx code.
- TheAlpha - Danish translation.
- breadfish - German translation.
- Fireburn - Dutch translation.
- yom - French translation.
- 50p - Polish translation.
- Zamaroht - Spanish translation.
- Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
- for me to strive to better.
- Pixels^ - Running XScripters where the idea was born.
- Matite - Pestering me to release it and using it.
-
- Very special thanks to:
- Thiadmer - PAWN, whose limits continue to amaze me!
- Kye/Kalcor - SA:MP.
- SA:MP Team past, present and future - SA:MP.
-
- Version:
- 0.1.4
- Changelog:
- 20/10/10:
- Fixed a bug with insensitive commands - my fault for not testing.
- 06/01/08:
- Improved master and /help support.
- 04/01/08:
- Fixed bad element in Command_SetDeniedReturn.
- 12/08/07:
- Added master support.
- 24/06/07:
- Modifed a few functions to use Bit_GetBit for speed.
- 04/05/07:
- Completed command use support.
- Added invalid character protection.
- 02/05/07:
- Added YSI_ prefix to all globals.
- 14/04/07:
- Updated header documentation with more than changelog/functions.
- Added function name requesting.
- 13/04/07:
- Added function documentation.
- Added wrapped functions for e_COMM_FLAG values missing them.
- Added header function list.
- 12/04/07:
- Added command removal.
- 11/04/07:
- Changed system slightly to handle names and alt names separately. Still
- need a better way of ignoring names when alt names are used.
- 10/04/07:
- First version.
- Functions:
- Public:
- Command_Add - Adds a command to the array for processing.
- Command_Remove - Removes a command.
- Command_Name - Gets the name of a command in a property.
- Core:
- Command_Process - Called from OnPlayerCommandText to process entered commands.
- Command_Parse - Sorts added commands into a binary tree.
- Command_Hash - Hashes a word for command hashing.
- Command_ProcRem - Processes a help command in the master script.
- Stock:
- Command_SetDisconnectReturn - Sets the return value for unconnected players.
- Command_UseShortCuts - Toggles use of per-player command shortcuts.
- Command_SetDeniedReturn - Sets the return value for denied use commands.
- Command_UseDeniedMessage - Toggles the use of an error message for denied.
- Command_SetIllegalReturn - Sets the return value for illegal characters.
- Command_UseAltNames - Toggles the use of ini defined alternate names.
- Command_UsePrefix - Toggles the use of a global prefix.
- Command_UseSpace - Toggles the use of a space between prefix and command.
- Command_SetAltName - Sets the alternate name of a function.
- Command_SetPrefix - Sets the pfexix to be typed.
- Comamnd_SetPlayerUse - Sets wether or not a player can use a command.
- Comamnd_SetPlayerUseByID - Sets wether or not a player can use a command.
- Command_FindByName - Finds a command in a possibly sorted list.
- Static:
- Command_FindFast - Finds a function by binary search of function name.
- Command_FindAlt - Finds a function by binary search of alternate name.
- Command_SetSorted - Marks the binary tree as sorted.
- Command_FindSlow - Finds a function by linear search of function name.
- Command_Find - Finds a function from entered text.
- Command_Prefix - Checks the entered prefix.
- Command_ReturnName - Returns the name of a function.
- Command_GetPlayerCount - Gets the number of commands a player can use.
- Inline:
- Command_Command - Not used, constructor.
- Command_IsCleared - Checks a player is cleared to use a command.
- Command_DisconnectReturn - Gets the return value for disconnected players.
- Command_UsingShortCuts - Checks if short cuts are being used.
- Command_DeniedReturn - Gets the return value for prohibited commands.
- Command_IllegalReturn - Gets the return value for invalid characters.
- Command_DeniedMessage - Checks if a level error message should be sent.
- Command_IsSorted - Checks if the binary tree has been initialised.
- Command_UsingAltNames - Checks if alt names are being used.
- Command_UsingPrefix - Checks if the prefix is being used.
- Command_UsingSpace - Checks if the space option is being used.
- Command_CallFunction - Calls the required function.
- ycmd - Adds a command to the system.
- API:
- -
- Callbacks:
- -
- Definitions:
- MAX_COMMAND_LENGTH - The maximum length of a command string.
- COMMAND_NOT_FOUND - Indicates that a searched for string is not a function.
- Enums:
- e_COMM_FLAG - Bit mappings for command options.
- E_COMMANDS - Structure of the array holding the string data.
- Macros:
- Command_(%1) - Forwards and declares a standard command for calling.
- ycmd(%1) - Adds a command to the array (wrapper for Command_Add).
- Tags:
- e_COMM_FLAG - Flag type.
- Variables:
- Global:
- -
- Static:
- YSI_g_sCommands - Holds all the textual data of the commands.
- YSI_g_sSearchTree - Tree of hashes for function names.
- YSI_g_sAltTree - Tree of hashes for alternate names.
- YSI_g_sPrefix - The command prefix.
- YSI_g_sPrefixLength - Length of the prefix.
- YSI_g_sCommandIndex - Pointer to the next free index in the function array.
- YSI_g_sAltCount - The number of commands with altnames.
- YSI_g_sCommandFlags - Bit array of command options.
- Commands:
- commands - Lists all commands available to you.
- Compile options:
- COMMAND_SENSITIVE - Make commands case sensitive.
- COMMAND_ACCURATE - Can use '@' in command names.
- MAX_COMMANDS - The maximum number of commands which can be used.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if defined _INC_y_text
- #error y_commands must be included before y_text
- #endif
- #include "internal\y_version"
- #if !defined MAX_COMMANDS
- #define MAX_COMMANDS (1024)
- #endif
- #define _GROUP_MAKE_NAME_CMD<%0...%1> %0Command%1
- #define _GROUP_MAKE_LIMIT_CMD MAX_COMMANDS
- #define YSIM_U_DISABLE
- #include "y_master"
- #include "y_groups"
- #include "y_debug"
- #include "y_hooks"
- #include "y_bintree"
- #include "y_amx"
- #include "y_playerarray"
- #include "y_utils"
- #include "internal\y_natives"
- // Define the CMD: macro. This uses the prefix "@yC_" as it's 32 bits so allows
- // for fast command string searching in the publics table and makes the commands
- // public without the need for the public keyword.
- /*#if YSIM_HAS_MASTER
- #if _YSIM_IS_CLIENT
- #define YCMD:%1(%2) static stock @_yC%1(%2)
- #else
- #if _YSIM_IS_SERVER
- #define YCMD:%1(%2) @yC_%1(a,b[],c);@yC_%1(a,b[],c)U@(8,YSIM_RETURN,@_yC%1(a,b,c));static @_yC%1(%2)
- #else
- #define YCMD:%1(%2) @yC_%1(a,b[],c);@yC_%1(a,b[],c)<>{}@yC_%1(a,b[],c)<_YCM:y>U@(8,YSIM_RETURN,@_yC%1(a,b,c));static @_yC%1(%2)
- #endif
- #endif
- #else
- #define YCMD:%1(%2) @yC_%1(%2);@yC_%1(%2)
- #endif*/
- //#define YCMD:%0(%1) RC:%0(%1)
- #define _YCMD_0:_YCMD_1:_YCMD_2:%0(%1[]%2) RC:%0(%1[]%2)
- #define _YCMD_1:_YCMD_2:%0, Command_GetID(#%0),
- #define _YCMD_2:%0) Command_GetID(#%0))
- #define @YCMD:%0; Command_TouchNamed(#%0);
- #define YCMD: _YCMD_0:_YCMD_1:_YCMD_2:
- // ZCMD compatibility.
- #define CMD:%0(%1) RC:%0(%1,__help)if(__help)return 0;else
- #define COMMAND CMD
- // This is opposite AMX_FastString as that's in C, not packed, order.
- #define Command_FastString(%1,%2,%3,%4) \
- (((%1)<<24)|((%2)<<16)|((%3)<<8)|((%4)<<0))
- #define MAX_COMMAND_LENGTH (32)
- #define COMMAND_NOT_FOUND (-1)
- #if defined COMMAND_SENSITIVE
- #define TOLOWER(%0) (%0)
- #define COMMAND_END_CMP (0)
- #else
- //#if defined COMMAND_ACCURATE
- // #define TOLOWER(%0) ((%0) | 0x20)
- // #define COMMAND_END_CMP (0x20)
- //#else
- #define TOLOWER(%0) tolower(%0)
- #define COMMAND_END_CMP (0)
- //#endif
- #endif
- // Don't forget the AMX_FastString below if you change this.
- #define COMMAND_FUNCTION_PREFIX (Command_FastString('@', 'y', 'C', '_'))
- // Reset both of these when you remove a command.
- #define _Command_IsValid(%0) ((Command_GetPointer(%0)==(%0))||(YSI_g_sCommands[(%0)][E_COMMANDS_MASTERS]==-1))
- #define Command_IsValid(%0) ((0<=(%0)<MAX_COMMANDS)&&_Command_IsValid(%0))
- enum e_COMM_FLAG (<<= 1)
- {
- e_COMM_FLAG_PROVIDER = 0x000000FF,
- e_COMM_FLAG_SORTED = 0x00000100,
- e_COMM_FLAG_PERMISSION_WARN,
- e_COMM_FLAG_USE_ALTNAMES,
- e_COMM_FLAG_PERMISSION_RET,
- e_COMM_FLAG_USE_PREFIX,
- e_COMM_FLAG_USE_SPACE,
- e_COMM_FLAG_USE_SHORTCUTS,
- e_COMM_FLAG_DISCONNECT,
- e_COMM_FLAG_ILLEGAL,
- e_COMM_FLAG_COLLISION,
- e_COMM_FLAG_UNKNOWN,
- e_COMM_FLAG_MULPRO,
- // Can't easilly add more flags now...
- e_COMM_FLAG_OPCP = 0x07C00000, // 0b00000111110..0
- e_COMM_FLAG_OPCP_ADD = 0x00400000, // Low bit of above flag.
- e_COMM_FLAG_OPCR = 0xF8000000, // 0b11111000000..0
- e_COMM_FLAG_OPCR_ADD = 0x08000000 // Low bit of above flag.
- }
- enum E_COMMANDS
- {
- E_COMMANDS_FUNCTION[MAX_COMMAND_LENGTH char],
- PlayerArray:E_COMMANDS_PLAYERS<MAX_PLAYERS>,
- #if YSIM_HAS_MASTER
- E_COMMANDS_MASTERS,
- #endif
- E_COMMANDS_FUNC_POINTER
- //E_COMMANDS_AMX_ADDRESS,
- }
- static stock
- #if YSIM_HAS_MASTER
- YSI_g_sPlayerProvider[MAX_PLAYERS char] = {-1, ...},
- #endif
- YSI_g_sCommands[MAX_COMMANDS][E_COMMANDS],
- BinaryTree:YSI_g_sSearchTree<MAX_COMMANDS>,
- e_COMM_FLAG:YSI_g_sCommandFlags = e_COMM_FLAG:0xFF,
- YSI_g_sCommandIndex,
- YSI_g_sCommandCount;
- /**--------------------------------------------------------------------------**\
- <summary>Command_Name</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the name of a function from the array.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_Name(%1) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_FUNCTION][1])
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetFuncName</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the full function name for a slot - note that this may not be the right
- function if this slot points to another one.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_GetFuncName(%1) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_FUNCTION])
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetPointer</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the pointer for a function from the array.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- #define Command_GetPointer(%1) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_FUNC_POINTER]&0x00FFFFFF)
- #else
- #define Command_GetPointer(%1) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_FUNC_POINTER])
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetProvider</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the unique script in which this version of the command is.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- #define Command_Provider(%1) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_FUNC_POINTER]>>>24)
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetProvider</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the unique script in which this version of the command is.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- #define Command_DefaultProvider() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_PROVIDER)
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetFunction</summary>
- <param name="index">Index of the command to operate on.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the real function for this slot.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_GetFunction(%1) \
- (Command_GetFuncName(Command_GetPointer((%1))))
- /**--------------------------------------------------------------------------**\
- <summary>Command_CheckPlayer</summary>
- <param name="index">Index of the command to operate on.</param>
- <param name="playerid">The player to check for.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets wether a player can use a command.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_CheckPlayer(%1,%2) \
- (YSI_g_sCommands[(%1)][E_COMMANDS_PLAYERS][Bit_Slot(%2)+1]&Bit_Mask(%2))
- //(PA=([E_COMMANDS_PLAYERS], (%2)))
- //(Bit_Get(YSI_g_sCommands[(%1)][E_COMMANDS_PLAYERS], (%2)))
- /**--------------------------------------------------------------------------**\
- <summary>Command_DeniedReturn</summary>
- <returns>
- e_COMM_FLAG_PERMISSION_RET
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_DeniedReturn() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_PERMISSION_RET)
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetDeniedReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetDeniedReturn(bool:set);
- global void:Command_SetDeniedReturn(bool:set)
- {
- P:2("Command_SetDeniedReturn called: %i", bool:set);
- if (set)
- {
- YSI_g_sCommandFlags |= e_COMM_FLAG_PERMISSION_RET;
- }
- else
- {
- YSI_g_sCommandFlags &= ~e_COMM_FLAG_PERMISSION_RET;
- }
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetProvider</summary>
- <param name="p">Script.</param>
- <returns>
- -
- </returns>
- <remarks>
- Set the current provider to use for all commands being added. Basically
- allows us to have the same command name in different scripts and have them
- do different things, with different players targetting different ones.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- foreign void:Command_SetProvider(p);
-
- global void:Command_SetProvider(p)
- {
- P:2("Command_SetProvider called: %i", p);
- YSI_g_sCommandFlags = (YSI_g_sCommandFlags & ~e_COMM_FLAG_PROVIDER) | (e_COMM_FLAG:p & e_COMM_FLAG_PROVIDER) | e_COMM_FLAG_MULPRO;
- //return 1;
- }
-
- foreign Command_GetProvider();
-
- global Command_GetProvider()
- {
- P:2("Command_GetProvider called");
- /*YSI_g_sCommandFlags = (YSI_g_sCommandFlags & ~e_COMM_FLAG_PROVIDER) | (e_COMM_FLAG:p & e_COMM_FLAG_PROVIDER)
- if (YSI_g_sCommandFlags & e_COMM_FLAG_MULPRO)
- {
- return _:(YSI_g_sCommandFlags & (YSI_g_sCommandFlags & ~e_COMM_FLAG_PROVIDER));
- }
- else
- {
- }*/
- // Poorely named, gets the current provider.
- return _:Command_DefaultProvider();
- }
-
- foreign void:Command_SetPlayerProvider(playerid,p);
-
- global void:Command_SetPlayerProvider(playerid,p)
- {
- P:2("Command_SetPlayerProvider called: %i, %i", playerid, p);
- if (0 <= playerid < MAX_PLAYERS)
- {
- YSI_g_sPlayerProvider{playerid} = p & 0xFF;
- }
- //return 1;
- }
-
- foreign Command_GetPlayerProvider(playerid);
-
- global Command_GetPlayerProvider(playerid)
- {
- P:2("Command_GetPlayerProvider called: %i", playerid);
- return YSI_g_sPlayerProvider{playerid};
- }
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetDeniedReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetDeniedReturn();
- global bool:Command_GetDeniedReturn()
- {
- P:2("bool:Command_GetDeniedReturn called");
- return bool:Command_DeniedReturn();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_HasCollisions</summary>
- <returns>
- e_COMM_FLAG_COLLISION
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_HasCollisions() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_COLLISION)
- /**--------------------------------------------------------------------------**\
- <summary>Command_HasCollisions</summary>
- <returns>
- e_COMM_FLAG_MULPRO
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- #define Command_HasMultipleProviders() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_MULPRO)
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetCollisions</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_SetCollisions() \
- YSI_g_sCommandFlags |= e_COMM_FLAG_COLLISION
- /**--------------------------------------------------------------------------**\
- <summary>Command_IllegalReturn</summary>
- <returns>
- e_COMM_FLAG_ILLEGAL
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_IllegalReturn() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_ILLEGAL)
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetIllegalReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetIllegalReturn(bool:set);
- global void:Command_SetIllegalReturn(bool:set)
- {
- P:2("Command_SetIllegalReturn called: %i", bool:set);
- if (set)
- {
- YSI_g_sCommandFlags |= e_COMM_FLAG_ILLEGAL;
- }
- else
- {
- YSI_g_sCommandFlags &= ~e_COMM_FLAG_ILLEGAL;
- }
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetIllegalReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetIllegalReturn();
- global bool:Command_GetIllegalReturn()
- {
- P:2("bool:Command_GetIllegalReturn called");
- return bool:Command_IllegalReturn();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_IllegalReturn</summary>
- <returns>
- e_COMM_FLAG_ILLEGAL
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_UnknownReturn() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_UNKNOWN)
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetIllegalReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetUnknownReturn(bool:set);
- global void:Command_SetUnknownReturn(bool:set)
- {
- P:2("Command_SetUnknownReturn called: %i", bool:set);
- if (set)
- {
- YSI_g_sCommandFlags |= e_COMM_FLAG_UNKNOWN;
- }
- else
- {
- YSI_g_sCommandFlags &= ~e_COMM_FLAG_UNKNOWN;
- }
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetIllegalReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetUnknownReturn();
- global bool:Command_GetUnknownReturn()
- {
- P:2("bool:Command_GetUnknownReturn called");
- return bool:Command_UnknownReturn();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_DisconnectReturn</summary>
- <returns>
- e_COMM_FLAG_DISCONNECT
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_DisconnectReturn() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_DISCONNECT)
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetDisconnectReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetDisconnectReturn(bool:set);
- global void:Command_SetDisconnectReturn(bool:set)
- {
- P:2("Command_SetDisconnectReturn called: %i", bool:set);
- if (set)
- {
- YSI_g_sCommandFlags |= e_COMM_FLAG_DISCONNECT;
- }
- else
- {
- YSI_g_sCommandFlags &= ~e_COMM_FLAG_DISCONNECT;
- }
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetDisconnectReturn</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetDisconnectReturn();
- global bool:Command_GetDisconnectReturn()
- {
- P:2("bool:Command_GetDisconnectReturn called");
- return bool:Command_DisconnectReturn();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_DeniedDisplay</summary>
- <returns>
- e_COMM_FLAG_PERMISSION_WARN
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_DeniedDisplay() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_PERMISSION_WARN)
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetDeniedDisplay</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetDeniedDisplay(bool:set);
- global void:Command_SetDeniedDisplay(bool:set)
- {
- P:2("Command_SetDeniedDisplay called: %i", bool:set);
- if (set)
- {
- YSI_g_sCommandFlags |= e_COMM_FLAG_PERMISSION_WARN;
- }
- else
- {
- YSI_g_sCommandFlags &= ~e_COMM_FLAG_PERMISSION_WARN;
- }
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetDeniedDisplay</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetDeniedDisplay();
- global bool:Command_GetDeniedDisplay()
- {
- P:2("bool:Command_GetDeniedDisplay called");
- return bool:Command_DeniedDisplay();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetNameInt</summary>
- <param name="f">Command to get the name of.</param>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- /*RF:Command_GetNameInt[i](f)
- {
- P:2("Command_GetNameInt called: %i", f);
- if (f >= 0 && f < YSI_g_sCommandIndex)
- {
- setproperty(8, "", YSIM_STRING, Command_Name(f));
- return 1;
- }
- return 0;
- }*/
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetName</summary>
- <param name="funcid">Command to get the name of.</param>
- <returns>
- -
- </returns>
- <remarks>
- native Command_GetName(funcid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- /*stock Command_GetName(funcid)
- {
- P:3("Command_GetName called: %i", funcid);
- new
- buffer[32] = "";
- if (Command_GetNameInt(funcid))
- {
- getproperty(8, "", YSIM_STRING, buffer);
- strunpack(buffer, buffer);
- }
- return buffer;
- }*/
- /**--------------------------------------------------------------------------**\
- <summary>Command_IsSorted</summary>
- <returns>
- e_COMM_FLAG_SORTED
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_IsSorted() \
- (YSI_g_sCommandFlags & e_COMM_FLAG_SORTED)
- /**--------------------------------------------------------------------------**\
- <summary>Command_Generate</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_Generate();
- global void:Command_Generate()
- {
- P:2("Command_Generate called");
- P:2("Command_Generate called");
- if (!Command_IsSorted())
- {
- P:2("Command_Generate: Count = %d", YSI_g_sCommandCount);
- new
- data[MAX_COMMANDS][E_BINTREE_INPUT];
- // This is only called once, so we know YSI_g_sCommandCount will be
- // accurate WRT the locations of commands.
- for (new i = 0; i != YSI_g_sCommandCount; ++i)
- {
- data[i][E_BINTREE_INPUT_POINTER] = i;
- new
- hash = Command_PackHash(Command_Name(i));
- // Check for an existing command with this hash.
- if (!Command_HasCollisions())
- {
- for (new j = 0; j != i; ++j)
- {
- if (hash == data[j][E_BINTREE_INPUT_VALUE])
- {
- Command_SetCollisions();
- break;
- }
- }
- }
- C:3(else printf("Command_Generate: Hash = %d", hash););
- P:2("Command_Generate: Hash = %d", hash);
- data[i][E_BINTREE_INPUT_VALUE] = hash;
- }
- // WHY THE HECK did I change "Bintree_Generate" to "Bintree_Fill"? That
- // skips the whole sorting code before adding things to the binary tree!
- if (YSI_g_sCommandCount)
- {
- //Bintree_Fill(YSI_g_sSearchTree, data, YSI_g_sCommandCount);
- Bintree_Generate(YSI_g_sSearchTree, data, YSI_g_sCommandCount);
- //Bintree_Fill(YSI_g_sSearchTree, data, YSI_g_sCommandCount);
- }
- P:4("Command_Generate: %d %d %d %d %d", YSI_g_sSearchTree[0][E_BINTREE_TREE_VALUE], YSI_g_sSearchTree[0][E_BINTREE_TREE_LEFT], YSI_g_sSearchTree[0][E_BINTREE_TREE_RIGHT], YSI_g_sSearchTree[0][E_BINTREE_TREE_PARENT], YSI_g_sSearchTree[0][E_BINTREE_TREE_POINTER]);
- // Set sorted to true.
- YSI_g_sCommandFlags |= e_COMM_FLAG_SORTED;
- }
- //return 1;
- }
- foreign void:Command_IncOPCR();
- global void:Command_IncOPCR()
- {
- P:2("Command_IncOPCR called");
- YSI_g_sCommandFlags += e_COMM_FLAG_OPCR_ADD;
- //return 1;
- }
- foreign void:Command_DecOPCR();
- global void:Command_DecOPCR()
- {
- P:2("Command_DecOPCR called");
- YSI_g_sCommandFlags -= e_COMM_FLAG_OPCR_ADD;
- //return 1;
- }
- foreign void:Command_IncOPCP();
- global void:Command_IncOPCP()
- {
- P:2("Command_IncOPCP called");
- YSI_g_sCommandFlags += e_COMM_FLAG_OPCP_ADD;
- //return 1;
- }
- foreign void:Command_DecOPCP();
- global void:Command_DecOPCP()
- {
- P:2("Command_DecOPCP called");
- YSI_g_sCommandFlags -= e_COMM_FLAG_OPCP_ADD;
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>OnScriptInit</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- hook OnScriptInit()
- {
- // Set the default provider as any script.
- //YSI_g_sCommandFlags = 0xFF;
- P:1("Command_OnScriptInit called");
- // Initialise the tree.
- #if YSIM_NOT_CLIENT
- Bintree_Reset(YSI_g_sSearchTree);
- //YSI_g_sMaster23 = getproperty(8, "x@");
- #endif
- // Make a list of unused commands.
- for (new i = 0; i != MAX_COMMANDS - 1; ++i)
- {
- YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER] = i + 1;
- }
- YSI_g_sCommands[MAX_COMMANDS - 1][E_COMMANDS_FUNC_POINTER] = -1;
- // Loop through all the possible commands. Note that this may need to add
- // commands to the remote command system if this is not the master system.
- // The way the master system is designed means that we will know if we are
- // master or not by the time this function is called.
- new
- buffer[32],
- idx;
- // This is the only place where AMX_FastString is used instead of
- // Commands_FastString as the strings in the AMX are not the same as packed
- // strings - they are in different memory orders.
- while ((idx = AMX_GetPublicNamePrefix(idx, buffer, _A<@yC_>)))
- {
- Command_Add(buffer, _@);
- //Command_Add(unpack(buffer), _@);
- //Command_Add(unpack(buffer), _@);
- P:2("Command_OnScriptInit: Adding %s", unpack(buffer));
- }
- Command_Generate();
- // Now that all commands have been added to the array, sort it.
- // Now call the next constructor.
- if (funcidx("OnPlayerCommandPerformed") != -1)
- {
- Command_IncOPCP();
- }
- if (funcidx("OnPlayerCommandReceived") != -1)
- {
- Command_IncOPCR();
- }
- }
- // Forwards for initial command callbacks.
- forward OnPlayerCommandReceived(playerid, cmdtext[]);
- forward OnPlayerCommandPerformed(playerid, cmdtext[], success);
- hook OnScriptExit()
- {
- P:1("Commands_OnScriptExit called");
- if (funcidx("OnPlayerCommandPerformed") != -1)
- {
- Command_DecOPCP();
- }
- if (funcidx("OnPlayerCommandReceived") != -1)
- {
- Command_DecOPCR();
- }
- return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>OnScriptClose</summary>
- <param name="script">ID of the closing script.</param>
- <returns>
- -
- </returns>
- <remarks>
- Called when a script under the control of the master system ends.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER && YSIM_NOT_CLIENT
- #if _YSIM_IS_CLOUD
- public OnScriptClose(script) <>
- {
- #if defined Command_OnScriptClose
- Command_OnScriptClose(script);
- #endif
- }
-
- public OnScriptClose(script) <_YCM:y>
- #elseif _YSIM_IS_STUB
- #error y_commands called with _YSIM_IS_STUB.
- #else
- public OnScriptClose(script)
- #endif
- {
- new
- mask = ~(1 << script);
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (Command_GetPointer(i) == i && (YSI_g_sCommands[i][E_COMMANDS_MASTERS] &= mask) == 0)
- {
- for (new j = 0; j != MAX_COMMANDS; ++j)
- {
- // Remove all alternate names.
- if (Command_GetPointer(j) == i)
- {
- YSI_g_sCommands[j][E_COMMANDS_FUNC_POINTER] = YSI_g_sCommandIndex;
- YSI_g_sCommandIndex = j;
- YSI_g_sCommands[j][E_COMMANDS_MASTERS] = 0;
- //Bintree_Delete(YSI_g_sSearchTree, j, YSI_g_sCommandCount);
- Command_RemoveFromBintree(j);
- --YSI_g_sCommandCount;
- //Bintree_Add(YSI_g_sSearchTree, YSI_g_sCommandIndex, hash, YSI_g_sCommandIndex);
- }
- }
- }
- /*new
- p = i;
- while (YSI_g_sCommands[p][E_COMMANDS_MASTERS] == -1)
- {
- p = Command_GetPointer(p);
- }
- if (YSI_g_sCommands[p][E_COMMANDS_FUNC_POINTER] == p && (YSI_g_sCommands[p][E_COMMANDS_MASTERS] &= mask) == 0)
- {
- // Remove all alternate versions of commands - done backwards by
- // an alternate command checking its parent. Can also handle
- // alternate versions of alternate commands (note this is the
- // only code that can currently).
- YSI_g_sCommands[i][E_COMMANDS_MASTERS] = 0;
- YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER] = YSI_g_sCommandIndex;
- YSI_g_sCommandIndex = i;
- // Mark it as invalid in this instance.
- YSI_g_sCommands[i][E_COMMANDS_MASTERS] = 0;
- // Reduce the number of commands.
- --YSI_g_sCommandCount;
- }*/
- }
- //YSI_g_sMaster23 = getproperty(8, "x@");
- // I can add better removal code later. Done ^
- #if defined Command_OnScriptClose
- Command_OnScriptClose(script);
- #endif
- }
-
- // Don't need ALS here as we did it supporting it at the start.
- #undef OnScriptClose
- #define OnScriptClose Command_OnScriptClose
- #if defined Command_OnScriptClose
- forward Command_OnScriptClose(script);
- #endif
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_TouchNamed</summary>
- <param name="string:command[]">Command to "touch".</param>
- <returns>
- -
- </returns>
- <remarks>
- Used within "GROUP_ADD" to quickly assign a load of commands to just one
- group.
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_TouchNamed(string:command[]);
- global void:Command_TouchNamed(string:command[])
- {
- new
- id = Command_Find(command);
- if (id != COMMAND_NOT_FOUND)
- {
- NO_GROUPS(id)
- {
- return; //0;
- }
- }
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Touch</summary>
- <param name="string:command[]">Command to "touch".</param>
- <returns>
- -
- </returns>
- <remarks>
- Used within "GROUP_ADD" to quickly assign a load of commands to just one
- group.
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_Touch(command);
- global void:Command_Touch(command)
- {
- if (Command_IsValid(command))
- {
- NO_GROUPS(command)
- {
- return; //0;
- }
- //return 1;
- }
- //return 0;
- }
- /**--------------------------------------------------------------------------**\
- <summary>OnPlayerConnect</summary>
- <returns>
- -
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- // TODO: Rewrite!
- //RA:Command_OnPlayerConnect(playerid)
- #if YSIM_NOT_CLIENT
- mhook OnPlayerConnect(playerid)
- {
- //#if YSIM_NOT_CLIENT
- //YSI_g_sCommandDialog[playerid] = -1;
- #if YSIM_HAS_MASTER
- YSI_g_sPlayerProvider{playerid} = 0xFF;
- #endif
- NO_GROUPS()
- {
- new
- slot = Bit_Slot(playerid) + 1,
- Bit:mask = Bit_Mask(playerid); //Bit:(1 << (playerid & (cellbits - 1)));
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- YSI_g_sCommands[i][E_COMMANDS_PLAYERS][slot] |= mask;
- //PA+(YSI_g_sCommands[i][E_COMMANDS_PLAYERS], mask);
- }
- }
- //#endif
- // Groups will ALWAYS be called after this function - so this can reset
- // player permissions however it likes with the group system then being
- // able to override anything set in here.
- return 1;
- //ALS_CALL<PlayerConnect, i>(playerid)
- }
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_</summary>
- <param name="command">Command to declare.</param>
- <returns>
- -
- </returns>
- <remarks>
- Deprecated!
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_(%1) \
- CMD:%1(playerid,params[],help)
- /**--------------------------------------------------------------------------**\
- <summary>ycmd</summary>
- <param name="command[]">Command to register.</param>
- <returns>
- -
- </returns>
- <remarks>
- Deprecated!
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define ycmd(%1);
- /**--------------------------------------------------------------------------**\
- <summary>Command_FindFast</summary>
- <param name="data[]">Function name to find.</param>
- <param name="value">Hash of function name.</param>
- <returns>
- Position in functions array or COMMAND_NOT_FOUND.
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- static stock Command_FindFast(data[], value, provider = 0xFF)
- #else
- static stock Command_FindFast(data[], value)
- #endif
- {
- new
- leaf,
- pointer;
- #if YSIM_HAS_MASTER
- P:4("Command_FindFast called: \"%s\", %i, %i", data, value, provider);
- provider <<= 24;
- P:5("Command_FindFast: Searching for %s", data);
- if (Command_HasMultipleProviders())
- {
- /*if (provider == 0xFF)
- {
- while ((pointer = Bintree_FindValue(YSI_g_sSearchTree, value, leaf)) != BINTREE_NOT_FOUND)
- {
- //new
- // p = YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] & 0xFF000000;
- //P:7("Command_FindFast: providers %d %d %d", Command_HasMultipleProviders(), (p & 0xFF000000 != 0xFF000000), (p >>> 24 != provider));
- // Any script will do.
- //if ((YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] & 0xFF000000) != 0xFF000000) continue;
- //if (p != 0xFF000000 && p != provider) continue;
- // Don't do an strcmp if there are no collisions.
- P:7("Command_FindFast: collisions %d", !Command_HasCollisions());
- if (!Command_HasCollisions()) return pointer;
- //if (!strcmp(YSI_g_sCommands[i][E_COMMANDS_FUNCTION][1], funcname) &&
- P:7("Command_FindFast: strcmp %d", !strcmp(Command_Name(pointer), data));
- if (!strcmp(Command_Name(pointer), data)) return pointer;
- //if (!strcmp(Command_Name(pointer), data) && (Command_GetProvider(pointer) == 0xFF || Command_GetProvider(pointer) == provider)) return pointer;
- }
- }
- else
- {*/
- while ((pointer = Bintree_FindValue(YSI_g_sSearchTree, value, leaf)) != BINTREE_NOT_FOUND)
- {
- //new
- // p = YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] & 0xFF000000;
- //P:7("Command_FindFast: providers %d %d %d", Command_HasMultipleProviders(), (p & 0xFF000000 != 0xFF000000), (p >>> 24 != provider));
- //if (p != provider && p != 0xFF000000) continue;
- // Only one provider will do.
- if ((YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] & 0xFF000000) != provider) continue;
- // Don't do an strcmp if there are no collisions.
- P:7("Command_FindFast: collisions %d", Command_HasCollisions());
- if (!Command_HasCollisions()) return pointer;
- //if (!strcmp(YSI_g_sCommands[i][E_COMMANDS_FUNCTION][1], funcname) &&
- P:7("Command_FindFast: strcmp %d", !strcmp(Command_Name(pointer), data));
- if (!strcmp(Command_Name(pointer), data)) return pointer;
- //if (!strcmp(Command_Name(pointer), data) && (Command_GetProvider(pointer) == 0xFF || Command_GetProvider(pointer) == provider)) return pointer;
- }
- //}
- }
- else
- {
- #endif
- while ((pointer = Bintree_FindValue(YSI_g_sSearchTree, value, leaf)) != BINTREE_NOT_FOUND)
- {
- //new
- // p = YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] & 0xFF000000;
- //P:7("Command_FindFast: providers %d %d %d", Command_HasMultipleProviders(), (p & 0xFF000000 != 0xFF000000), (p >>> 24 != provider));
- //if (Command_HasMultipleProviders() && (p != 0xFF000000) && (p != provider)) continue;
- // Don't do an strcmp if there are no collisions.
- P:7("Command_FindFast: collisions %d", Command_HasCollisions());
- if (!Command_HasCollisions()) return pointer;
- //if (!strcmp(YSI_g_sCommands[i][E_COMMANDS_FUNCTION][1], funcname) &&
- P:7("Command_FindFast: strcmp %d", !strcmp(Command_Name(pointer), data));
- if (!strcmp(Command_Name(pointer), data)) return pointer;
- //if (!strcmp(Command_Name(pointer), data) && (Command_GetProvider(pointer) == 0xFF || Command_GetProvider(pointer) == provider)) return pointer;
- }
- #if YSIM_HAS_MASTER
- }
- #endif
- P:5("Command_FindFast: Not found");
- return COMMAND_NOT_FOUND;
- }
- static stock Command_FindFastStrict(data[], value, provider)
- {
- #if YSIM_HAS_MASTER
- P:4("Command_FindFastStrict called: \"%s\", %i, %i", data, value, provider);
- #else
- #pragma unused provider
- #endif
- new
- leaf,
- pointer;
- P:5("Command_FindFast: Searching for %s", data);
- while ((pointer = Bintree_FindValue(YSI_g_sSearchTree, value, leaf)) != BINTREE_NOT_FOUND)
- {
- #if YSIM_HAS_MASTER
- if (Command_HasMultipleProviders() && (YSI_g_sCommands[pointer][E_COMMANDS_FUNC_POINTER] >>> 24 != provider)) continue;
- #endif
- // Don't do an strcmp if there are no collisions.
- if (!Command_HasCollisions()) return pointer;
- if (!strcmp(Command_Name(pointer), data)) return pointer;
- }
- P:5("Command_FindFast: Not found");
- return COMMAND_NOT_FOUND;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_FindSlow</summary>
- <param name="funcname[]">Function to find.</param>
- <returns>
- -
- </returns>
- <remarks>
- Searches through the array for function linearly - used to set altnames
- before the data has been sorted.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- static stock Command_FindSlow(funcname[], provider = 0xFF)
- #else
- static stock Command_FindSlow(funcname[])
- #endif
- {
- #if YSIM_HAS_MASTER
- P:4("Command_FindSlow called: \"%s\", %i", funcname, provider);
- #endif
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- #if YSIM_HAS_MASTER
- new
- p = YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER];
- if (((p & 0x00FFFFFF == i) || (YSI_g_sCommands[i][E_COMMANDS_MASTERS] == -1)) &&
- (!Command_HasMultipleProviders() || (p & 0xFF000000 == 0xFF000000) || (p >>> 24 == provider)) &&
- !strcmp(Command_Name(i), funcname))
- #else
- if (YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER] == i && !strcmp(Command_Name(i), funcname))
- #endif
- {
- return i;
- }
- }
- return COMMAND_NOT_FOUND;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_FindSlowStrict</summary>
- <param name="funcname[]">Function to find.</param>
- <returns>
- -
- </returns>
- <remarks>
- Searches through the array for function linearly - used to set altnames
- before the data has been sorted.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_FindSlowStrict(funcname[], provider)
- {
- #if YSIM_HAS_MASTER
- P:4("Command_FindSlowStrict called: \"%s\", %i", funcname, provider);
- #else
- #pragma unused provider
- #endif
- P:2("Command_FindSlowStrict: Searching for %s", unpack(funcname));
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- #if YSIM_HAS_MASTER
- new
- p = YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER];
- P:6("Command_FindSlowStrict: %s %08x %d %d", unpack(funcname), Command_Name(i), p & 0xFFFFFF, i);
- // This needs additional checks that the item is valid.
- if (((p & 0x00FFFFFF == i) || (YSI_g_sCommands[i][E_COMMANDS_MASTERS] == -1)) &&
- (!Command_HasMultipleProviders() || (p >>> 24 == provider)) &&
- !strcmp(Command_Name(i), funcname))
- #else
- if (YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER] == i && !strcmp(Command_Name(i), funcname))
- #endif
- {
- return i;
- }
- }
- return COMMAND_NOT_FOUND;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_AddHash</summary>
- <param name="command[]">Command text to hash.</param>
- <param name="dest[]">Array to copy to.</param>
- <param name="idx">Point to start copying from.</param>
- <returns>
- hash value.
- </returns>
- <remarks>
- Hashes a string and copies it to a destination at the same time.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_AddHash(command[], dest[], idx)
- {
- P:4("Command_AddHash called: \"%s\", %i, %i", command, dest, idx);
- // Skip the function name prefix.
- new
- hash = -1,
- ch,
- dx = 1,
- end = idx + 28;
- // Copy and hash at the same time.
- do
- {
- /*ch = TOLOWER(command[idx++]);
- // Always NULL terminate.
- if ((dest[dx] = ch << 24) == COMMAND_END_CMP << 24)
- {
- // Fixes a bug with commands multiples of 4 chars long.
- dest[dx] = 0;
- break;
- }*/
- ch = TOLOWER(command[idx++]);
- if (ch == COMMAND_END_CMP) break;
- dest[dx] = ch << 24;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command[idx++]);
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 16;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command[idx++]);
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 8;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command[idx++]);
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 0;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ++dx;
- }
- while (idx < end);
- return hash;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_AddHashPacked</summary>
- <param name="command[]">Packed command text to hash.</param>
- <param name="dest[]">Array to copy to.</param>
- <param name="idx">Point to start copying from.</param>
- <returns>
- hash value.
- </returns>
- <remarks>
- Hashes a string and copies it to a destination at the same time.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_AddHashPacked(command[], dest[], idx)
- {
- P:4("Command_AddHashPacked called: \"%s\", %i, %i", command, dest, idx);
- // Skip the function name prefix.
- new
- hash = -1,
- ch,
- dx = 1,
- end = idx + 28;
- // Copy and hash at the same time.
- do
- {
- /*ch = TOLOWER(command[idx++]);
- // Always NULL terminate.
- if ((dest[dx] = ch << 24) == COMMAND_END_CMP << 24)
- {
- // Fixes a bug with commands multiples of 4 chars long.
- dest[dx] = 0;
- break;
- }*/
- ch = TOLOWER(command{idx++});
- if (ch == COMMAND_END_CMP) break;
- dest[dx] = ch << 24;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command{idx++});
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 16;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command{idx++});
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 8;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ch = TOLOWER(command{idx++});
- if (ch == COMMAND_END_CMP) break;
- dest[dx] |= ch << 0;
- hash = hash * 33 + ch; //Command_ToUpper(ch);
- ++dx;
- }
- while (idx < end);
- return hash;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_FastHash</summary>
- <param name="command[]">Command text to hash.</param>
- <returns>
- hash value.
- </returns>
- <remarks>
- Just hashes the passed string.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_FastHash(command[])
- {
- P:4("Command_FastHash called: \"%s\"", command);
- new
- index = 0,
- hash = -1,
- ch;
- while ((ch = command[index++])) hash = hash * 33 + TOLOWER(ch);
- return hash;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_PackHash</summary>
- <param name="command[]">Command text to hash.</param>
- <returns>
- hash value.
- </returns>
- <remarks>
- Hashes packed strings.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_PackHash(command[])
- {
- P:4("Command_PackHash called: \"%s\"", command);
- new
- index = 0,
- hash = -1,
- ch;
- while ((ch = command[index++]))
- {
- P:4("Commands_PackHash: ch = 0x%04x%04x", ch >>> 16, ch & 0xFFFF);
- if (ch & 0xFF000000)
- {
- hash = hash * 33 + TOLOWER(ch >>> 24);
- P:5("Command_PackHash: Hash1 = %d", hash);
- }
- else
- {
- break;
- }
- if (ch & 0x00FF0000)
- {
- hash = hash * 33 + TOLOWER(ch >> 16 & 0xFF);
- P:5("Command_PackHash: Hash2 = %d", hash);
- }
- else
- {
- break;
- }
- if (ch & 0x0000FF00)
- {
- hash = hash * 33 + TOLOWER(ch >> 8 & 0xFF);
- P:5("Command_PackHash: Hash3 = %d", hash);
- }
- else
- {
- break;
- }
- if (ch & 0x000000FF)
- {
- hash = hash * 33 + TOLOWER(ch & 0xFF);
- P:5("Command_PackHash: Hash4 = %d", hash);
- }
- else
- {
- break;
- }
- }
- return hash;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Hash</summary>
- <param name="command[]">Command text to hash.</param>
- <param name="&index">Start point and variable to store end point to.</param>
- <param name="&length">Length of the hashed word.</param>
- <returns>
- hash value.
- </returns>
- <remarks>
- Hashes a string using space delimiters and returns information such as the
- length of the string hased and the start point of the next word.
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_Hash(command[], &index, &length)
- {
- P:4("Command_Hash called: \"%s\", %i, %i", command, index, length);
- new
- hash = -1,
- ch;
- length = index;
- while ((ch = command[index++]) > ' ') hash = hash * 33 + TOLOWER(ch);
- length = index - length - 1;
- while (ch)
- {
- if (ch > ' ')
- {
- break;
- }
- ch = command[index++];
- }
- --index;
- return hash;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Find</summary>
- <param name="function[]">Function name to find.</param>
- <returns>
- Position in functions array or COMMAND_NOT_FOUND.
- </returns>
- <remarks>
- Used by API functions to avoid repeated sorting checks.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_HAS_MASTER
- static stock Command_Find(function[], provider = -1)
- #else
- static stock Command_Find(function[])
- #endif
- {
- #if YSIM_HAS_MASTER
- P:4("Command_Find called: \"%s\", %i", function, provider);
- if (provider == -1)
- {
- provider = _:Command_DefaultProvider();
- // Find the ID of the command.
- if (Command_IsSorted())
- {
- return Command_FindFast(function, Command_FastHash(function), provider);
- }
- else
- {
- return Command_FindSlow(function, provider);
- }
- }
- else
- {
- provider &= 0xFF;
- // Find the ID of the command.
- if (Command_IsSorted())
- {
- return Command_FindFastStrict(function, Command_FastHash(function), provider);
- }
- else
- {
- return Command_FindSlowStrict(function, provider);
- }
- }
- #else
- if (Command_IsSorted())
- {
- return Command_FindFast(function, Command_FastHash(function));
- }
- else
- {
- return Command_FindSlow(function);
- }
- #endif
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetID</summary>
- <param name="function[]">Function name to find.</param>
- <returns>
- The ID of the passed function.
- </returns>
- <remarks>
- -
- native Command_GetID(function[])
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign Command_GetID(string:function[]);
- global Command_GetID(string:function[])
- {
- P:2("Command_GetID called: \"%s\"", function);
- return Command_Find(function);
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetPlayer</summary>
- <param name="command">Command to set for.</param>
- <param name="playerid">Player to set.</param>
- <param name="bool:set">Wether or not this player can use this command.</param>
- <returns>
- -
- </returns>
- <remarks>
- -
- native bool:Command_SetPlayer(command, playerid, bool:set);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetPlayer(c,p,bool:s);
- global void:Command_SetPlayer(c,p,bool:s)
- {
- P:2("Command_SetPlayer called: %i, %i, %i", c, p, s);
- // if (c < 0 || c >= YSI_g_sCommandIndex)
- if (0 <= c < MAX_COMMANDS)
- {
- //Bit_Set(YSI_g_sCommands[c][E_COMMANDS_PLAYERS], p, s, bits<MAX_PLAYERS>);
- //if (s) PA+(YSI_g_sCommands[c][E_COMMANDS_PLAYERS], p);
- //else PA-(YSI_g_sCommands[c][E_COMMANDS_PLAYERS], p);
- PA_Set(YSI_g_sCommands[c][E_COMMANDS_PLAYERS], p, s);
- // Not in range,
- // return false;
- }
- //return 1;
- // return s;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_SetPlayerNamed</summary>
- <param name="funcname[]">Command to set for.</param>
- <param name="playerid">Player to set.</param>
- <param name="set">Wether or not this player can use this command.</param>
- <returns>
- -
- </returns>
- <remarks>
- Like Command_SetPlayer but for a function name.
- native bool:Command_SetPlayerNamed(funcname[], playerid, bool:set);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_SetPlayerNamed(string:f[],p,bool:s);
- global void:Command_SetPlayerNamed(string:f[],p,bool:s)
- {
- P:2("Command_SetPlayerNamed called: \"%s\", %i, %i", f, p, s);
- Command_SetPlayer(Command_Find(f), p, s);
- //return 1;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetPlayer</summary>
- <param name="command">Command to get for.</param>
- <param name="playerid">Player to get.</param>
- <returns>
- Wether this player can use this command.
- </returns>
- <remarks>
- -
- native bool:Command_GetPlayer(command, playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetPlayer(command, playerid);
- global bool:Command_GetPlayer(command, playerid)
- {
- P:2("bool:Command_GetPlayer called: %i, %i", command, playerid);
- if (0 <= command < MAX_COMMANDS)
- {
- return bool:Command_CheckPlayer(command, playerid);
- }
- // Not in range,
- return false;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetPlayerNamed</summary>
- <param name="funcname[]">Command to get for.</param>
- <param name="playerid">Player to get.</param>
- <returns>
- -
- </returns>
- <remarks>
- Like Command_GetPlayer but for a function name.
- native bool:Command_GetPlayerNamed(funcname[], playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign bool:Command_GetPlayerNamed(string:func[], playerid);
- global bool:Command_GetPlayerNamed(string:func[], playerid)
- {
- P:2("bool:Command_GetPlayerNamed called: \"%s\", %i", func, playerid);
- return Command_GetPlayer(Command_Find(func), playerid);
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Remove</summary>
- <param name="func">The slot of the command to remove.</param>
- <returns>
- -
- </returns>
- <remarks>
- native Command_Remove(func);
- </remarks>
- \**--------------------------------------------------------------------------**/
- static stock Command_RemoveFromBintree(func)
- {
- P:4("Command_RemoveFromBintree called: %i", func);
- if (!Command_IsSorted()) return;
- // This function has to find the right index in the binary tree, as that's
- // not in the same order at all.
- new
- leaf,
- hash = Command_PackHash(Command_Name(func));
- // Find where in the binary tree this is referenced from.
- while (Bintree_FindValue(YSI_g_sSearchTree, hash, _, leaf) != BINTREE_NOT_FOUND)
- {
- if (YSI_g_sSearchTree[leaf][E_BINTREE_TREE_POINTER] == func)
- {
- P:2("Command_RemoveFromBintree: Delete branch");
- Bintree_Delete(YSI_g_sSearchTree, leaf, YSI_g_sCommandCount);
- return;
- }
- }
- }
- foreign void:Command_Remove(func);
- global void:Command_Remove(func)
- {
- P:2("Command_Remove called: %i", func);
- if (0 <= func < MAX_COMMANDS)
- {
- if (Command_GetPointer(func) == func)
- {
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- // Remove all alternate names.
- if (Command_GetPointer(i) == func)
- {
- // Add this to the list of unused functions.
- YSI_g_sCommands[i][E_COMMANDS_FUNC_POINTER] = YSI_g_sCommandIndex;
- YSI_g_sCommandIndex = i;
- // Mark it as invalid in this instance.
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[i][E_COMMANDS_MASTERS] = 0;
- #endif
- // Reduce the number of commands.
- //Bintree_Delete(YSI_g_sSearchTree, i, YSI_g_sCommandCount);
- Command_RemoveFromBintree(i);
- --YSI_g_sCommandCount;
- }
- }
- }
- // Remove a single alternate name.
- YSI_g_sCommands[func][E_COMMANDS_FUNC_POINTER] = YSI_g_sCommandIndex;
- YSI_g_sCommandIndex = func;
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[func][E_COMMANDS_MASTERS] = 0;
- #endif
- //Bintree_Delete(YSI_g_sSearchTree, func, YSI_g_sCommandCount);
- Command_RemoveFromBintree(func);
- --YSI_g_sCommandCount;
- //return 1;
- }
- //return 0;
- }
- foreign void:Command_RemoveNamed(string:func[]);
- global void:Command_RemoveNamed(string:func[])
- {
- P:2("Command_RemoveNamed called: \"%s\"", func);
- Command_Remove(Command_Find(func));
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Add</summary>
- <param name="funcname[]">The function to add to the array.</param>
- <param name="script">The script ID with the function.</param>
- <returns>
- -
- </returns>
- <remarks>
- If the list of commands have already been sorted into the binary tree the
- new commands will be appended, otherwise they will just be added to the
- array.
- native Command_Add(funcname[], script);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign void:Command_Add(string:f[],s);
- global void:Command_Add(string:f[],s)
- {
- #if !YSIM_HAS_MASTER
- #pragma unused s
- #endif
- P:2("Command_Add called: \"%s\", %i", f, s);
- if (YSI_g_sCommandCount < MAX_COMMANDS && YSI_g_sCommandIndex != -1)
- {
- #if !YSIM_HAS_MASTER
- static
- provider = -1;
- #endif
- new
- #if YSIM_HAS_MASTER
- provider = _:Command_DefaultProvider(),
- #endif
- //hash = Command_AddHashPacked(f, YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION], 4),
- // Because of the way the master system works, packed strings are
- // unpacked when they are passed remotely, but not when they are
- // passed locally. The unpacking is done by "CallRemoteFunction",
- // not anything we outselves do...
- offset = f[0] == '@' ? 4 : 1,
- hash = f[0] == '@' ?
- Command_AddHash(f, YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION], 4) :
- Command_AddHashPacked(f, YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION], 4);
- //printf("%s", unpack(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][1]));
- if (Command_IsSorted())
- {
- new
- idx = Command_FindFastStrict(f[offset], hash, provider);
- if (idx != COMMAND_NOT_FOUND)
- {
- P:4("Command_Add: Command exists");
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[idx][E_COMMANDS_MASTERS] |= 1 << s;
- #endif
- return; //0;
- }
- if (!Command_HasCollisions())
- {
- // Check for an existing command with this hash.
- if (Bintree_FindValue(YSI_g_sSearchTree, hash) != BINTREE_NOT_FOUND)
- {
- Command_SetCollisions();
- }
- }
- // Command doesn't exist already - good!
- Bintree_Add(YSI_g_sSearchTree, YSI_g_sCommandIndex, hash, YSI_g_sCommandIndex);
- }
- else
- {
- new
- idx = Command_FindSlowStrict(f[offset], provider);
- if (idx != COMMAND_NOT_FOUND)
- {
- P:4("Command_Add: Command exists");
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[idx][E_COMMANDS_MASTERS] |= 1 << s;
- #endif
- return; //0;
- }
- }
- YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][0] = COMMAND_FUNCTION_PREFIX;
- //Bit_SetAll(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS], true, bits<MAX_PLAYERS>);
- //Command_InitialiseFromGroups(YSI_g_sCommandIndex);
- PA_FastInit(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS]);
- NO_GROUPS(YSI_g_sCommandIndex)
- {
- PA_Init(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS], true);
- }
- // Swap these.
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_MASTERS] = 1 << s;
- #endif
- P:2("Command_Add: Command added in %d (%d)", YSI_g_sCommandIndex, hash);
- hash = YSI_g_sCommandIndex;
- // Set this command as usable in any script.
- P:4("Command_Add: %08x%08x%08x%08x", YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][0], YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][1], YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][2], YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][3]);
- YSI_g_sCommandIndex = YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER];
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER] = hash | (provider << 24);
- #else
- YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER] = hash;
- #endif
- /*#if YSIM_HAS_MASTER
- if (s == _@)
- #endif
- {
- new
- addr = funcidx(f) * 8 + AMX_HEADER_PUBLICS;
- #emit LREF.S.pri addr
- #emit STOR.S.pri addr
- YSI_g_sCommands[hash][E_COMMANDS_AMX_ADDRESS] = addr;
- }
- #pragma tabsize 4*/
- // Now some complex debug rubbish.
- C:4(new str[32];strpack(str, f);printf("Command_Add: %08x%08x%08x%08x", str[0], str[1], str[2], str[3]););
- ++YSI_g_sCommandCount;
- }
- //return 1;
- /*else
- {
- // Not all hope is lost - check if this command name already exists.
- if (Command_IsSorted())
- {
- new
- pos = Command_FindFast(funcname[4], Command_FastHash(funcname[4]));
- if (pos != COMMAND_NOT_FOUND)
- {
- // Found it already in the array.
- return pos;
- }
- }
- else
- {
- new
- pos = Command_FindSlow(funcname[4]);
- if (pos != COMMAND_NOT_FOUND)
- {
- // Command already exists.
- return pos;
- }
- }
- }
- return COMMAND_NOT_FOUND;*/
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_AddAlt</summary>
- <param name="funcidx">The function this is an alternate to.</param>
- <param name="altname[]">The new name.</param>
- <returns>
- -
- </returns>
- <remarks>
- If the list of commands have already been sorted into the binary tree the
- new commands will be appended, otherwise they will just be added to the
- array.
- native Command_AddAlt(funcidx, altname[]);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign Command_AddAlt(oidx, string:altname[]);
- global Command_AddAlt(oidx, string:altname[])
- {
- P:2("Command_AddAlt called: %i, \"%s\"", oidx, altname);
- if (!Command_IsValid(oidx))
- {
- return COMMAND_NOT_FOUND;
- }
- #if YSIM_HAS_MASTER
- new
- provider = _:Command_DefaultProvider();
- #else
- static
- provider = -1;
- #endif
- if (YSI_g_sCommandCount < MAX_COMMANDS && YSI_g_sCommandIndex != -1)
- {
- new
- hash = Command_AddHash(altname, YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION], 0);
- if (Command_IsSorted())
- {
- // Find the function this mirrors.
- //oidx = Command_FindFast(function, Command_FastHash(function));
- new
- pos = Command_FindFastStrict(altname, hash, provider);
- if (pos != COMMAND_NOT_FOUND)
- {
- if (Command_GetPointer(pos) != oidx)
- {
- // Same altname, different function.
- return COMMAND_NOT_FOUND;
- }
- return pos;
- }
- if (!Command_HasCollisions())
- {
- // Check for an existing command with this hash.
- //if (Bintree_FindValue(YSI_g_sSearchTree, hash) != BINTREE_NOT_FOUND)
- //{
- // Command_SetCollisions();
- //}
- new
- leaf;
- while ((pos = Bintree_FindValue(YSI_g_sSearchTree, hash, leaf)) != BINTREE_NOT_FOUND)
- {
- // Don't have collisions if the providers are different.
- if ((YSI_g_sCommands[pos][E_COMMANDS_FUNC_POINTER] >>> 24) != provider) continue;
- Command_SetCollisions();
- }
- }
- // Command doesn't exist already - good!
- Bintree_Add(YSI_g_sSearchTree, YSI_g_sCommandIndex, hash, YSI_g_sCommandIndex);
- }
- else
- {
- new
- pos = Command_FindSlowStrict(altname, provider);
- if (pos != COMMAND_NOT_FOUND)
- {
- if (Command_GetPointer(pos) != oidx)
- {
- // Same altname, different function.
- return COMMAND_NOT_FOUND;
- }
- // Command already exists.
- return pos;
- }
- }
- YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_FUNCTION][0] = COMMAND_FUNCTION_PREFIX;
- //Bit_SetAll(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS], true, bits<MAX_PLAYERS>);
- //Command_InitialiseFromGroups(YSI_g_sCommandIndex);
- PA_FastInit(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS]);
- NO_GROUPS(YSI_g_sCommandIndex)
- {
- PA_Init(YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_PLAYERS], true);
- }
- ++YSI_g_sCommandCount;
- #if YSIM_HAS_MASTER
- // This doesn't have real masters.
- YSI_g_sCommands[YSI_g_sCommandIndex][E_COMMANDS_MASTERS] = -1;
- #endif
- P:2("Command_AddAlt: Command added in %d as %d", YSI_g_sCommandIndex, oidx);
- hash = YSI_g_sCommandIndex;
- YSI_g_sCommandIndex = YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER];
- #if YSIM_HAS_MASTER
- YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER] = oidx | (provider << 24);
- #else
- YSI_g_sCommands[hash][E_COMMANDS_FUNC_POINTER] = oidx;
- #endif
- return hash;
- }
- else
- {
- // Not all hope is lost - check if this command name already exists.
- new
- pos;
- if (Command_IsSorted())
- {
- pos = Command_FindFastStrict(altname, Command_FastHash(altname), provider);
- }
- else
- {
- pos = Command_FindSlowStrict(altname, provider);
- }
- if (pos != COMMAND_NOT_FOUND)
- {
- // Found it already in the array. Check if the element it points to
- // has the correct name so we know this is the correct pair, not
- // just the correct single element. I.e. check that this is the
- // correct original/altname combo, not the right altname on a
- // different original name.
- if (oidx == Command_GetPointer(pos))
- {
- return pos;
- }
- }
- }
- return COMMAND_NOT_FOUND;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_AddAltNamed</summary>
- <param name="function[]">The function this is an alternate to.</param>
- <param name="altname[]">The new name.</param>
- <returns>
- -
- </returns>
- <remarks>
- Add an alternate command for an existing command.
- native Command_AddAltNamed(function[], altname[]);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign Command_AddAltNamed(string:function[], string:altname[]);
- global Command_AddAltNamed(string:function[], string:altname[])
- {
- P:2("Command_AddAltNamed called: \"%s\", \"%s\"", function, altname);
- return Command_AddAlt(Command_Find(function), altname);
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Debug</summary>
- <returns>
- -
- </returns>
- <remarks>
- Print some random information about commands if _DEBUG is set.
- </remarks>
- \**--------------------------------------------------------------------------**/
- stock Command_Debug()
- {
- P:3("Command_Debug called: %i");
- #if _DEBUG > 0
- printf("Command_Debug: Start");
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (Command_IsValid(i))
- {
- printf("Command_Debug: Loop start %d", i);
- new buffer[MAX_COMMAND_LENGTH];
- strunpack(buffer, Command_Name(i));
- printf("%08x%08x%08x", YSI_g_sCommands[i][E_COMMANDS_FUNCTION][0], YSI_g_sCommands[i][E_COMMANDS_FUNCTION][1], YSI_g_sCommands[i][E_COMMANDS_FUNCTION][2]);
- new pointer = Command_GetPointer(i);
- printf("Command %d:", i);
- printf("\t%s", buffer);
- printf("\t%d", pointer);
- printf("\t%d %d %d", YSI_g_sSearchTree[i][E_BINTREE_TREE_LEFT], YSI_g_sSearchTree[i][E_BINTREE_TREE_RIGHT], YSI_g_sSearchTree[i][E_BINTREE_TREE_VALUE]);
- CallLocalFunction(Command_GetFunction(Command_GetPointer(i)), "isi", 0, "hi", 0);
- printf("Command_Debug: Loop end");
- }
- }
- printf("Command_Debug: End");
- #endif
- }
- /**--------------------------------------------------------------------------**\
- <summary>OnPlayerCommandText</summary>
- <param name="playerid">Player who entered the command.</param>
- <param name="cmdtext[]">Text entered.</param>
- <returns>
- true - success or hidden fail.
- false - fail.
- </returns>
- <remarks>
- Calls the Command_Process function if this is not a client.
- </remarks>
- \**--------------------------------------------------------------------------**/
- #if YSIM_NOT_CLIENT
- mhook OnPlayerCommandText(playerid, cmdtext[])
- {
- P:1("Commands_OnPlayerCommandText");
- if (isnull(cmdtext)) return Command_UnknownReturn();
- if (YSI_g_sCommandFlags & e_COMM_FLAG_OPCR)
- {
- switch (CallRemoteFunction("OnPlayerCommandReceived", "is", playerid, cmdtext))
- {
- case 0:
- // Handle normally, as in ZCMD.
- return 1;
- case -1:
- // Allow them to stop processing but return 0.
- return 0;
- // Do nothing on 1.
- }
- }
- if (YSI_g_sCommandFlags & e_COMM_FLAG_OPCP)
- {
- new
- ret = Command_Process(playerid, cmdtext, 0);
- switch (CallRemoteFunction("OnPlayerCommandPerformed", "isi", playerid, cmdtext, ret))
- {
- case 0:
- return 0;
- case 1:
- return 1;
- //default:
- // Return the original return on -1.
- }
- return ret;
- }
- else
- {
- /*switch (Command_Process(playerid, cmdtext, 0))
- {
- case 1:
- // Found the command, processed.
- return 1;
- case -1:
- // Found the command, but want to return 0 anyway.
- return 0;
- // Do nothing on 0.
- }*/
- return Command_Process(playerid, cmdtext, 0);
- }
- // This can never actually be reached!
- //return 0;
- }
- #endif
- /**--------------------------------------------------------------------------**\
- <summary>Command_ReProcess</summary>
- <param name="playerid">Player who entered the command.</param>
- <param name="cmdtext[]">Text entered.</param>
- <param name="help">Called from the help commmand or OnPlayerCommandText.</param>
- <returns>
- true - success or hidden fail.
- false - fail.
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign Command_ReProcess(p,string:c[],h);
- global Command_ReProcess(p,string:c[],h)
- {
- P:2("Command_ReProcess called: %i, \"%s\", %i", p, c, h);
- return Command_Process(p,c,h);
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_Process</summary>
- <param name="playerid">Player who entered the command.</param>
- <param name="cmdtext[]">Text entered.</param>
- <param name="help">Called from the help commmand or OnPlayerCommandText.</param>
- <returns>
- true - success or hidden fail.
- false - fail.
- </returns>
- <remarks>
- -
- </remarks>
- \**--------------------------------------------------------------------------**/
- #define Command_CallR(%1,%2) \
- CallRemoteFunction(Command_GetFuncName((%1)), "isii", playerid, %2, help, script)
- #define Command_CallL(%1,%2) \
- CallLocalFunction(Command_GetFuncName((%1)), "isi", playerid, %2, help)
- static stock Command_Process(playerid, cmdtext[], help)
- {
- P:4("Command_Process FS called: %i, \"%s\", %i", playerid, cmdtext, help);
- // Support for very old problems!
- // TODO: Add back.
- P:2("Command_Process called: %d %s", playerid, cmdtext);
- /*#if !_DEBUG && !defined _YSI_SPECIAL_DEBUG
- // For testing purposes.
- if (!IsPlayerConnected(playerid))
- {
- return Command_DisconnectReturn();
- }
- #endif*/
- P:4("Command_Process: Connected");
- new
- idx,
- prelen = help ? 0 : 1,
- index = prelen;
- /*// Shortcuts.
- if (cmdtext[2] <= ' ')
- {
- // Get a player's shortcut information for this letter.
- }
- else*/
- {
- // No more faffing about with random alternate code - it's all done in
- // one nice function instead of having to handle both separately.
- new
- length,
- hash = Command_Hash(cmdtext, index, length);
- P:2("Command_Process: Hash = %d, Length = %d", hash, length);
- // NOTE: No prefix support here.
- cmdtext[length + prelen] = '\0';
- #if YSIM_HAS_MASTER
- length = YSI_g_sPlayerProvider{playerid};
- P:2("Command_Process: Provider: %d", length);
- idx = Command_FindFast(cmdtext[prelen], hash, length);
- if (idx == COMMAND_NOT_FOUND && length != 0xFF)
- {
- // Check default commands if no specialised commands were found.
- idx = Command_FindFast(cmdtext[prelen], hash);
- }
- #else
- idx = Command_FindFast(cmdtext[prelen], hash);
- #endif
- // TODO: Replace!
- //idx = Command_FindSlow(cmdtext[prelen]);//, hash);
- }
- P:2("Command_Process: Index = %d", idx);
- if (idx != COMMAND_NOT_FOUND)
- {
- // Get the master data for the underlying command, not the possibly
- // changed name.
- new
- pointer = Command_GetPointer(idx);
- P:4("Command_Process: Found %d, %d", idx, pointer);
- // Found a command with this name - check the permissions.
- //if (Bit_Get(YSI_g_sCommands[idx][E_COMMANDS_PLAYERS], playerid))
- if (Command_CheckPlayer(idx, playerid))
- {
- P:4("Command_Process: Allowed");
- // Allowed to use the command, get the real function. Note that
- // this may well be the same as "idx", but we loose no time.
- #if YSIM_HAS_MASTER
- P:4("Command_Process: %08x%08x%08x%08x", YSI_g_sCommands[idx][E_COMMANDS_FUNCTION][0], YSI_g_sCommands[idx][E_COMMANDS_FUNCTION][1], YSI_g_sCommands[idx][E_COMMANDS_FUNCTION][2], YSI_g_sCommands[idx][E_COMMANDS_FUNCTION][3]);
- //if (master & 1 << YSI_g_sMaster23)
- //{
- // master = YSI_g_sMaster23;
- //}
- //else
- //{
- new
- script = Command_Provider(idx);
- if (script == 0xFF)
- {
- script = YSI_g_sCommands[pointer][E_COMMANDS_MASTERS];
- if (!script)
- {
- // No scripts can serve the code.
- return Command_UnknownReturn();
- }
- // Find the lowest set bit. We use this to broadcastfunc the
- // command. If it uses MASTER 23, this will select only
- // one script to use. If it doesn't use MASTER 23, this is
- // ignored as a parameter and _YCM is used instead.
- static const
- scDeBruijn[] =
- {
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
- };
- // http://supertech.csail.mit.edu/papers/debruijn.pdf
- script = scDeBruijn[((script & -script) * 0x077CB531) >>> 27];
- }
- //}
- P:2("Command_Process: script = %d", script);
- //if (master == _@)
- //{
- /*#endif
- // This script has it!
- addr = YSI_g_sCommands[pointer][E_COMMANDS_AMX_ADDRESS];
- P:4("Command_Process: %04x%04x", addr >>> 16, addr & 0xFFFF);
- // Make sure all the "#emits" are together as they don't
- // seem to be affected by pre-processor directives.
- #emit PUSH.S master
- #emit PUSH.S help
- #emit LOAD.S.alt cmdtext
- #emit LOAD.S.pri index
- #emit SMUL.C 4
- #emit ADD
- #emit PUSH.pri
- #emit PUSH.S playerid
- #emit PUSH.C 16
- #emit LCTRL 6
- #emit ADD.C 28
- #emit PUSH.pri
- #emit LOAD.S.pri addr
- #emit SCTRL 6
- #emit STOR.S.pri addr
- #if YSIM_HAS_MASTER*/
- //}
- //else
- //{
- #pragma tabsize 4
- P:2("Command_Process: call %s (%d, %d)", unpack(Command_GetFuncName(pointer)), pointer, script);
- if (cmdtext[index])
- {
- // Call it!
- Command_CallR(pointer, cmdtext[index]);
- }
- else
- {
- Command_CallR(pointer, NULL);
- }
- #pragma tabsize 4
- //}
- // Get the real return.
- P:1("Command_Process: return: %d", getproperty(8, YSIM_RETURN));
- return getproperty(8, YSIM_RETURN);
- #else
- if (cmdtext[index])
- {
- // Call it!
- return Command_CallL(pointer, cmdtext[index]);
- }
- else
- {
- return Command_CallL(pointer, NULL);
- }
- //return addr;
- #endif
- }
- else
- {
- return Command_DeniedReturn();
- }
- }
- P:5("Command_Process: Not found");
- #pragma tabsize 4
- return Command_UnknownReturn();
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetName</summary>
- <param name="funcid">Command to get the name of.</param>
- <returns>
- -
- </returns>
- <remarks>
- -
- native Command_GetName(funcid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign string:Command_GetName(funcid);
- global string:Command_GetName(funcid)
- {
- P:2("Command_GetName called: %i", funcid);
- new
- buffer[YSI_MAX_STRING] = "";
- if (Command_IsValid(funcid))
- {
- strunpack(buffer, Command_Name(funcid));
- }
- return buffer;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetDisplay</summary>
- <param name="f">Command to get the real name of.</param>
- <param name="p">Player to get the name for.</param>
- <returns>
- The name of a command for a single player.
- </returns>
- <remarks>
- -
- native Command_GetDisplay(funcid, playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign string:Command_GetDisplay(funcid, playerid);
- global string:Command_GetDisplay(funcid, playerid)
- {
- P:2("Command_GetDisplay called: %i, %i", funcid, playerid);
- new
- buffer[YSI_MAX_STRING] = "";
- if (Command_IsValid(funcid))
- {
- // Don't recalculate this every loop.
- new
- slot = Bit_Slot(playerid) + 1,
- Bit:mask = Bit_Mask(playerid);
- // Check if they can use the original version.
- if (YSI_g_sCommands[funcid][E_COMMANDS_PLAYERS][slot] & mask)
- {
- //setproperty(8, "", YSIM_STRING, Command_Name(f));
- strunpack(buffer, Command_Name(funcid));
- return buffer;
- //return 1;
- }
- // Search for a command pointing to that command which the player can use.
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (Command_GetPointer(i) == funcid && (YSI_g_sCommands[i][E_COMMANDS_PLAYERS][slot] & mask))
- {
- //setproperty(8, "", YSIM_STRING, Command_Name(i));
- strunpack(buffer, Command_Name(i));
- return buffer;
- }
- }
- }
- return buffer;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetDisplayNamed</summary>
- <param name="f[]">Command to get the real name of.</param>
- <param name="p">Player to get the name for.</param>
- <returns>
- The name of a named function for one player.
- </returns>
- <remarks>
- Remote function call for Command_GetDisplayNameNamed - avoids needing to
- expose users to the master system's odd way of returning strings. This is
- the only part I've not yet fixed up to be nice and hidden.
- native string:Command_GetDisplayNamed(string:funcid[], playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign string:Command_GetDisplayNamed(string:func[], playerid);
- global string:Command_GetDisplayNamed(string:func[], playerid)
- {
- P:1("Command_GetDisplayNamed called: \"%s\", %i", func, playerid);
- new
- pointer = Command_Find(func),
- buffer[YSI_MAX_STRING] = "";
- if (pointer != COMMAND_NOT_FOUND)
- {
- // Don't recalculate this every loop.
- new
- slot = Bit_Slot(playerid) + 1, //playerid >>> CELLSHIFT) + 1,
- Bit:mask = Bit_Mask(playerid); //Bit:(1 << (playerid & (cellbits - 1)));
- // Check if they can use the original version.
- if (YSI_g_sCommands[pointer][E_COMMANDS_PLAYERS][slot] & mask)
- {
- //setproperty(8, "", YSIM_STRING, Command_Name(pointer));
- strunpack(buffer, Command_Name(pointer));
- return buffer;
- }
- // Search for a command pointing to that command which the player can use.
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (Command_GetPointer(i) == pointer && (YSI_g_sCommands[i][E_COMMANDS_PLAYERS][slot] & mask))
- {
- //setproperty(8, "", YSIM_STRING, Command_Name(i));
- strunpack(buffer, Command_Name(i));
- return buffer;
- }
- }
- }
- return buffer;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetPlayerCommandCount</summary>
- <param name="playerid">Player to count for.</param>
- <returns>
- -
- </returns>
- <remarks>
- Gets the number of comamnds this player can use.
- native Command_GetPlayerCommandCount(playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign Command_GetPlayerCommandCount(playerid);
- global Command_GetPlayerCommandCount(playerid)
- {
- P:2("Command_GetPlayerCommandCount called: %i", playerid);
- new
- slot = Bit_Slot(playerid) + 1,
- Bit:mask = Bit_Mask(playerid),
- count = 0;
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (_Command_IsValid(i) && YSI_g_sCommands[i][E_COMMANDS_PLAYERS][slot] & mask)
- {
- ++count;
- }
- }
- return count;
- }
- /**--------------------------------------------------------------------------**\
- <summary>Command_GetNext</summary>
- <param name="index">Index of the next command for this player.</param>
- <param name="playerid">Player to get the name for.</param>
- <returns>
- The name of a command for a single player.
- </returns>
- <remarks>
- -
- native Command_GetNext(index, playerid);
- </remarks>
- \**--------------------------------------------------------------------------**/
- foreign string:Command_GetNext(index, playerid);
- global string:Command_GetNext(index, playerid)
- {
- P:2("Command_GetNext called: %i, %i", index, playerid);
- new
- buffer[YSI_MAX_STRING] = "";
- if (0 <= index < MAX_COMMANDS)
- {
- // Don't recalculate this every loop.
- new
- slot = Bit_Slot(playerid) + 1,
- Bit:mask = Bit_Mask(playerid);
- for (new i = 0; i != MAX_COMMANDS; ++i)
- {
- if (_Command_IsValid(i) && YSI_g_sCommands[i][E_COMMANDS_PLAYERS][slot] & mask)
- {
- // Skip already displayed ones.
- if (index)
- {
- --index;
- }
- else
- {
- strunpack(buffer, Command_Name(i));
- return buffer;
- }
- }
- }
- }
- return buffer;
- }
- //#tryinclude <YSI\y_groups>
- //#undef _YCM
- // This is to allow callback chaining. When the user includes y_groups and
- // other libraries, the function names will be reset to their custom ones after
- // every inclusion, however if you then include another YSI library you need to
- // revert to the previous library names to get the chaining to work. However I
- // think this is completely pointless now thanks to "y_hooks".
- //#define YSI_SET_LAST_GROUP 25
- #include "internal\y_grouprevert"
- // So we can use custom syntax on these two functions and allow command names to
- // be sort of used...
- //#define Group_SetCommand(%0,YCMD:%2,%3) Group_SetCommand(%0,Command_GetID(#%2),%3)
- //#define Group_SetGlobalCommand(YCMD:%2,%3) Group_SetGlobalCommand(Command_GetID(#%2),%3)
|