[Include] ICMD 8.0 Beta
#1

Primeiramente esclarecendo, ICMD й um projeto que vem sido desenvolvido desde 2011 e lб vai pedrada, pelo Bruno e os seus filhotes de codorna, porйm desde o lanзamento da sua ultima versгo ICMD 7.0 o projeto tomou um rumo diferente, continua sendo nomeado como tal, por ser mais uma include do pacote de bibliotecas IPSI, contudo, seu cуdigo foi totalmente reformulado na ultima versгo e agora novamente, sempre buscando novidades e maneiras de processar o comando da forma mais rбpida e que mais convйm aos usuбrios do sistema.

Da ultima versгo para essa, o maior fator para ter ocorrido essa reformulaзгo toda, foram os reports que chegaram atй nуs, a respeito de bugs e o fato da sintaxe ter se tornado algo complicado, esses reports foram essenciais para o amadurecimento da include atй entгo.

Quote:
Originally Posted by arakuta
Посмотреть сообщение
Achei um bug. Nгo existe o comando "k,i,i,l" no meu GM, mas quando usa isso, ele entra no "h,e,l,p"

O ID deve estar retornando o mesmo.
Quote:
Originally Posted by BielCOP
Посмотреть сообщение
Uma destas limitaзoes й ter que ficar digitando uma virgula por cada caractere, e isto й cansativo.

Jб pensou se vocк for escrever um comando gigante e ficar:

pawn Код:
d,a,r,a,d,m,i,n,p,r,o,b,i,e,l,c,o,p,p,q,e,l,e,e,h,g,o,s,t,o,s,o
Facilitando:

daradminprobielcoppqeleehgostoso


Apresentaзгo

A ICMD 8.0, й uma include para criaзгo de comandos de maneira simples, fбcil e extremamente rбpida.

Seus comandos agora podem ser definidos atravйs de dois tipos diferentes de ouvintes, ouvintes para comandos no qual exigirгo entrada de parвmetros e comandos do qual nгo exigirгo.

Ex1.
pawn Код:
public OnCommandCalled(playerid, params[])
{
    //EXEMPLO DE OUVINTE PARA COMANDO SEM ENTRADA PARВMETROS
    get_cmd_noparams(kill)
    {
        SetPlayerHealth(playerid, 0);
        return 1;
    }
   
    //EXEMPLO DE OUVINTE PARA COMANDO COM ENTRADA DE PARВMETROS
    get_cmd_params(cv)
    {
        new carId;
        if (sscanf(params, "i", carId)) return SendClientMessage(playerid, -1, "/cv [int id]"), r(1);

        new Float:x, Float:y, Float:z, Float:a;
        GetPlayerPos(playerid, x, y, z);
        GetPlayerFacingAngle(playerid, a);
        PutPlayerInVehicle(playerid, CreateVehicle(carId, x, y, z, a, -1, -1, cellmax), 0);
        return r(1);
    }
    get_cmd_params(vida)
    {
        new Float:v;
        if (sscanf(params, "f", v)) return SendClientMessage(playerid, -1, "/vida [float valor]"), r(1);
        SetPlayerHealth(playerid, v);
        return r(1);
    }
    get_cmd_params(mensagem)
    {
        new str[128];
        sscanf(params, "s[128]", str);

        new sStr[128];
        format(sStr, 128, "Mensagem: %s", str);
        SendClientMessageToAll(-1, sStr);
        return r(1);
    }
    return 0;
}
Os ouvintes sгo estados que ficam no seu GM, porйm eles nгo podem ser alcanзados atravйs de uma chamada simples a sua respectiva callback OnCommandCalled, ao invйs disso ele й chamado somente atravйs da callback original OnPlayerCommandText.


Para quem chegou a ver, ou atй mesmo usar a ICMD 7.0, poderб notar a diferenзa gritante.

Ex de cуdigo utilizando ICMD 7.0:
pawn Код:
public OnPlayerCommandText(playerid, commandid, params[]) {

    switch(commandid) {


        case iscmd("v,i,d,a"): {
            new Float:v;
            if(sscanf(params,"f", v) {
                return SendClientMessage(playerid, -1, "[Erro]: Use /vida [valor]");
            }

            SetPlayerHealth(playerid, v);

            return true;
        }
    }

    return false;
}
Ex de cуdigo utilizando ICMD 8.0:
pawn Код:
public OnCommandCalled(playerid, params[])
{
    get_cmd_params(vida)
    {
        new Float: v;
        if (sscanf(params, "f", v))
            return SendClientMessage(playerid, -1, "/vida [float quantidade]"), r(1);
           
        SetPlayerHealth(playerid, v);
        return r(1);
    }
    return 0;
}

O processador teve melhorias na sintaxe/semвntica, abstraindo a necessidade de utilizar um switch e separar os comandos por vнrgulas.


OBS: O processador estб em versгo BETA, oque indica que jб estб sendo projetado uma versгo com ganho em velocidade e fixando alguns problemas que jб foram identificados nessa versгo. O motivo de eu estar lanзando essa versгo agora, й justamente para permitir que mais pessoas testem, identificando assim, possнveis bugs se existirem...

***OBS: O processador estб preciso em todos os sentidos, logo, algumas limitaзхes precisam ser estabelecidas para o uso correto e sem problemas.

Todo e qualquer comando digitado sofre uma extraзгo padrгo de parвmetros, a identificaзгo de inexistкncia do comando causarб em mensagem de erro: "Server unkown command"

o ultimo return da callback OnCommandCalled nгo farб diferenзa no seu script, porйm os demais farгo. Uma vez que seu comando nгo contenha return, ele irб varrer todos os outros possнveis comandos, causando conflito na execuзгo.

o return da callback OnPlayerCommandText pode ser alterado de acordo com as necessidades do programador, atravйs do comando r(1/0), aonde 1 й o comando sucesso e 0 й a mensagem padrгo "Server unkown command"


Alguns scripts exemplificando a utilizaзгo do processador serгo publicados ao longo da semana, e possнveis tutoriais se for o caso.




Include source

Include (icmd.inc)
pawn Код:
/*
*
*
*       ICMD 8.0 Por Willian Luigi
*
*   -LOG:
*   Data de inicio: 07/10/2013 ICMD versгo 7.0 beta
*                   11/10/2013 ICMD versгo 7.1 alpha
*
*   Ultima atualizaзгo: 24/12/2014 ICMD versгo 8.0 beta
*
*
*   - CODE.ME, 2013.1 - Willian Luigi
*
*
*/


#if !defined isnull
    #define isnull(%1) \
                ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
#endif
#define g<%0> gotoaddr(%0)
#define gl<%0> saveaddr(#%0)
#define set(%0) gotoaddr(%0)
#define get_cmd_params(%0) gl<%0>;playerid=_wrefPlayerId;r(1);if(!isnull(_wrefCmdParams))strcat((params[0]=EOS,params),_wrefCmdParams, 128);if(_wrefHash(#%0)==_wrefCmdHash)
#define get_cmd_noparams(%0) gl<%0>;playerid=_wrefPlayerId;r(1);if(_wrefHash(#%0)==_wrefCmdHash)
#define F_VALUE _wrefReturnValue
#define r(%0) F_CMD(%0)
new _wrefPlayerId, _wrefCmdHash, _wrefCmdParams[128], _wrefReturnValue;
#pragma unused _wrefPlayerId
#pragma unused _wrefCmdHash
#pragma unused _wrefCmdParams
stock saveaddr(name[])
{
    static addr;
    #emit load.s.pri 4
    #emit stor.pri addr
    setproperty(.id = 0, .name = name, .value = addr);
}
stock gotoaddr(label[])
{
    static addr;
    addr = getproperty(0,label);
    #emit load.pri addr
    #emit sctrl 6
}
stock _wrefHash(s[])
{
    return s[0];
}
stock F_CMD(value)
{
    _wrefReturnValue = value;
    return value;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
    _wrefCmdParams[0]=EOS;
    new __@i = 2;
    __@i = strfind(cmdtext, " ");
    _wrefPlayerId = playerid;
    _wrefCmdHash = cmdtext[1];

    if (__@i != -1)
    {
        new __@cmd[24];
        strmid(__@cmd, cmdtext, 1, __@i);
        while(cmdtext[++__@i] == 0x20){}
        strcat(_wrefCmdParams, cmdtext[__@i]);
        g<__@cmd>;
    }
    else
    {

        g<cmdtext[1]>;
    }

    return F_VALUE;
}

public OnGameModeInit()
{

    OnCommandCalled(0, "");

    if (funcidx("icmd_OnGameModeInit") != -1)
    {
        return CallLocalFunction("icmd_OnGameModeInit", "");
    }
    return 1;
}
#if defined _ALS_OnGameModeInit
    #undef OnGameModeInit
#else
    #define _ALS_OnGameModeInit
#endif
#define OnGameModeInit icmd_OnGameModeInit
forward icmd_OnGameModeInit();
forward OnCommandCalled(playerid, params[]);

Para utilizaзгo do processador:
1. Salve o cуdigo acima em um arquivo "icmd.inc"
2. Coloque-o em sua pasta pawno/includes
3. Faзa a inclusгo dessa lib em seu cуdigo
pawn Код:
#include <icmd>
Link para download: ICMD-8.0 BETA




Exemplares

Aqui deixarei alguns comandos de exemplo, para auxilio.
pawn Код:
public OnCommandCalled(playerid, params[])
{
    get_cmd_params(vida)
    {
        new Float:vida, id;
        if (sscanf(params, "if", id, vida))
            return SendClientMessage(playerid, -1, "/vida [int id][float vida]");

        SetPlayerHealth(id, vida);
        return 1;
    }
    get_cmd_params(colete)
    {
        new Float:colete, id;
        if (sscanf(params, "if", id, colete))
            return SendClientMessage(playerid, -1, "/colete [int id][float colete]");

        SetPlayerArmour(id, colete);
        return 1;
    }
    get_cmd_params(tapa)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/tapa [int id]");

        new Float:x, Float:y, Float:z;
        GetPlayerPos(id, x, y, z);
        SetPlayerPos(id, x, y, z+10);
        return 1;
    }
    get_cmd_params(carro)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/carro [int id]");

        new Float:x, Float:y, Float:z, Float:a;
        GetPlayerPos(playerid, x, y, z);
        GetPlayerFacingAngle(playerid, a);
        PutPlayerInVehicle(playerid, CreateVehicle(id, x, y, z, a, -1, -1, cellmax), 0);
        return 1;
    }
    get_cmd_params(destruir)
    {
        new id;
        if (sscanf(params, "if", id))
            return SendClientMessage(playerid, -1, "/destruir [int id]");

        DestroyVehicle(id);
        return 1;
    }
    get_cmd_params(ir)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/ir [int id]");

        new Float:x, Float:y, Float:z;
        GetPlayerPos(id, x, y, z);
        SetPlayerPos(playerid, x+2, y+2, z);
        return 1;
    }
    get_cmd_params(trazer)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/trazer [int id]");

        new Float:x, Float:y, Float:z;
        GetPlayerPos(playerid, x, y, z);
        SetPlayerPos(id, x+2, y+2, z);
        return 1;
    }
    get_cmd_params(irv)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/irv [int id]");

        new Float:x, Float:y, Float:z;
        GetVehiclePos(id, x, y, z);
        SetPlayerPos(playerid, x+2, y+2, z);
        return 1;
    }
    get_cmd_params(trazerv)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/trazerv [int id]");

        new Float:x, Float:y, Float:z;
        GetPlayerPos(playerid, x, y, z);
        SetVehiclePos(id, x+2, y+2, z);
        return 1;
    }
    get_cmd_params(entrarv)
    {
        new id;
        if (sscanf(params, "i", id))
            return SendClientMessage(playerid, -1, "/entrarv [int id]");
           
        PutPlayerInVehicle(playerid, id, 0);
        return 1;
    }
    get_cmd_params(par)
    {
        new id, smsg[128];
        if (sscanf(params, "is[128]", id, smsg))
            return SendClientMessage(playerid, -1, "/par [int id][string mensagem]");
           
        SendClientMessage(id, -1, smsg);
        return 1;
    }
   
    get_cmd_noparams(cmds)
    {
        SendClientMessage(playerid, -1, "vida, colete, tapa, carro, destruir, ir, trazer, irv, trazerv, entrarv, par");
        return 1;
    }
    return 0;
}


A include tem autoria de minha parte (Willian_Luigi)
Junto de um dos membros antigos do fуrum e idealizador da lib IPSI, ipsBruno
Juntamente com estudos compartilhados pelo ******

Agradecimentos especiais:
  • kreisson
  • PT


Estб include tem por visгo, melhorar a forma como os demais programadores da board trabalham com comandos, por tanto, quanto maior for a contribuiзгo de vocкs, maior serб a evoluзгo da mesma.

Abraзos.
Reply
#2

Sensacional cara!
Jб testei e estб muito rбpido, deixa zCmd no chinelo e se equipara ao iCmd 7 porйm muito mais preciso e sem conflitos. Alйm da sintaxe ter melhorado muito.
+REP

OBS: Pensei que vocк nгo ia postar nunca kkkkkkk
Reply
#3

Parabens, vou usar
Reply
#4

Will, sу uma coisa, vocк deve verificar se isnull jб esta definido ( caso coloque sscanf2 antes do processador ou outras includes que contenham a define )

pawn Код:
#if !defined isnull
    #define isnull(%1) \
                ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))
#endif
Bom trabalho, parabйns pelo processador!
Reply
#5

Quote:
Originally Posted by PT
Посмотреть сообщение
Will, sу uma coisa, vocк deve verificar se isnull jб esta definido ( caso coloque sscanf2 antes do processador ou outras includes que contenham a define )
Ah sim, obrigado por lembrar.
Reply
#6

Parabйns Willian
Vou fazer alguns testes com ele aqui
Reply
#7

Parabйns Willian se eu nгo tivesse comeзado com YCMD eu usaria essa include, mas enfim parabйns pela include +REP
Reply
#8

Parabйns will, achei bastante interessante, irei explorar as capacidades da mesma
Reply
#9

To pensando em criar um projeto simples, vou usar ela para testar!
Bom trabalho!

Se eu quiser bloquear um comando por exemplo:
Bloquear todos comandos para um player preso.
Eu usaria uma condiзгo com
pawn Код:
return 0;
no inicio da funзгo?
pawn Код:
OnCommandCalled
Reply
#10

Include interessante, pretendendo utilizб-la em um projeto que iniciei hoje.
Parabйns!
Reply
#11

Parabйns Willian, gostei
Reply
#12

Parabйns, show de bola, talvez use no projeto!
Reply
#13

Bom, esperarei sу um pouquinho para atualizar para eu comeзar desde de jб, utilizar em meus Projetos.

Nгo que eu ache que estб ruim, muito pelo ao contrбrio acho que estб muito bom, porйm entrarei em um projeto grande, e ainda nгo sei se hб bugs ou nгo. sу esperar uma atualizaзгo oficial para utilizar, jб que este й o beta...
Reply
#14

consegue ser mais rapido que y_commands ?
Reply
#15

Уtimo, parabйns cara!
Reply
#16

Gostei wiil pela include mano Parabйns mesmo ano...
Reply
#17

Muitos parabйns. Um excelente projeto ganhou meu REP
Reply
#18

Quote:
Originally Posted by ReDKiiL
View Post
To pensando em criar um projeto simples, vou usar ela para testar!
Bom trabalho!

Se eu quiser bloquear um comando por exemplo:
Bloquear todos comandos para um player preso.
Eu usaria uma condiзгo com
pawn Code:
return 0;
no inicio da funзгo?
pawn Code:
OnCommandCalled
Esse aspecto ainda nгo foi trabalhado, o processamento de comandos nгo estб vendo de modo sequencial, oque indica que oque vocк inserir dentro da callback "OnCommandCalled" que seja diferente de um ouvinte para comandos com ou sem parвmetros, jamais serб executado...

O processamento se dб ao uso da quebra da rotina atual, quando o comando digitado й identificado a rotina atual se torna a rotina do comando criado na callback, e ai o ouvinte daquele comando й chamado.

Logo, para fazer essa divisгo de comandos, vocк teria que especificar de comando por comando...

Vou levar esse comentбrio em consideraзгo e ver se й possнvel fazer uma melhoria nessa бrea, obrigado por perguntar.

Quote:
Originally Posted by RiqueP
View Post
consegue ser mais rapido que y_commands ?
Nгo foi efetuado testes com a ycmd ainda, mas й esperado que seja um valor aproximado, se nгo superior...

Assim que possнvel, ao tйrmino de alguns testes para aumento de velocidade, posto os testes.

Quote:
Originally Posted by Dolpin
View Post
Bom, esperarei sу um pouquinho para atualizar para eu comeзar desde de jб, utilizar em meus Projetos.

Nгo que eu ache que estб ruim, muito pelo ao contrбrio acho que estб muito bom, porйm entrarei em um projeto grande, e ainda nгo sei se hб bugs ou nгo. sу esperar uma atualizaзгo oficial para utilizar, jб que este й o beta...
Й a versгo beta em termos teуricos, mas foi comprovado que nгo existe conflito entre os comandos e o mais importante, foi garantido a velocidade superior em N diferentes casos de comandos utilizados em gamemodes normais. Sejam eles, comandos com nome grande, comandos com multi-parвmetros, comandos sem parвmetros.

Entгo, quanto a isso, nгo hб com oque se preocupar, o fator ativo pelo qual a include foi postada como BETA, й porque ainda nгo estб pronto o processador de parвmetros que irб descontinuar o uso de SSCANF para esta include, facilitando o trabalho na hora de processar os comandos.


E por fim, estб em anбlise, uma maneira diferente de alocaзгo de comandos, visando assim aumentar a velocidade da include em um valor considerбvel.


Gostaria fortemente de recomendar que todos testassem, o teste й um ato muito importante tanto para quem produz ter feedbacks para melhorias, quanto para quem usa, conhecer novas maneiras de se fazer uma determinada coisa.
Reply
#19

Ah, pensava que estava em testes... mas vou usar sim, no prуximo projeto usarei iCMD, valeu Willian.

Parabйns cara!
Reply
#20

Nossa isso ai jб tб no 8.0 eu lembro qnd o viado do drakins e eu fizemos a primeira versгo lб, naquela йpoca ele basicamente fez o msm cуdigo do zcmd e sу removeu as outras callbacks de management e usou condiзгo ternбria dai postou na board inglesa dizendo que fez um processador "mais rapido" ai a gringaiada chingou ele em peso UAHEUAE, sdds desse tempo
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)