Advertisement
RyDeR_

rCmd.inc

Mar 6th, 2012
1,732
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 5.88 KB | None | 0 0
  1. /*
  2.  *  Copyright © 2012-2013 RyDeR`
  3.  *  rCmd.inc (v0.2.0)
  4.  * 
  5.  *  This program is free software: you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation, either version 3 of the License, or
  8.  *  (at your option) any later version.
  9.  * 
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. #if !defined sscanf
  20.     #error you have to include the sscanf plugin in order to use it
  21. #endif
  22.  
  23. #if defined _Included_rCmd
  24.     #endinput
  25. #else
  26.     #define _Included_rCmd
  27. #endif
  28.  
  29. #if !defined MAX_DYNAMIC_PARAMS
  30.     #define MAX_DYNAMIC_PARAMS (16)
  31. #endif
  32.  
  33. #include "DynamicParams.inc"
  34.  
  35. #if !defined MAX_FUNCTIONS
  36.     #define MAX_FUNCTIONS (1024)
  37. #endif
  38.  
  39. #if !defined MAX_SSCANF_FORMAT
  40.     #define MAX_SSCANF_FORMAT (32)
  41. #endif
  42.    
  43.  
  44. stock
  45.     bool: g_bInit,
  46.     bool: g_bHasOPCR,
  47.     bool: g_bHasOPCP,
  48.     g_iNativeIdx,
  49.     g_aszCmd[MAX_FUNCTIONS][MAX_SSCANF_FORMAT char]
  50. ;
  51.  
  52. #define rCmd[%0]->%1(%2) \
  53.         cmd@%1();public cmd@%1(){new i=funcidx(#cmd_%1);if(-1!=i&&i<MAX_FUNCTIONS)strpack(g_aszCmd[i],#%0,sizeof(g_aszCmd[]));}cmd_%1(%2);public cmd_%1(%2)
  54.  
  55. public OnPlayerCommandText(playerid, cmdtext[]) {
  56.     if(cmdtext[0] != '/' || cmdtext[0] == EOS) {
  57.         return 0;
  58.     }
  59.     if(!g_bInit) {
  60.         rCmd_Init();
  61.     }
  62.     if(g_bHasOPCR && !CallLocalFunction("OnPlayerCommandReceived", "is", playerid, cmdtext)) {
  63.         return 1;
  64.     }
  65.     new
  66.         iPos,
  67.         szFunc[32]
  68.     ;
  69.     while(cmdtext[++iPos] > ' ') {
  70.         szFunc[iPos - 1] = tolower(cmdtext[iPos]);
  71.     }
  72.     format(szFunc, sizeof(szFunc), "cmd_%s", szFunc);
  73.    
  74.     new
  75.         iFunc = funcidx(szFunc)
  76.     ;
  77.     if(iFunc != -1 && iFunc < MAX_FUNCTIONS) {
  78.         clearParams();
  79.        
  80.         if(g_aszCmd[iFunc][0] != EOS) {
  81.             new
  82.                 szBuf[MAX_SSCANF_FORMAT],
  83.                 aiAddr[MAX_DYNAMIC_PARAMS][128]
  84.             ;
  85.             strunpack(szBuf, g_aszCmd[iFunc]);
  86.  
  87.             pushParam(e_TYPE_STRING, cmdtext[iPos]);
  88.             pushParam(e_TYPE_STRING, szBuf);
  89.            
  90.             for(new i = 0, iParams = getParamCount(szBuf); i < iParams; ++i) {
  91.                 pushParam(e_TYPE_BYREF, aiAddr[i][0]);
  92.             }
  93.             iFunc = !callNative(g_iNativeIdx, false);
  94.            
  95.             setParam(e_TYPE_MIXED, 0, playerid);
  96.             setParam(e_TYPE_MIXED, 1, iFunc);
  97.         } else {
  98.             pushParam(e_TYPE_MIXED, playerid);
  99.         }
  100.         iFunc = callFunction(szFunc);
  101.        
  102.         if(g_bHasOPCP) {
  103.             return CallLocalFunction("OnPlayerCommandPerformed", "isi", playerid, cmdtext, true);
  104.         }
  105.     } else {
  106.         if(g_bHasOPCP) {
  107.             return CallLocalFunction("OnPlayerCommandPerformed", "isi", playerid, cmdtext, false);
  108.         }
  109.     }
  110.     return 0;
  111. }
  112.  
  113. static stock rCmd_Init() {
  114.     static
  115.         s_szFunc[32]
  116.     ;
  117.     sscanf("1", "i", s_szFunc[0]); // Fix crash
  118.    
  119.     #emit CONST.PRI sscanf
  120.     #emit STOR.PRI g_iNativeIdx
  121.    
  122.     for(new i = 0; i < MAX_FUNCTIONS; ++i) {
  123.         if(!getPublicNameByIndex(i, s_szFunc, sizeof(s_szFunc))) {
  124.             continue;
  125.         }
  126.         if(strfind(s_szFunc, "cmd@") != -1) {
  127.             CallLocalFunction(s_szFunc, "");
  128.         }
  129.     }
  130.     if(!g_bHasOPCR) {
  131.         g_bHasOPCR = !!(funcidx("OnPlayerCommandReceived") != -1);
  132.     }
  133.     if(!g_bHasOPCP) {
  134.         g_bHasOPCP = !!(funcidx("OnPlayerCommandPerformed") != -1);
  135.     }
  136.     g_bInit = true;
  137. }
  138.  
  139. static stock getPublicNameByIndex(const iIdx, szName[], const iSize = sizeof(szName)) {
  140.     static
  141.         s_iBase,
  142.         s_iPublics,
  143.         s_iNatives,
  144.         s_iCount
  145.     ;
  146.     if(!s_iBase) {
  147.         #emit LCTRL 1
  148.         #emit NEG
  149.         #emit STOR.PRI s_iBase
  150.     }
  151.     if(!s_iPublics) {
  152.         new
  153.             iAddr
  154.         ;
  155.         #emit LOAD.PRI s_iBase
  156.         #emit ADD.C 32
  157.         #emit STOR.S.PRI iAddr
  158.         #emit LREF.S.PRI iAddr 
  159.         #emit LOAD.S.ALT iAddr
  160.         #emit ADD
  161.         #emit CONST.ALT 32
  162.         #emit SUB  
  163.         #emit STOR.PRI s_iPublics
  164.     }
  165.     if(!s_iNatives) {
  166.         new
  167.             iAddr
  168.         ;
  169.         #emit LOAD.PRI s_iBase
  170.         #emit ADD.C 36
  171.         #emit STOR.S.PRI iAddr
  172.         #emit LREF.S.PRI iAddr 
  173.         #emit LOAD.S.ALT iAddr
  174.         #emit ADD
  175.         #emit CONST.ALT 36
  176.         #emit SUB
  177.         #emit STOR.PRI s_iNatives
  178.     }
  179.     if(!s_iCount) {
  180.         s_iCount = ((s_iNatives - s_iPublics) >>> 3);
  181.     }
  182.     if(iIdx < s_iCount) {
  183.         new
  184.             iPos = (iIdx << 3) + s_iPublics + 4,
  185.             iCh,
  186.             i
  187.         ;
  188.         #emit LREF.S.PRI iPos
  189.         #emit LOAD.ALT s_iBase
  190.         #emit ADD
  191.         #emit STOR.S.PRI iPos
  192.  
  193.         do {
  194.             #emit LREF.S.PRI iPos
  195.             #emit STOR.S.PRI iCh
  196.  
  197.             szName[i] = iCh & 0xFF;
  198.                
  199.             iPos++;
  200.         } while(szName[i++] != EOS && i <= iSize);
  201.         szName[i] = EOS;
  202.        
  203.         return 1;
  204.     }
  205.     return 0;
  206. }
  207.  
  208. static stock getParamCount(szFormat[]) {
  209.     new
  210.         iParams
  211.     ;
  212.     for(new i = 0, j = strlen(szFormat); i < j; ++i) {
  213.         switch(szFormat[i]) {
  214.             case 'l', 'k', 'b', 'n', 'c', 'i', 'd', 'h', 'o', 'f', 'g', 'u', 'q', 'r': {
  215.                 iParams++;
  216.             }
  217.             case 'L', 'K', 'B', 'N', 'C', 'I', 'D', 'H', 'O', 'F', 'G', 'U', 'Q', 'R', 'E': {
  218.                 i = findNext(szFormat, "(", ")", i);
  219.                 iParams++;
  220.             }
  221.             case 'Z', 'z', 'S', 's', 'A', 'a': {
  222.                 i = findNext(szFormat, "[", "]", i);
  223.                 iParams++;
  224.             }
  225.             case 'e': {
  226.                 i = findNext(szFormat, "<", ">", i);
  227.                 iParams++;
  228.             }
  229.         }
  230.     }
  231.     return iParams;
  232. }
  233.  
  234. static stock findNext(szFormat[], szOpen[], szClosed[], iIdx) {
  235.     new
  236.         iFound = strfind(szFormat, szOpen, false, iIdx);
  237.    
  238.     if(iFound != -1) {
  239.         iIdx = iFound;
  240.         iFound = 0;
  241.        
  242.         while(szFormat[iIdx] != EOS) {
  243.             if(szFormat[iIdx] == szOpen[0]) {
  244.                 iFound++;
  245.             } else if(szFormat[iIdx] == szClosed[0]) {
  246.                 iFound--;
  247.             }
  248.             if(!iFound) {
  249.                 break;
  250.             }
  251.             iIdx++;
  252.         }
  253.     }
  254.     return iIdx;
  255. }
  256.  
  257. forward OnPlayerCommandReceived(playerid, cmdtext[]);
  258. forward OnPlayerCommandPerformed(playerid, cmdtext[], success);
  259.  
  260. #if defined _ALS_OnPlayerCommandText
  261.     #undef OnPlayerCommandText
  262. #else
  263.     #define _ALS_OnPlayerCommandText
  264. #endif
  265.  
  266. #define OnPlayerCommandText rCmd_OnPlayerCommandText
  267.  
  268. forward rCmd_OnPlayerCommandText(playerid, cmdtext[]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement