[Tutorial] Uso de Y_commands y sscanf
#1

Hola a todos! Aqui les dejo mi tutorial traducido del portugues al espaсol, espero que les guste, les voy a mostrar junto con SmiT como crear un comando con y_commands y sscanf.

Que es y_commands y sscanf?

Bueno y_commands es el procesador de comandos mas rapido y flexible hasta ahora y sscanf es el mejor alternativo para reemplazar el antiguo uso de strtok, ambos fueron creados por ******.

Requisitos y dуnde poner

Bueno, primero tendran que descargar la libreria de YSI y sscanf, aqui les dejo los link:
Despues de descargar copiar /cortar la carpeta "YSI" y colocar la carpeta en "..pawno / include" y poner ahi "sscanf2.inc" tambien copiar / cortar y colocar en la carpeta "...pawno / include" el "YSI".

En cuanto a los plugin

En Windows
  • Tendra que copiar el "sscanf.dll" y colocarlo en la carpeta "plugins" del server. Si esta carpeta no existe, tendra que crearlo.
  • A continuacion, abra el "server.cfg" y agrege "sscanf.dll" en los "Plugins", si no tendra que crearlo de este modo:
Код:
plugins sscanf.dll
En Linux
  • Tendra que copiar el "sscanf.so" y colocarlo en la carpeta "plugins" del server. Si esta carpeta no existe, tendra que crearlo.
  • A continuacion, abra el "server.cfg" y agrege "sscanf.so" en los "Plugins", si no tendra que crearlo de este modo::
Код:
plugins sscanf.so
Agregar en GameMode

Bueno, ahora tenemos que cargar el y_commands y el sscanf. Para eso deberan incluir los includes en la parte de arriva de todo su script(include).

Asн:
pawn Код:
#include <YSI\y_commands>
#include <sscanf2>
Esto cargarб en la carpeta de Cуdigos "..pawno/include/YSI/y_commands.inc" y "..pawno/include/sscanf2.inc" para su script.

Nota
  • Los comandos que crean no pueden estar dentro de cualquier Callbacks, tiene que crearse a fuera

Y ahora la Callback es un cуdigo que ya existe en su script es decir, es una funciуn nativa, ejemplo;

pawn Код:
public OnGameModeInit()
{
    return 1;
}
  • Si se coloca dentro de estos Callback's se producirбn errores, y por lo tanto nos aburrimos y dejaremos la creaciуn del comando.

Adicional Comando
  • Para aсadir un comando basta con estar fuera de cualquier Callback, y usar las siguentes funciones
pawn Код:
YCMD:teste(playerid, params[], help)
{
    return 1;
}
  • params es el parametro string, playerid es el ID del player que hace el comando.
  • y_commands tiene un sistema de ayuda integrado.
Nota

En vez de usar "params" podemos usar "o".
seria asi:

pawn Код:
YCMD:teste(playerid, o, help)
{
    return 1;
}
Sistema help de y_commands
  • Si tu Recurres al uso de este sistema, para confirmar el parametro help un comando habнa sido asн por ejemplo:
Comandos con parametro help:

pawn Код:
YCMD:testando(playerid, params[], help)
{
    if (help) return SendClientMessage(playerid, -1, "comando lindo.");
    SendClientMessage(playerid, -1, "funciona");
    return 1;
}

YCMD:testando2(playerid, params[], help)
{
    if (help) return SendClientMessage(playerid, -1, "comando feo.");
    SendClientMessage(playerid, -1, "funciona2");
    return 1;
}

Ahora, la forma de comprobar es hacer un comando para leer el parametros help, asi:

pawn Код:
YCMD:ayudacomando(playerid, params[], help)
{
    if (isnull(params)) return SendClientMessage(playerid, -1, "uso: /ayudacomando [comando]");
    Command_ReProcess(playerid, params, true);
    // leerб el parametro 'help' comando para poner
    return 1;
}
Creaciуn de comandos sin sscanf
  • Vamos a empezar con un simple comando "/hola" sin recurrir a la utilizaciуn de sscanf.
pawn Код:
YCMD:hola(playerid, params[], help)
{
    SendClientMessage(playerid, -1, "PT el comando funciona!");
    return 1;
}
  • El jugador recibe un mensaje simple , PT el comando funciona!
  • Pero si por casualidad recibe dicha advertencia en la compilaciуn:
Код:
warning 203: symbol is never used "params"
warning 203: symbol is never used "help"
  • la forma de reparar eso es no utilisando el parametros "params" y "help" en su comando:
Podemos decirle al script que no queremos usar el parametro "params" y "help" usando el diretiva "#pragma unused symbol" no comando, asi:

pawn Код:
YCMD:hola(playerid, params[], help)
{
    #pragma unused params, help
    SendClientMessage(playerid, -1, "PT el comando funciona!");
    return 1;
}

Otro Ejemplo
  • Vamos a crear un comando para admin RCON.
pawn Код:
YCMD:adm(playerid, params[], help)
{
    new string[ 128 ];
    new pname[ MAX_PLAYER_NAME ];
   
    if( !IsPlayerAdmin(playerid) ) return SendClientMessage(playerid, -1, "Este comando no lo puedes usar");
    if( help ) return SendClientMessage(playerid, -1, "Este es un comando de admin RCON");
    if( isnull( params ) ) return SendClientMessage(playerid, -1, "Error: /adm [texto]");
    GetPlayerName( playerid, pname, sizeof( pname ) );
    format( string, sizeof( string ),"(RCON) %s: %s", pname, params);
    SendClientMessageToAll(-1, string);
    return 1;
}

String
  • new string[ 128 ]; Declaramos que la variable "string" tiene espacio para 128 caracteres.
pname
  • new pname[ MAX_PLAYER_NAME ]; Declaramos que la variable "pname" tendra todo el nombre de jugador almacenara un maximo de 24 carateres ("MAX_PLAYER_NAME") y el tamaсo mбximo de ese nombre como jugador serб capaz de tener el SA-MP.
Nota

En vez de:
pawn Код:
new string[ 128 ];
new pname[ MAX_PLAYER_NAME ];
Podes hacer asi:
pawn Код:
new string[ 128 ], pname[ MAX_PLAYER_NAME ];
se hizo de esa para manera para que sea mбs fбcil de explicar.

Sistema Help
  • pawn Код:
    if( help ) return SendClientMessage(playerid, -1, "Este es un comando de admin RCON");
    Si el jugador quiere saber mбs sobre el comando ( /ajudacomando adm).
Isnull
  • pawn Код:
    if( isnull( params ) ) return SendClientMessage(playerid, -1, "Error: /adm [texto]");
    Si el parбmetro estб vacнo (isnull) es decir, el jugador asн lo escribiу "/adm" y recibira (return) el mensaje acerca de cуmo utilizar el comando.
Arrays
  • Un array es una variable donde se puede almacenar informacion y acceder a ella de forma dinamica, por ejemplo:
    MAX_PLAYER_NAME
Obtener el nombre del jugador
  • GetPlayerName( playerid, pname, sizeof( pname ) );
    el script obtendrб el nombre del jugador que ejecuta el comando ( "sizeof( pname )" ) y lo pone en array una variable llamada "pname" con el tamaсo mбximo de los MAX_PLAYER_NAME (24) caracteres.
Format
  • pawn Код:
    format( string, sizeof( string ),"(RCON) %s: %s", pname, params);
    Nos formatamos nuestro mensaje, y se almacenarб en la variable "string", y "sizeof( string )" obtendrб el tamaсo mбximo de string, en este caso declaramos 128.
Placeholders
  • "%s"irse a string. La primera "%s"y un placeholder el nombre del jugador y el segundo por el texto que escribe. (/adm [Texto])
SendClientMessageToAll
  • SendClientMessageToAll(-1, string); Esto enviarб el texto que escribiу para todos los jugadores en lнnea.
Ejemplo de uso
  • El rcon adm PT escribe"/adm testando"[/b]
resultado:

Код:
(RCON) PT: testando
Placeholders

Код:
%b para ingresar un numero binario
%c para ingresar un unico caracter
%d para ingresar un numero entero
%f para ingresar un numero con coma 
%i para ingresar un numero entero
%s para ingresar una cadena, como por ejemplo un texto
%x para ingresar un numero hexadecimal
%% para ingresar literalmente el signo '%'
Creaciуn de comandos con sscanf
  • Vamos a empezar con algo simple "/vida" command.
pawn Код:
YCMD:vida(playerid, params[], help)
{
    new ID;
    if( help ) return SendClientMessage(playerid, -1, "Este comando dara vida a 1 jugador!");
    if( sscanf( params, "u", ID ) ) return SendClientMessage(playerid, -1, "Uso: /vida [PlayerName / ID]");
    if( PlayerID == INVALID_PLAYER_ID ) return SendClientMessage(playerid, -1, "[ERROR] Este jugador esta OFFLINE");
    SetPlayerHealth(ID, 100);
    return 1;
}
Declarando

  • new ID; Esta variable declara la id del jugador que le vamos dar vida.
Sistema help
  • pawn Код:
    if( help ) return SendClientMessage(playerid, -1, "Este comando dara vida a 1 jugador!");
    Como siempre si el parбmetro "help" se utiliza, se mostrarб el mensaje que se escribe en la descripciуn del comando.
Sscanf
  • pawn Код:
    if( sscanf( params, "d", ID ) ) return SendClientMessage(playerid, -1, "Error: /vida [ID]");
    Utilizamos el parбmetro, "d" para especificar que el nъmero ese es la id del jugador, el sscanf comprobarб si ponemos lo incorrecto los parбmetros del comando, que en este caso deberнa ser, por ejemplo: /vida 0 si no se ponen de esa manera obtendrб el mensaje de error
INVALID_PLAYER_ID
  • pawn Код:
    if( ID == INVALID_PLAYER_ID ) return SendClientMessage(playerid, -1, "[ERROR] Este jugador esta OFFLINE");
    Esto verificarб que el ID y la ID se ponen en lнnea en el servidor, si no estб recibiendo el mensaje de error.
SetPlayerHealth
  • SetPlayerHealth(ID, 100);
    Esto establecer la vida del ID 100.
La fуrmula de sscanf en un comando
  • La fуrmula de sscanf es esta:
pawn Код:
if(sscanf( params, "Especificaciones", nuestras variables ) )  // Si el jugador entrу en los parбmetros incorrectos
{
 // mensaje para advertir al jugador
}
Especificaciones

Las usamos como al final lo conseguimos

Код:
a - si un personaje.
f - si se trata de un nъmero de punto flotante (float).
i / d - si un nъmero entero.
s - si se trata de una cadena.
x / h - Introduce un nъmero en notaciуn hexadecimal.
z - si un texto opcional
px - si es un delimitador adicional donde X en otro jugador.
'' - Para localizar una cadena (de texto).
u - parte de un nombre o un ID
Comandos

  • y_commands cuenta con un sistema especial que detecta todos los comandos que usted tiene en su escritura lo que no necesita es ir siempre para actualizar su "/comandos"
  • pawn Код:
    YCMD:comandos(playerid, params[], help)
    {
        if ( help ) return SendClientMessage(playerid, -1, "Lista de todos los comandos.");
        new count = Command_GetPlayerCommandCount( playerid );
       
        for ( new i = 0; i != count; ++i) SendClientMessage( playerid, -1, Command_GetNext ( i, playerid ) );
        return 1;
    }
Mensaje: UNKNOWN COMMAND
  • Cuando un jugador escribe un comando que no existe, recibe el mensaje: "SERVER: Unknown Command." entonces cуmo puedo cambiar este mensaje?
    Simplemente ponga la CallBack OnPlayerCommandPerformed y el uso, por ejemplo asн:

    pawn Код:
    public OnPlayerCommandPerformed(playerid, cmdtext[], success)
    {
        if( !success ) return false;
        return true;
    }
Pero podemos poner un mensaje para ser mбs agradable para ser visto, para usarlo de esta manera:
  • pawn Код:
    public OnPlayerCommandPerformed(playerid, cmdtext[], success)
    {
        if( !success )
        {
            format( cmdtext, 128, "ERROR: El comando %s no existe mira /comandos", cmdtext );
            SendClientMessage( playerid, -1, cmdtext );
           
        }
        return true;
    }
Resultado final

pawn Код:
// This is a comment
// uncomment the line below if you want to write a filterscript
//#define FILTERSCRIPT

#include <a_samp>
#include <YSI\y_commands>
#include <sscanf2>

#if defined FILTERSCRIPT

public OnFilterScriptInit()
{
    print("\n--------------------------------------");
    print(" Blank Filterscript by your name here");
    print("--------------------------------------\n");
    return 1;
}

public OnFilterScriptExit()
{
    return 1;
}

#else

main()
{
    print("\n----------------------------------");
    print(" Blank Gamemode by your name here");
    print("----------------------------------\n");
}

#endif

public OnGameModeInit()
{
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
    Command_AddAltNamed("information", "info");
    return 1;
}

public OnGameModeExit()
{
    return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
    SetPlayerPos(playerid, 1958.3783, 1343.1572, 15.3746);
    SetPlayerCameraPos(playerid, 1958.3783, 1343.1572, 15.3746);
    SetPlayerCameraLookAt(playerid, 1958.3783, 1343.1572, 15.3746);
    return 1;
}

public OnPlayerConnect(playerid)
{
    return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    return 1;
}

public OnPlayerSpawn(playerid)
{
    return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
    return 1;
}

public OnVehicleSpawn(vehicleid)
{
    return 1;
}

public OnVehicleDeath(vehicleid, killerid)
{
    return 1;
}

public OnPlayerText(playerid, text[])
{
    return 1;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
    if (strcmp("/mycommand", cmdtext, true, 10) == 0)
    {
        // Do something here
        return 1;
    }
    return 0;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
    return 1;
}

public OnPlayerExitVehicle(playerid, vehicleid)
{
    return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
    return 1;
}

public OnPlayerEnterCheckpoint(playerid)
{
    return 1;
}

public OnPlayerLeaveCheckpoint(playerid)
{
    return 1;
}

public OnPlayerEnterRaceCheckpoint(playerid)
{
    return 1;
}

public OnPlayerLeaveRaceCheckpoint(playerid)
{
    return 1;
}

public OnRconCommand(cmd[])
{
    return 1;
}

public OnPlayerRequestSpawn(playerid)
{
    return 1;
}

public OnObjectMoved(objectid)
{
    return 1;
}

public OnPlayerObjectMoved(playerid, objectid)
{
    return 1;
}

public OnPlayerPickUpPickup(playerid, pickupid)
{
    return 1;
}

public OnVehicleMod(playerid, vehicleid, componentid)
{
    return 1;
}

public OnVehiclePaintjob(playerid, vehicleid, paintjobid)
{
    return 1;
}

public OnVehicleRespray(playerid, vehicleid, color1, color2)
{
    return 1;
}

public OnPlayerSelectedMenuRow(playerid, row)
{
    return 1;
}

public OnPlayerExitedMenu(playerid)
{
    return 1;
}

public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
{
    return 1;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    return 1;
}

public OnRconLoginAttempt(ip[], password[], success)
{
    return 1;
}

public OnPlayerUpdate(playerid)
{
    return 1;
}

public OnPlayerStreamIn(playerid, forplayerid)
{
    return 1;
}

public OnPlayerStreamOut(playerid, forplayerid)
{
    return 1;
}

public OnVehicleStreamIn(vehicleid, forplayerid)
{
    return 1;
}

public OnVehicleStreamOut(vehicleid, forplayerid)
{
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    return 1;
}

public OnPlayerClickPlayer(playerid, clickedplayerid, source)
{
    return 1;
}

YCMD:teste(playerid, params[], help)
{
    return 1;
}

YCMD:teste(playerid, o, help)
{
    return 1;
}

YCMD:testando(playerid, params[], help)
{
    if (help) return SendClientMessage(playerid, -1, "comando lindo.");
    SendClientMessage(playerid, -1, "funciona");
    return 1;
}

YCMD:testando2(playerid, params[], help)
{
    if (help) return SendClientMessage(playerid, -1, "comando feo.");
    SendClientMessage(playerid, -1, "funciona2");
    return 1;
}

YCMD:ayudacomando(playerid, params[], help)
{
    if (isnull(params)) return SendClientMessage(playerid, -1, "uso: /ayudacomando [comando]");
    Command_ReProcess(playerid, params, true);
    // leerб el parametro 'help' comando para poner
    return 1;
}

YCMD:hola(playerid, params[], help)
{
    #pragma unused params, help
    SendClientMessage(playerid, -1, "PT el comando funciona!");
    return 1;
}

YCMD:adm(playerid, params[], help)
{
    new string[ 128 ];
    new pname[ MAX_PLAYER_NAME ];
   
    if( !IsPlayerAdmin(playerid) ) return SendClientMessage(playerid, -1, "Este comando no lo puedes usar");
    if( help ) return SendClientMessage(playerid, -1, "Este es un comando de admin RCON");
    if( isnull( params ) ) return SendClientMessage(playerid, -1, "Error: /adm [texto]");
    GetPlayerName( playerid, pname, sizeof( pname ) );
    format( string, sizeof( string ),"(RCON) %s: %s", pname, params);
    SendClientMessageToAll(-1, string);
    return 1;
}

YCMD:vida(playerid, params[], help)
{
    new ID;
    if( help ) return SendClientMessage(playerid, -1, "Este comando dara vida a 1 jugador!");
    if( sscanf( params, "u", ID ) ) return SendClientMessage(playerid, -1, "Uso: /vida [PlayerName / ID]");
    if( PlayerID == INVALID_PLAYER_ID ) return SendClientMessage(playerid, -1, "[ERROR] Este jugador esta OFFLINE");
    SetPlayerHealth(ID, 100);
    return 1;
}

YCMD:comandos(playerid, params[], help)
{
    if ( help ) return SendClientMessage(playerid, -1, "Lista de todos los comandos.");
    new count = Command_GetPlayerCommandCount( playerid );
   
    for ( new i = 0; i != count; ++i) SendClientMessage( playerid, -1, Command_GetNext ( i, playerid ) );
    return 1;
}

public OnPlayerCommandPerformed(playerid, cmdtext[], success)
{
    if( !success )
    {
        format( cmdtext, 128, "ERROR: El comando %s no existe mira /comandos", cmdtext );
        SendClientMessage( playerid, -1, cmdtext );
       
    }
    return true;
}
  • Si se me olvidу algo o me expliquй mal en algo, por favor informen. Hice mi mejor esfuerzo para explicarles a ustedes.
Crйditos
  • ****** - el procesador de comandos y sscanf
    SA:MP Wiki - por referencias
    Raylan Givens - por ayudarme a traducir ( Gracias amigo )
    PT y SmiT - El tutorial
Reply
#2

Hacia falta uno de estos tutorial, ya que no hay ningъn "creo" en esta secciуn, se agradece mucho "PT" por el tutorial muy bien explicado, mucha paciencia, cuando pueda te doy rep!

Saludos.
Reply
#3

Buen tutorial amigo, yo tambien estoy haciendo un tuto.. manana lo leo bien
Reply
#4

Muy bueno !
Reply
#5

Quote:
Originally Posted by Raylan Givens
Посмотреть сообщение
Hacia falta uno de estos tutorial, ya que no hay ningъn "creo" en esta secciуn, se agradece mucho "PT" por el tutorial muy bien explicado, mucha paciencia, cuando pueda te doy rep!

Saludos.
Gracias, y gracias por la ayuda

Quote:
Originally Posted by Adoniiz
Посмотреть сообщение
Buen tutorial amigo, yo tambien estoy haciendo un tuto.. manana lo leo bien
Gracias

Quote:
Originally Posted by Willian_Luigi
Посмотреть сообщение
Muy bueno !
Gracias
Reply
#6

Me gustу y me servirб mucho. Gracias amigo .

+Rep.
Reply
#7

Quote:
Originally Posted by EnzoMetlc
Посмотреть сообщение
Me gustу y me servirб mucho. Gracias amigo .

+Rep.
Gracias
Reply
#8

-Perfecto
-Bien explicado
- +rep
Reply
#9

Buen trabajo PT, aunque yo me quedo con el viejo zcmd, jeje...
Reply
#10

Se podria explotar mucho mas y_commands, pero es un muy buen comienzo para alguien nuevo. Buen tutorial. Solo un encontre un detalle a simple vista:
Quote:
Originally Posted by PT
Посмотреть сообщение
String
  • new string[ 128 ]; Declaramos que la variable "string" tiene espacio para 127 caracteres.
Si declaras un array de tamaсo N, puedes colocar N caracteres dentro del mismo (no N-1 como indicas); esto se debe a que se utiliza desde la posicion 0 hasta la N-1 inclusive.

ej:
pawn Код:
new array[2];
array[0] = 'a'; //El 1er caracter es la 'a'
array[1] = 'b'; //El 2do caracter es la 'b'
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)