[Tutorial] Crear sistema de administracion con registro y pequeсo anticheat
#1

Bueno como mi post numero 1000 se me ocurrio hacer algo lindo pero util, asi q despues de un rato de pensar, se me ocurrio hacer este tutorial, en el cual

explicare paso a paso como crear un sistema de administracion, relativamente sensillo, el cual tendra un sistema de registro por dialogos y varios comandos

utiles, ademas de un pequeсo sistema de anti-cheat(dinero y armas)

Lo que necesitaremos para nuesto FS.
•el pawno
•conocimientos basicos sobre pawn, ya que no se explicaran todas las funciones usadas.
dudb (include) por DracoBlue
DUtils por DracoBlue (neesario para el dudb)
DINI por DracoBlue (neesario para el dudb)
•ganas de leer y trabajar un poquito:P

bueno, una vez q tenemos todo esto, manos a la obra:

1є Paso los includes
pawn Код:
//arriba del todo
#include <a_samp>
#include <dudb>
#pragma unused ret_memcpy
2є Paso la definicion de dcmd
pawn Код:
//debajo de los includes
#define dcmd(%1,%2,%3) if (!strcmp((%3)[1], #%1, true, (%2)) && ((((%3)[(%2) + 1] == '\0') && (dcmd_%1(playerid, ""))) || (((%3)[(%2) + 1] == ' ') && (dcmd_%1

(playerid, (%3)[(%2) + 2]))))) return 1
3є Paso definicion de los colores que usaremos para facilitar el uso de los mismos y dos arrays
pawn Код:
//debajo de la definicion de dcmd
#define COLOR_ROJO 0xFF0000AA
#define COLOR_BLANCO 0xFFFFFFAA
#define COLOR_AZUL 0x004FD8F6
#define COLOR_NARANJA 0xFF9900AA
#define COLOR_AMARILLO 0xF6F600F6
#define COLOR_VERDE 0x33AA33AA
#define COLOR_GRIS 0xAFAFAFAA
//dialogos
#define REGISTRO 0
#define LOGIN 1
//modos de spec
#define ADMIN_SPEC_TYPE_NONE 0
#define ADMIN_SPEC_TYPE_PLAYER 1
#define ADMIN_SPEC_TYPE_VEHICLE 2
4є Paso Creacion de arrays para almacenar los datos del jugador
pawn Код:
enum Datos //crea un array de variables.
{
  registrado,
  logueado,
  asesinatos,
  muertes,
  dinero,
  congelado,
  callado,
  mirandoID,
  nivel,
  SpecType,
}

new pInfo[MAX_PLAYERS][Datos]; //Datos puede tomar cualquier variable de las anteriormente definidas.
5є Paso Empezaremos con la definicion los comandos
pawn Код:
public OnPlayerCommandText(playerid, cmdtext[])
{
  //definimos los comandos que usaremos
  //dcmd(comando, 7, cmdtext): dcmd(nombre del comando, largo del nombre, cmdtext).
  dcmd(ban, 3, cmdtext);
  dcmd(mirar, 5, cmdtext);
  dcmd(callar, 6, cmdtext);
  dcmd(nomirar, 7, cmdtext);
  dcmd(darvida, 7, cmdtext);
  dcmd(darnivel, 8, cmdtext);
  dcmd(expulsar, 8, cmdtext);
  dcmd(congelar, 8, cmdtext);
  dcmd(ingresar, 8, cmdtext);
  dcmd(registrar, 9, cmdtext);
  dcmd(darchaleco, 10, cmdtext);
  dcmd(limpiarchat, 11, cmdtext);
  return 0;
}
6є Paso Los comandos en si, es decir las funciones de cada uno y su respectivo codigo
pawn Код:
dcmd_ban(playerid, params[]){
  if(pInfo[playerid][nivel] >= 4 || IsPlayerAdmin(playerid)){//restriccion para que solo los admins de nivel 4 o superior puedan usar el comando
    new tmp[256], tmp2[256], Index;//arrays
    tmp = strtok(params, Index);//tomara el 1 valor del comando, es decir la id del jugador
    tmp2 = strtok(params, Index);//tomara el 2 valor del comando, es decir la razon del ban
    if(!strlen(params) || !IsNumeric(tmp))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /ban <playerid> <razуn>");//comprobamos que hayan igresado los argumentos, y que la id sea un numero.
    if(!strlen(tmp2))return SendClientMessage(playerid, COLOR_ROJO, "ERROR: Debes ingresar una razуn");
    new jugador, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128]; //arrays que usaremos para almacenar nombres, la id del jugador y un mensaje
    jugador = strval(tmp);//jugador =valor de tmp es decir la id.
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){ //restriccion para saber si el jugador que se quiere banear esta conectado o no, y si la id es valida
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){ //restriccion para saber si el jugador que se quiere banear posee un nivel de admin mayor o es admin RCON
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        if(pInfo[jugador][registrado] == 1 && pInfo[jugador][logueado] == 1){//si el jugador esta registrado, entonces tambien baneamos su cuenta
          dUserSetINT(name).("Baneado",1);
        }
        format(str, sizeof(str), "El administrador %s ha baneado a %s [Razуn: %s]", admin, name, params[2]);
        SendClientMessageToAll(COLOR_GRIS, str);
        format(str, sizeof(str), "Has sido baneado por el administrador %s, [Razуn: %s]", admin, params[2]);
        return BanEx(jugador, str);
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_mirar(playerid, params[]){
  if(pInfo[playerid][nivel] >= 5 || IsPlayerAdmin(playerid)){
    new tmp[256], Index;
    tmp = strtok(params, Index);
    if(!strlen(params))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /mirar <playerid>");
    new jugador;
    jugador = strval(tmp);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        if(pInfo[jugador][mirandoID] == -1){
          return StartSpectate(playerid, jugador);
        }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: Este jugador ya esta espectando a alguien");
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_callar(playerid, params[]){
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(params) || !IsNumeric(tmp))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /callar <playerid> opcional <razуn>");
    new jugador, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        if(pInfo[jugador][callado] == 0){
          if(!strlen(tmp2)){
            format(str, sizeof(str), "El administrador %s ha callado a %s. [Razуn: No ha dado]", admin, name);
          }else{
            format(str, sizeof(str), "El administrador %s ha callado a %s. [Razуn: %s]", admin, name, params[2]);
          }
          SendClientMessageToAll(COLOR_GRIS, str);
          return pInfo[jugador][callado] = 1;
        }
        else{
          format(str, sizeof(str), "El administrador %s le ha permitido hablar a %s.", admin, name);
          pInfo[jugador][callado] = 0;
          return SendClientMessageToAll(COLOR_GRIS, str);
        }
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_nomirar(playerid, params[]){
  #pragma unused params
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    if(pInfo[playerid][mirandoID] != 0){
      StopSpectate(playerid);
      pInfo[playerid][mirandoID] = -1;
      return 1;
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No estas spectando");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_darnivel(playerid, params[]){
  if(pInfo[playerid][nivel] >= 5 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(tmp) || !strlen(tmp2) || !IsNumeric(tmp) || !IsNumeric(tmp2))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /darnivel <playerid> <nivel>");
    new jugador, Nivel, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    Nivel = strval(tmp2);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        if(Nivel <= pInfo[playerid][nivel]){
          GetPlayerName(jugador, name, sizeof(name));
          GetPlayerName(playerid, admin, sizeof(admin));
          format(str, sizeof(str), "El administrador %s ha seteado tu nivel a %d.", admin, Nivel);
          SendClientMessage(jugador, COLOR_AMARILLO, str);
          pInfo[jugador][nivel] = Nivel;
          return 1;
        }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes dar un nivel mayor al tuyo");
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_darvida(playerid, params[]){
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(tmp) || !strlen(tmp2) || !IsNumeric(tmp) || !IsNumeric(tmp2))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /darvida <playerid> <vida>");
    new jugador, vida, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    vida = strval(tmp2);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        format(str, sizeof(str), "El administrador %s ha seteado tu vida a %d.", admin, vida);
        SendClientMessage(jugador, COLOR_AMARILLO, str);
        return SetPlayerHealth(jugador, vida);
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_expulsar(playerid, params[]){
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(params) || !IsNumeric(tmp))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /expulsar <playerid> opcional <razуn>");
    new jugador, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        if(!strlen(tmp2)){//si no hay razon, entonces....
          format(str, sizeof(str), "El administrador %s ha kickeado a %s. [Razуn: No ha dado]", admin, name);
        }else{//si no...
          format(str, sizeof(str), "El administrador %s ha kickeado a %s. [Razуn: %s]", admin, name, params[2]);
        }
        SendClientMessageToAll(COLOR_GRIS, str);
        return Kick(jugador);
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_congelar(playerid, params[]){
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(params) || !IsNumeric(tmp))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /congelar <playerid> opcional <razуn>");
    new jugador, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        if(pInfo[jugador][congelado] == 0){
          if(!strlen(tmp2)){
            format(str, sizeof(str), "El administrador %s ha congelado a %s. [Razуn: No ha dado]", admin, name);
          }else{
            format(str, sizeof(str), "El administrador %s ha congelado a %s. [Razуn: %s]", admin, name, params[2]);
          }
          SendClientMessageToAll(COLOR_GRIS, str);
          pInfo[jugador][congelado] = 1;
          return TogglePlayerControllable(jugador, 0);
        }
        else{
          format(str, sizeof(str), "El administrador %s ha descongelado a %s.", admin, name);
          SendClientMessageToAll(COLOR_GRIS, str);
          pInfo[jugador][congelado] = 0;
          return TogglePlayerControllable(jugador, 1);
        }
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_ingresar(playerid, params[]){
  #pragma unused params
  new name[MAX_PLAYER_NAME];
  GetPlayerName(playerid, name, sizeof(name));
  if(pInfo[playerid][logueado] == 1) return SendClientMessage(playerid, COLOR_ROJO, "ERROR: Ya estas registrado y logueado");
  if(!udb_Exists(name))
  {
    SendClientMessage(playerid, COLOR_ROJO, "ERROR: La cuenta no existe, por favor usa");
    return SendClientMessage(playerid, COLOR_ROJO, "/register para poder registrarla");
  }
  return ShowPlayerDialog(playerid, LOGIN, 1, "Login", "Ingresa la contraseсa para loguearte con esta cuenta", "Aceptar", "Cancelar");
}

dcmd_registrar(playerid, params[]){
  #pragma unused params
  new name[MAX_PLAYER_NAME];
  GetPlayerName(playerid, name, sizeof(name));
  if(pInfo[playerid][logueado] == 1) return SendClientMessage(playerid, COLOR_ROJO, "ERROR: Ya estas registrado y logueado");
  if(udb_Exists(name)){
    SendClientMessage(playerid, COLOR_ROJO, "ERROR: La cuenta ya esta registrada, por favor usa");
    return SendClientMessage(playerid, COLOR_ROJO, "/login para poder loguearte");
  }
  return ShowPlayerDialog(playerid, REGISTRO, 1, "Registro", "Ingresa la contraseсa para registrar tu cuenta", "Aceptar", "Cancelar");
}

dcmd_darchaleco(playerid, params[]){
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    new tmp[256], tmp2[256], Index;
    tmp = strtok(params, Index);
    tmp2 = strtok(params, Index);
    if(!strlen(tmp) || !strlen(tmp2) || !IsNumeric(tmp) || !IsNumeric(tmp2))return SendClientMessage(playerid, COLOR_BLANCO, "USO: /darchaleco <playerid> <chaleco>");
    new jugador, chaleco, name[MAX_PLAYER_NAME], admin[MAX_PLAYER_NAME], str[128];
    jugador = strval(tmp);
    chaleco = strval(tmp2);
    if(IsPlayerConnected(jugador) || jugador != INVALID_PLAYER_ID){
      if(pInfo[jugador][nivel] < pInfo[playerid][nivel] || !IsPlayerAdmin(jugador)){
        GetPlayerName(jugador, name, sizeof(name));
        GetPlayerName(playerid, admin, sizeof(admin));
        format(str, sizeof(str), "El administrador %s ha seteado tu chaleco a %d.", admin, chaleco);
        SendClientMessage(jugador, COLOR_AMARILLO, str);
        return SetPlayerArmour(jugador, chaleco);
      }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No puedes usar este comando sobre este jugador");
    }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: El jugador no esta conectado o la id no es correcta");
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}

dcmd_limpiarchat(playerid, params[]){
  #pragma unused params //con esto indicamos que no usaremos los parametros.
  if(pInfo[playerid][nivel] >= 1 || IsPlayerAdmin(playerid)){
    for(new i=0; i<60; i++){//creamos un loop o bucle que toma todos los valores de 0 a 60.
      for(new p=0; p<MAX_PLAYERS; p++){//creamos un loop o bucle que toma todos los valores de los jugadores
        if(IsPlayerConnected(p)){
          if(pInfo[p][nivel] == 0 || !IsPlayerAdmin(p)){//si el jugador p esta conectado, y no es admin, entonces...
            SendClientMessage(p, COLOR_BLANCO, " ");
          }
        }
      }
    }
    return 1;
  }else return SendClientMessage(playerid, COLOR_ROJO, "ERROR: No posees el nivel suficiente para usar este comando");
}
Reply
#2

7є Paso Evitar que el jugador hable si esta callado y el chat de los admins
pawn Код:
public OnPlayerText(playerid, text[])
{
  //chat de admins
  if(text[0] == '#'){
    if(pInfo[playerid][nivel] > 0){
      new str[128], name[MAX_PLAYER_NAME];
      GetPlayerName(playerid, name, sizeof(name));
      format(str, sizeof(str), "Admin Chat: %s, %s",name, text[1]);
      AdminChat(COLOR_AZUL, str); //envia el mensaje a los demas administradores
    }
    return 0;
  }
  //evitar que hable si esta callado
  if(pInfo[playerid][callado] == 1){
    SendClientMessage(playerid, COLOR_ROJO, "ERROR: Estas callado y no puedes hablar");
    return 0;
  }
  return 1;
}
8є Paso Spec avanzado y score por muertes
pawn Код:
public OnPlayerDeath(playerid, killerid, reason)
{
  pInfo[playerid][muertes]++; //aumenta las muertes del jugador que murio en 1
  pInfo[killerid][asesinatos]++; //aumenta los asesinatos del jugador que mato en 1

  //aca hacemos el spec avanzado cuando el jugador muere.
  for(new x=0; x<MAX_PLAYERS; x++){//bucle q recorre todos los jugadores
    if(GetPlayerState(x) == PLAYER_STATE_SPECTATING && pInfo[x][mirandoID] == playerid){//si alguno de esos jugadores esta espectando al jugador que murio...
      AdvanceSpectate(x);//se activa la funcion advance spectate
    }
  }

  return 1;
}
9є Paso Registro y Logeo
pawn Код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
  new name[MAX_PLAYER_NAME];
  GetPlayerName(playerid, name, sizeof(name));
  if(dialogid == REGISTRO){
    if(response){
      if(strlen(inputtext) < 3 || strlen(inputtext) > 20){//verifica el largo de la contraseсa, si es muy chica o muy larga entonces no dejara que la registres
        SendClientMessage(playerid, COLOR_ROJO, "ERROR: La contraseсa debe tener un largo de entre 3-20 caracteres");
        return ShowPlayerDialog(playerid, REGISTRO, 1, "Registro", "Ingresa la contraseсa para registrar tu cuenta", "Aceptar", "Cancelar");
      }

      if(udb_Create(name, inputtext)){
        dUserSetINT(name).("Nivel",0);
        dUserSetINT(name).("Baneado",0);
        dUserSetINT(name).("Asesinatos",0);
        dUserSetINT(name).("Muertes",0);
        dUserSetINT(name).("Dinero",0);
        pInfo[playerid][registrado] = 1;
        SendClientMessage(playerid, COLOR_VERDE, "Servidor: La cuenta fue creada con exito.");
        return ShowPlayerDialog(playerid, LOGIN, 1, "Login", "Ingresa la contraseсa para loguearte con esta cuenta", "Aceptar", "Cancelar");
      }
    }
    else{
      SendClientMessage(playerid, COLOR_ROJO, "[[Info]]Has canselado el registro de tu cuenta");
    }
  }
  else if(dialogid == LOGIN){
    if(response){
      if(udb_Exists(name)){
        if(udb_CheckLogin(name, inputtext)){
          pInfo[playerid][nivel] = dUserINT(name).("Nivel");
          pInfo[playerid][asesinatos] = dUserINT(name).("Asesinatos");
          pInfo[playerid][muertes] = dUserINT(name).("Muertes");
          pInfo[playerid][dinero] = dUserINT(name).("Dinero");
          pInfo[playerid][logueado] = 1;
          if(pInfo[playerid][nivel] > 0){
            new str[128];
            format(str, sizeof(str), "Server: %s has sido logueado como admin exitosamente. [Level: %d]", name, pInfo[playerid][nivel]);
            return SendClientMessage(playerid, COLOR_VERDE, str);
          }else return SendClientMessage(playerid, COLOR_VERDE, "Server: Has sido logueado exitosamente.");
        }
      }
      else{
        SendClientMessage(playerid, COLOR_ROJO, "ERROR: Contraseсa incorrecta");
      }
        }
    else{
      SendClientMessage(playerid, COLOR_ROJO, "[[Info]]Has canselado el logueo de la cuenta");
    }
  }
  return 1;
}
10є Paso Guardar Datos del jugador y detectar existencia de cuenta
pawn Код:
//detectar si el usuario se encuentra registrado o no
public OnPlayerConnect(playerid)
{
  new name[MAX_PLAYER_NAME];
  GetPlayerName(playerid, name, sizeof(name));
  if(udb_Exists(name)){
    pInfo[playerid][registrado] = 1;
  }
  return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
  new str[128], name[MAX_PLAYER_NAME];
  GetPlayerName(playerid, name, sizeof(name));
  //motivo por el cual salio el jugador
  switch(reason){
    case 0: format(str, sizeof(str), "*** %s (%d) ha dejado el servidor.(Crash)", name, playerid);
    case 1: format(str, sizeof(str), "*** %s (%d) ha dejado el servidor (Salio)", name, playerid);
    case 2: format(str, sizeof(str), "*** %s (%d) ha dejado el servidor (Kickeado/Baneado)", name, playerid);
  }
  SendClientMessageToAll(COLOR_GRIS, str);

  //guardar los datos del jugador
  dUserSetINT(name).("Nivel",pInfo[playerid][nivel]);
  dUserSetINT(name).("Asesinatos",pInfo[playerid][asesinatos]);
  dUserSetINT(name).("Muertes",pInfo[playerid][muertes]);
  dUserSetINT(name).("Dinero",pInfo[playerid][dinero]);

  pInfo[playerid][registrado] = 0;
  pInfo[playerid][logueado] = 0;
  pInfo[playerid][asesinatos] = 0;
  pInfo[playerid][muertes] = 0;
  pInfo[playerid][dinero] = 0;
  pInfo[playerid][congelado] = 0;
  pInfo[playerid][callado] = 0;
  pInfo[playerid][mirandoID] = -1;
  pInfo[playerid][nivel] = 0;

  return 1;
}
11є Paso Pequeсas funciones de anticheat
pawn Код:
//para no hacerlo dentro de OnPlayerUpdate, lo haremos con un timer que tarde un poco mas.

public OnFilterScriptInit()
{
  SetTimer("AntiCheat", 5000, 1);//definimos nuestro timer
  return 1;
}

forward AntiCheat();
public AntiCheat()
{
  for(new i=0; i<MAX_PLAYERS; i++){
    if(IsPlayerConnected(i)){
      new str[128], name[MAX_PLAYER_NAME];
      GetPlayerName(i, name, sizeof(name));
      if(pInfo[i][dinero] != GetPlayerMoney(i)){
        format(str, sizeof(str), "Se ha kickeado al jugador %s(%d). [Razуn: Posible Cheat de dinero]", name, i);
        SendClientMessageToAll(COLOR_GRIS, str);
        Kick(i);
      }
      new weap, ammo;
      GetPlayerWeaponData(i, 7, weap, ammo);
      if((weap == 38 || weap == 37 || weap == 36 || weap == 25) && ammo != 0){//38=minigun, 37=lanza llamas, 36=bazooka de calor, 35=bazooka
        format(str, sizeof(str), "Se ha kickeado al jugador %s(%d). [Razуn: Posible Cheat de arma]", name, i);
        Kick(i);
      }
    }
  }
}
12є Paso funciones necesarias
pawn Код:
//---------------------------------------------//
// FUNCION PARA DAR DINERO CON EL ANTICHEAT  //
//---------------------------------------------//
stock GivePlayerMoneyEx(playerid, amount)   //
{                       //
  pInfo[playerid][dinero] += amount;     //
    GivePlayerMoney(playerid, amount);     //
    return 1;                 //
}                       //
//---------------------------------------------//

stock AdminChat(color, const text[])
{
  for(new i=0; i<MAX_PLAYERS; i++){
    if(IsPlayerConnected(i) && pInfo[i][nivel] > 0){
        SendClientMessage(i, color, text);
    }
  }
}

stock IsNumeric(str[])
{
  for (new i = 0, j = strlen(str); i < j; i++){
    if (str[i] > '9' || str[i] < '0') return 0;
  }
  return 1;
}

forward ConnectedPlayers();
public ConnectedPlayers()
{
    new Connected;
    for(new i = 0; i < MAX_PLAYERS; i++) if(IsPlayerConnected(i)) Connected++;
    return Connected;
}

stock StartSpectate(playerid, specplayerid)
{
  for(new x=0; x<MAX_PLAYERS; x++){
    if(GetPlayerState(x) == PLAYER_STATE_SPECTATING && pInfo[x][mirandoID] == playerid){
      AdvanceSpectate(x);
    }
  }
  SetPlayerInterior(playerid,GetPlayerInterior(specplayerid));
  TogglePlayerSpectating(playerid, 1);
  if(IsPlayerInAnyVehicle(specplayerid)){
    PlayerSpectateVehicle(playerid, GetPlayerVehicleID(specplayerid));
    pInfo[playerid][mirandoID] = specplayerid;
    pInfo[playerid][SpecType] = ADMIN_SPEC_TYPE_VEHICLE;
  }
  else{
    PlayerSpectatePlayer(playerid, specplayerid);
    pInfo[playerid][mirandoID] = specplayerid;
    pInfo[playerid][SpecType] = ADMIN_SPEC_TYPE_PLAYER;
  }
  new str[100], Float:hp, Float:ar;
  GetPlayerName(specplayerid,str,sizeof(str));
  GetPlayerHealth(specplayerid, hp);    GetPlayerArmour(specplayerid, ar);
  format(str,sizeof(str),"~n~~n~~n~~n~~n~~n~~n~~n~~w~%s - id:%d~n~< sprint - jump >~n~hp:%0.1f ar:%0.1f $%d", str,specplayerid,hp,ar,pInfo[specplayerid]

[dinero]);
  GameTextForPlayer(playerid,str,25000,3);
  return 1;
}

stock StopSpectate(playerid)
{
  TogglePlayerSpectating(playerid, 0);
  pInfo[playerid][mirandoID] = INVALID_PLAYER_ID;
  pInfo[playerid][SpecType] = ADMIN_SPEC_TYPE_NONE;
  GameTextForPlayer(playerid,"~n~~n~~n~~w~Spectate mode ended",1000,3);
  return 1;
}

stock AdvanceSpectate(playerid)
{
  if(ConnectedPlayers() == 2){ StopSpectate(playerid); return 1; }
  if(GetPlayerState(playerid) == PLAYER_STATE_SPECTATING && pInfo[playerid][mirandoID] != INVALID_PLAYER_ID){
    for(new x=pInfo[playerid][mirandoID]+1; x<=MAX_PLAYERS; x++){
      if(x == MAX_PLAYERS) x = 0;
      if(IsPlayerConnected(x) && x != playerid){
        if(GetPlayerState(x) == PLAYER_STATE_SPECTATING && pInfo[x][mirandoID] != INVALID_PLAYER_ID || (GetPlayerState(x) != 1 && GetPlayerState(x)

!= 2 && GetPlayerState(x) != 3)){
        continue;
        }
        else{
          StartSpectate(playerid, x);
          break;
        }
      }
    }
  }
  return 1;
}
Creditos:

Spec => kye & LAdmin4v2
idea => mia :P

Espero que les haya gustado y les haya servido, cualquier duda consulten y cualquier error avisen

Edit:

solo una cosa me olvide de decirles, para cambiarle la ruta en la cual se crean sus cuentas, deben modificar el .inc del dudb. Para hacerlo, solo deben buscar dentro del mismo:"%s.dudb.sav" y cambiarlo por "ruta/%s.sav"
Reply
#3

Muy util, y nuevo ya que nadie se le hubiera ocurrido esto! xD. Felicitaciones
Reply
#4

gracias, lo mejor fue tenert a vos esperandolo con la intriga de saber sobre q era xD
Reply
#5

Wo0w xD si ubieses puesto esto antes XD no se que ubiera echo haha
Y gracias asi se como crearlo en Dialog

Muy Bueno The_Chaoz
Reply
#6

muy bueno te refelicito xd
Reply
#7

solo una cosa me olvide de decirles, para cambiarle la ruta en la cual se crean sus cuentas, deben modificar el .inc del dudb. Para hacerlo, solo deben buscar dentro del mismo:"%s.dudb.sav" y cambiarlo por "ruta/%s.sav"

igual ahora lo agrego al topic
Reply
#8

Desde ya te digo, lo combinare con el Sistema de Niveles de Laborgward, el Sistema de Clanes de Infierno, y hare un super FS de Clanes, Administracion y Niveles.

Es decir, gracias por esta gran ayuda XD.
Reply
#9

Muy bueno the_chaos y muy bien explicado felicitaciones...
Quote:
Originally Posted by Leaan(L)
Desde ya te digo, lo combinare con el Sistema de Niveles de Laborgward, el Sistema de Clanes de Infierno, y hare un super FS de Clanes, Administracion y Niveles.

Es decir, gracias por esta gran ayuda XD.
:O, y si unis eso con un buen GM te armas un super server
pienso yo nose...

salu2
Reply
#10

Quote:
Originally Posted by Leaan(L)
Desde ya te digo, lo combinare con el Sistema de Niveles de Laborgward, el Sistema de Clanes de Infierno, y hare un super FS de Clanes, Administracion y Niveles.

Es decir, gracias por esta gran ayuda XD.
igual es muy basico lo que esta explicado, es como para que se orienten y vean como comenzar.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)