[Tutorial] Haciendo un anti-armas.
#1

Hoy estaba totalmente al pedo y querнa ver si me salia hacer un anticheat, y bueno me funcionу. Asн que acб les voy a explicar mбs o menos como hacerlo.

Paso 1: Vamos definir 3 colores para utilizar, yo utilizarй rojo, verde y crema. Esto debemos ponerlo sobre todo el script.

pawn Код:
#define COLOR_GREEN 0x33AA33AA
#define COLOR_RED 0xAA3333AA
#define CREMA_ADMIN 0xFFFFD4D4
Paso 2: Necesitamos crear las variables que utilizaremos en todo el script.

pawn Код:
static
    Armas[MAX_PLAYERS][13], // Acб guardaremos todas las armas de los jugadores.
    Municion[MAX_PLAYERS][13], // Acб guardaremos las municiones de cada arma de los jugadores.
    temp_arm[13][2], // Esta variable la utilizaremos para comprobar las armas que tiene el jugador en el momento.
    w_nombre[MAX_PLAYER_NAME], // Para almacenar el nombre de las armas/jugadores.
    w_str[128], // Para darle un formato a los texto.
    Timer_Armas[MAX_PLAYERS]; // Acб crearemos los timers para cada jugador ( que comprueba las armas )
Paso 3: Vamos a crear el timer que se repetirб todo el tiempo mientras ese jugador estй conectado.

pawn Код:
public OnPlayerConnect(playerid) // Callback llamada cada vez que un jugador se conecta.
{
    Timer_Armas[playerid] = SetTimerEx("Comprobar_Cheat", 10000, 1, "i", playerid); // Guardamos el timer en la variable para luego destruir el timer ( cuando el jugador sale ) asн no se sigue repitiendo al pedo.
    return 1;
}
Paso 4: Destruiremos el timer cuando el jugador se desconecte y pasamos todas las variables del jugador a 0 ( asн si entra otro no se bugea y queda como que tenga armas. )

pawn Код:
public OnPlayerDisconnect(playerid)
{
    for(new slot = 0; slot < 13; slot++) // Loop para todas los slot de armas
    {
        Armas[playerid][slot] = 0; // Pasamos cada arma 0.
        Municion[playerid][slot] = 0; // Seteamos todas las municiones a 0.
    }
    KillTimer(Timer_Armas[playerid]); // Destruimos el timer del jugador, asн no se sigue repitiendo al pedo.
    return 1;
}
Paso 5: Creamos la funciуn con la que vamos a tener que dar las armas, "EntregarArmas" o la que mбs nos guste. Lo que harб es guardar quй arma se le da al jugador y la municiуn ( si es el mismo arma le agregarнa la municiуn ).

pawn Код:
stock EntregarArma(playerid, arma, municion) // Creamos la funciуn.
{
    new slot = GetWeaponSlot(arma); // Obtenemos el slot del arma.
    if(Armas[playerid][slot] == arma) Municion[playerid][slot] += municion; // Si es el mismo arma le sumamos la municiуn.
    else if(Armas[playerid][slot] != arma) Municion[playerid][slot] = municion; // Si es un arma diferente a la del slot, resetea las balas y le pone las nuevas.
    Armas[playerid][slot] = arma; // Guardamos el arma que le entregaremos al jugador.
    GivePlayerWeapon(playerid, arma, municion); // Le damos el arma.
    return 1;
}
Quote:

Si no tenйs el GetWeaponSlot, te lo dejo acб.

Paso 6: Vamos a comprobar, cada 10 segundos ( o lo que pusieron en el timer ) las armas de cada jugador, si el arma la entregaste vos con EntregarArma, no pasa nada. Si se la puso con cheats enviarб un mensaje a todos los administradores RCON.

pawn Код:
forward Comprobar_Cheat(playerid);
public Comprobar_Cheat(playerid)
{
    if(IsPlayerConnected(playerid)) // Comprobamos que estй conectado ese jugador.
    {
        for (new W = 0; W < 13; W++) // Hacemos un loop para cada slot de las armas.
        {
            GetPlayerWeaponData(playerid, W, temp_arm[W][0], temp_arm[W][1]); // Obtenemos las armas de cada slot.
            if(temp_arm[W][0] != Armas[playerid][W]) // Comparamos el dato que obtuvimos con el que le dimos nosotros, si es diferente quiere decir que ese arma la sacу con algun hack/truco.
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre)); // Obtenemos el nombre del jugador.
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de armas ( /armas ). - **", w_nombre, playerid); // Hacemos el format para el string.
                for(new i = 0; i < GetMaxPlayers(); i++) // Loop para todos los players
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i)) // Comprobamos que sea admin y estй conectado.
                    {
                        SendClientMessage(i, COLOR_RED, w_str); // Le mandamos el mensaje.
                    }
                }
            }
            if(temp_arm[W][1] > Municion[playerid][W]) // Esto es lo mismo, pero comprobamos las municiones del arma ( no explico abajo porque es lo mismo que arriba )
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre));
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de municion ( /armas ). - **", w_nombre, playerid);
                for(new i = 0; i < GetMaxPlayers(); i++)
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i))
                    {
                        SendClientMessage(i, COLOR_RED, w_str);
                    }
                }
            }
        }
    }
    return 1;
}
Paso 7: Haremos un comando para nosotros comprobar manualmente si tiene o no armas ilegales ( hacks ).

pawn Код:
public OnPlayerCommandText(playerid, cmdtext[]) // Callback llamado cada vez que escribe un comando.
{
    if(!strcmp(cmdtext, "/armas", true)) // Comparamos string, cmdtext y /armas.
    {
        if(IsPlayerAdmin(playerid)) // Comprobamos que sea administrador RCON el usuario.
        {
            new tienen = 0; // Definimos una variable para si nadie tiene armas mande un mensaje ( ver mбs abajo )
            for(new i = 0; i < GetMaxPlayers(); i++) // Hacemos un loop para todos los jugadores.
            {
                if(IsPlayerConnected(i)) // Comprobamos que estй conectados.
                {
                    for (new W = 0; W < 13; W++) // Hacemos otro loop para todos los slot de armas ( 13 )
                    {
                        GetPlayerWeaponData(i, W, temp_arm[W][0], temp_arm[W][1]); // Obtenemos los datos del slot.
                        if(temp_arm[W][0] != Armas[i][W] || temp_arm[W][1] > Municion[i][W]) // Si el arma o municion que tiene es diferente al que le dimos, quiere decir que utilizу cheats. Entonces, el cуdigo sigue.
                        {
                            GetPlayerName(i, w_nombre, sizeof(w_nombre)); // Obtenemos el nombre del jugador.
                            format(w_str, sizeof(w_str), "Armas - %s.", w_nombre); // Le damos formato.
                            SendClientMessage(playerid, CREMA_ADMIN, w_str);  Enviamos el mensaje de quienes son las armas.
                            GetWeaponName(temp_arm[W][0], w_nombre,sizeof(w_nombre)); // Obtenemos el nombre del arma.
                            format(w_str, sizeof(w_str), "%s - Municion: %i. ( cheat )", w_nombre,  temp_arm[W][1]); // Hacemos el format con el nombre y municiуn del arma.
                            SendClientMessage(playerid, COLOR_RED, w_str); // Mandamos el mensaje
                            tienen += 1; // Le sumamos 1 a la variable tienen, al final si es 0 quiere decir que nadie tiene armas.
                        }
                        if((temp_arm[W][0] == Armas[i][W] && temp_arm[W][1] == Municion[i][W]) && (Municion[i][W] != 0 && Armas[i][W] != 0)) // Acб es lo mismo que arriba, pero como son IGUALES quiere decir que no son cheat, ya uque se la dimos nosotros. ( Lo que sigue es igual que arriba )
                        {
                            GetPlayerName(i, w_nombre, sizeof(w_nombre));
                            format(w_str, sizeof(w_str), "Armas - %s.", w_nombre);
                            SendClientMessage(playerid, CREMA_ADMIN, w_str);
                            GetWeaponName(temp_arm[W][0], w_nombre,sizeof(w_nombre));
                            format(w_str, sizeof(w_str), "%s - Municion: %i.", w_nombre, temp_arm[W][1]);
                            SendClientMessage(playerid, COLOR_GREEN, w_str);
                            tienen += 1;
                        }
                    }
                }
            }
            if(tienen == 0) // Si tienen es igual a 0 quiere decir que NINGЪN usuario tenнa armas, por lo tanto enviarб el siguiente mensaje.
            {
                SendClientMessage(playerid, CREMA_ADMIN, "* No hay usuarios con armas."); // Envнa el mensaje.
                return 1;
            }
        }
        return 1;
    }
    return 0;
}
Paso 8: Tendremos que remplazar TODOS los GivePlayerWeapon ( o el que usemos ) por el nombre que le dimos a la funciуn mбs arriba. Vйase:

pawn Код:
// Ejemplo.
    if(!strcmp(cmdtext, "/test", true))
    {
        EntregarArma(playerid, 29, 999);
        EntregarArma(playerid, 30, 999);
        EntregarArma(playerid, 31, 999);
        return 1;
    }

їQuй pasa si gasto municiуn? їMe la detecta como cheat? Ya que serнan diferentes...
- No, la ъnica manera ( eficaz ) que se me ocurriу es comprobar que si tiene MБS de la municiуn guardada. Ya que si se pone menos, ademбs de ser medio estъpido, no le sirve de nada.
їCуmo puedo hacer para que los jugadores no vean el arma cheat? Y asн no recibir daсo...
- Mirб йste tutorial sobre la sincronizaciуn.
їEsto me sirve para otro tipo de cheats?
- Si, para lo que se te ocurra. Vida, chaleco, entre otras...

Crйditos cуdigos: [J]ulian.
Crйditos explicaciуn: [J]ulian.
Cуdigo entero: pastebin
Reply
#2

Buen tutorial, mбs uno de reputaciуn.
EDIT: SA-MP Forums no me deja darte mбs reputaciуn por que ya te he dado antes. Lo siento :S
Reply
#3

Nah, no importa. :P. Espero que te sirva, ahн editй una cosita ( la pregunta del final )
Reply
#4

El post estб muy bueno, estб bien explicado, tiene su buena ortografнa (lol)...

Lo ъnico malo es que no entiendo casi nada de lo que estб ahн :P

Gracias por el aporte!
Reply
#5

una pregunta Julian, si la arma se da con cheats, ps la arma se le quitara o solo le envia los mensajes alos admins y ya?, ps yo hize un anticheat de money que hace casi lo mismo pero al sacar el dinero cheat te devuelve al que tenias...
Reply
#6

De lujo el tutorial Juliбn, solo te faltarнa explicarnos un poco eso de que no se vea el arma y no haga daсo, se agradecerнa muchнsimo.

+1 de reputaciуn.

Edit: їCуmo podrнa hacer para que no floodee cuando alguien usa cheat?
Reply
#7

Veto, no no se la quita. Pero no es difнcil de hacer, en ves que envнe el mensaje hace usa esto.

Ruben, para que no flodee hace una nueva variable:

new CheatDetectado[MAX_PLAYERS];

En OnPlayerDisconnect: CheatDetectado[playerid] = 0;

Donde envнa el mensaje cambiб:

pawn Код:
SendClientMessage(playerid, COLOR_RED, w_str); // Mandamos el mensaje
Por:

pawn Код:
if(CheatDetectado[playerid] == 0)
{
    SendClientMessage(playerid, COLOR_RED, w_str); // Mandamos el mensaje
    CheatDetectado[playerid] = 1;
}
Pero no lo recomiendo, ya que si no hay admins lo mandarнa una vez y listo...

Para que no haga daсo tenes que usar OnPlayerUpdate, si haces lo de CheatDetectado podйs poner:

pawn Код:
public OnPlayerUpdate(playerid)
{
    if(CheatDetectado[playerid] != 0) return 0;
    return 1;
}
Si no, mirб en Comprobar_Cheat como lo detecta y usб eso enves de CheatDetectado[playerid].

Saludos!
Reply
#8

muy buen tutorial
Reply
#9

El timer por jugador estб muy al pedo, piensa que con 200 jugadores habrб 200 timers ejecutandose. Es mejor crear uno general en OnFilterScriptInit o OnGameModeInit con un bucle for para todos los jugadores, asн:
pawn Код:
for(new playerid,l=GetMaxPlayers();playerid<l;playerid++){
    if(IsPlayerConnected(playerid)) // Comprobamos que estй conectado ese jugador.
    {
        for (new W = 0; W < 13; W++) // Hacemos un loop para cada slot de las armas.
        {
            GetPlayerWeaponData(playerid, W, temp_arm[W][0], temp_arm[W][1]); // Obtenemos las armas de cada slot.
            if(temp_arm[W][0] != Armas[playerid][W]) // Comparamos el dato que obtuvimos con el que le dimos nosotros, si es diferente quiere decir que ese arma la sacу con algun hack/truco.
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre)); // Obtenemos el nombre del jugador.
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de armas ( /armas ). - **", w_nombre, playerid); // Hacemos el format para el string.
                for(new i = 0; i < GetMaxPlayers(); i++) // Loop para todos los players
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i)) // Comprobamos que sea admin y estй conectado.
                    {
                        SendClientMessage(i, COLOR_RED, w_str); // Le mandamos el mensaje.
                    }
                }
            }
            if(temp_arm[W][1] > Municion[playerid][W]) // Esto es lo mismo, pero comprobamos las municiones del arma ( no explico abajo porque es lo mismo que arriba )
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre));
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de municion ( /armas ). - **", w_nombre, playerid);
                for(new i = 0; i < GetMaxPlayers(); i++)
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i))
                    {
                        SendClientMessage(i, COLOR_RED, w_str);
                    }
                }
            }
        }
    }
    return 1;
}
Reply
#10

Quote:
Originally Posted by GantaIgarashi
Посмотреть сообщение
El timer por jugador estб muy al pedo, piensa que con 200 jugadores habrб 200 timers ejecutandose. Es mejor crear uno general en OnFilterScriptInit o OnGameModeInit con un bucle for para todos los jugadores, asн:
pawn Код:
for(new playerid,l=GetMaxPlayers();playerid<l;playerid++){
    if(IsPlayerConnected(playerid)) // Comprobamos que estй conectado ese jugador.
    {
        for (new W = 0; W < 13; W++) // Hacemos un loop para cada slot de las armas.
        {
            GetPlayerWeaponData(playerid, W, temp_arm[W][0], temp_arm[W][1]); // Obtenemos las armas de cada slot.
            if(temp_arm[W][0] != Armas[playerid][W]) // Comparamos el dato que obtuvimos con el que le dimos nosotros, si es diferente quiere decir que ese arma la sacу con algun hack/truco.
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre)); // Obtenemos el nombre del jugador.
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de armas ( /armas ). - **", w_nombre, playerid); // Hacemos el format para el string.
                for(new i = 0; i < GetMaxPlayers(); i++) // Loop para todos los players
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i)) // Comprobamos que sea admin y estй conectado.
                    {
                        SendClientMessage(i, COLOR_RED, w_str); // Le mandamos el mensaje.
                    }
                }
            }
            if(temp_arm[W][1] > Municion[playerid][W]) // Esto es lo mismo, pero comprobamos las municiones del arma ( no explico abajo porque es lo mismo que arriba )
            {
                GetPlayerName(playerid, w_nombre, sizeof(w_nombre));
                format(w_str, sizeof(w_str), "**[AVISO]: - Revisб a %s(%i), posible cheat de municion ( /armas ). - **", w_nombre, playerid);
                for(new i = 0; i < GetMaxPlayers(); i++)
                {
                    if(IsPlayerAdmin(i) && IsPlayerConnected(i))
                    {
                        SendClientMessage(i, COLOR_RED, w_str);
                    }
                }
            }
        }
    }
    return 1;
}
Concuerdo exactamente con йl.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)