[INC]How to make an Anti Weaponhack using Callback Hooks -
Tigerkiller - 28.05.2012
Hello SA-MP Forum Community.
This is my first Tutorial on 'How to make an Anti Weaponhack using Callback Hooks'.
In this Tutorial you will learn:
- How to hook a Callback
- How to hook a Function
- How to protect your Server for Weapon Cheaters
Now let's get started.
First off all you will need an Texteditor or somethink you can make an .inc File
Now we are going to make our Include works so it cant included twice
pawn Код:
#if defined _AC_included
#endinput
#endif
#define _AC_included
The next part is to make our Forwards so we can Script on it
pawn Код:
// Callback Hooks
forward AC_OnGameModeInit();
forward AC_OnGameModeExit();
forward AC_OnPlayerConnect(playerid);
forward AC_OnPlayerDisconnect(playerid, reason);
forward AC_OnPlayerSpawn(playerid);
forward AC_OnPlayerDeath(playerid, killerid, reason);
forward AC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
//Function Hooks
forward AC_GivePlayerWeapon(playerid,weaponid,ammo);
forward AC_ResetPlayerWeapons(playerid);
forward OnPlayerWeaponHack(hackerid,weapon);
The only think we need is a bool which checks if he has the weapon or not
pawn Код:
new bool:Weapons[MAX_PLAYERS][47];
It's created a bool which holds the weapons which the player can use and return true, if he has the gun or false if he dont have the gun.
The MAX_PLAYERS stands for ALL Players so no-one can use the weapons from other players, the 47 stands for the weapons ( There are only 47 guns which the player can use ).
Now let's Hook all the publics:
pawn Код:
public OnGameModeInit()
{
for(new acplayer = 0; acplayer < MAX_PLAYERS; acplayer++)
{
if(!IsPlayerConnected(acplayer) && IsPlayerNPC(acplayer)) continue;
{
for(new aci=0;aci<47;aci++) Weapons[acplayer][aci] = false;
}
}
return CallLocalFunction("AC_OnGameModeInit","");
}
public OnGameModeExit()
{
for(new acplayer = 0; acplayer < MAX_PLAYERS; acplayer++)
{
if(!IsPlayerConnected(acplayer) && IsPlayerNPC(acplayer)) continue;
{
for(new aci=0;aci<47;aci++) Weapons[acplayer][aci] = false;
}
}
return CallLocalFunction("AC_OnGameModeExit","");
}
public OnPlayerConnect(playerid)
{
for(new aci=0;aci<47;aci++) Weapons[playerid][aci] = false;
return CallLocalFunction("AC_OnPlayerConnect","i",playerid);
}
public OnPlayerDisconnect(playerid, reason)
{
for(new aci=0;aci<47;aci++) Weapons[playerid][aci] = false;
return CallLocalFunction("AC_OnPlayerDisconnect","ii",playerid,reason);
}
public OnPlayerSpawn(playerid)
{
for(new aci=0;aci<47;aci++) Weapons[playerid][aci] = false;
return CallLocalFunction("AC_OnPlayerSpawn","i",playerid);
}
public OnPlayerDeath(playerid, killerid, reason)
{
for(new aci=0;aci<47;aci++) Weapons[playerid][aci] = false;
return CallLocalFunction("AC_OnPlayerDeath","iii",playerid, killerid, reason);
}
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
new ackey = GetPlayerState(playerid); // Get's the current state of the Player
if(newkeys & KEY_FIRE) // if he shoot with the gun
{
if(ackey == PLAYER_STATE_DRIVER || ackey == PLAYER_STATE_ONFOOT) // if he's driver of a vehicle or if he on foot?
{
new acweapon = GetPlayerWeapon(playerid); // Get's the weapon the player is holding
if(Weapons[playerid][acweapon] == false && acweapon !=0 && acweapon !=46) // if he isnt allowed to use this gun, and isnt it weap id 0 (hand or 46 prarshute)
{
OnPlayerWeaponHack(playerid,acweapon); // Call this Callback ( the player is hacking a gun )
return 1;
}
}
}
return CallLocalFunction("AC_OnPlayerKeyStateChange","iii",playerid, newkeys, oldkeys);
}
Ok what did the Codes do ?
public OnGameModeInit() and public OnGameModeExit() resets the gun veriables on ServerRestart
OnPlayerConnect(playerid) and OnPlayerDisconnect(playerid) resets the gun veriables if he leave the server or connect to the server
OnPlayerSpawn resets the gun veriables if he is spawning
OnPlayerDeath is called if the player died and resets the gun veriables too
Now let's start hooking the Publics:
pawn Код:
/*=============== Public Hooking ===============*/
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit AC_OnGameModeInit
/*==============================================*/
#if defined _ALS_OnGameModeExit
#undef OnGameModeExit
#else
#define _ALS_OnGameModeExit
#endif
#define OnGameModeExit AC_OnGameModeExit
/*==============================================*/
#if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect AC_OnPlayerConnect
/*==============================================*/
#if defined _ALS_OnPlayerDisconnect
#undef OnPlayerDisconnect
#else
#define _ALS_OnPlayerDisconnect
#endif
#define OnPlayerDisconnect AC_OnPlayerDisconnect
/*==============================================*/
#if defined _ALS_OnPlayerSpawn
#undef OnPlayerSpawn
#else
#define _ALS_OnPlayerSpawn
#endif
#define OnPlayerSpawn AC_OnPlayerSpawn
/*==============================================*/
#if defined _ALS_OnPlayerDeath
#undef OnPlayerDeath
#else
#define _ALS_OnPlayerDeath
#endif
#define OnPlayerDeath AC_OnPlayerDeath
/*==============================================*/
#if defined _ALS_OnPlayerKeyStateChange
#undef OnPlayerKeyStateChange
#else
#define _ALS_OnPlayerKeyStateChange
#endif
#define OnPlayerKeyStateChange AC_OnPlayerKeyStateChange
it's checks if the callback is defined and undefine them, then it redefine the publics and hook it
What we have forgotten ? Yes!, the GivePlayerWeapon and ResetPlayerWeapon part.
pawn Код:
public AC_ResetPlayerWeapons(playerid)
{
for(new aci=0;aci<47;aci++) Weapons[playerid][aci] = false;
return ResetPlayerWeapons(playerid);
}
public AC_GivePlayerWeapon(playerid,weaponid,ammo)
{
Weapons[playerid][weaponid] = true;
return GivePlayerWeapon(playerid,weaponid,ammo);
}
Now if the Weapons will be resetted using ResetPlayerWeapons the gun veriables will be resseted
If we give a player a weapon using GivePlayerWeapon, the veriable from the weaponid will be activated, so it is true!
pawn Код:
#define GivePlayerWeapon AC_GivePlayerWeapon
#define ResetPlayerWeapons AC_ResetPlayerWeapons
Okay now you can use the OnPlayerWeaponHack(hackerid,weapon) in your GameMode if you have included your .inc file in ur script under samp inc!!
Warning: if you dont put OnPlayerWeaponHack in your Gamemode you'll get errors!
Sorry for my bad English i comes from Germany.
Hope you liked this Tutorial, please Comment and ye, have a nice day!
Re: [INC]How to make an Anti Weaponhack using Callback Hooks -
Kolten - 29.05.2012
Well done,i'm goint to test it.
Re: [INC]How to make an Anti Weaponhack using Callback Hooks -
Jonny5 - 29.05.2012
nice but your ALS code is kinda poor...
check here
https://sampforum.blast.hk/showthread.php?tid=85907
you should make vars and hold if the next function really exist
if so call it,
your way your calling the function every time if it exists or not.
this is closer to what it should look like, (without the weapon code)
pawn Код:
static gAC_HasCB[6];
//--------------OnGameModeInit Hook-------------------
public OnGameModeInit()
{
//your OnGameModeInit pre code here
//function hook checks
gAC_HasCB[0] = funcidx("AC_OnGameModeExit") != -1;
gAC_HasCB[1] = funcidx("AC_OnPlayerConnect") != -1;
gAC_HasCB[2] = funcidx("AC_OnPlayerDeath") != -1;
gAC_HasCB[3] = funcidx("AC_OnPlayerDisconnect") != -1;
gAC_HasCB[4] = funcidx("AC_OnPlayerKeyStateChange") != -1;
gAC_HasCB[5] = funcidx("AC_OnPlayerSpawn") != -1;
if (funcidx("AC_OnGameModeInit") != -1)
{
CallLocalFunction("AC_OnGameModeInit", "");
}
//your OnGameModeInit post code here
return 1;
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit AC_OnGameModeInit
forward AC_OnGameModeInit();
//--------------OnGameModeExit Hook-------------------
public OnGameModeExit()
{
//your OnGameModeExit code here
if (gAC_HasCB[0])
{
return CallLocalFunction("AC_OnGameModeExit", "");
}
return 1;
}
#if defined _ALS_OnGameModeExit
#undef OnGameModeExit
#else
#define _ALS_OnGameModeExit
#endif
#define OnGameModeExit AC_OnGameModeExit
forward AC_OnGameModeExit();
//--------------OnPlayerConnect Hook-------------------
public OnPlayerConnect(playerid)
{
//your OnPlayerConnect code here
if (gAC_HasCB[1])
{
return CallLocalFunction("AC_OnPlayerConnect", "i",playerid);
}
return 1;
}
#if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect AC_OnPlayerConnect
forward AC_OnPlayerConnect(playerid);
//--------------OnPlayerDeath Hook-------------------
public OnPlayerDeath(playerid, killerid, reason)
{
//your OnPlayerDeath code here
if (gAC_HasCB[2])
{
return CallLocalFunction("AC_OnPlayerDeath", "iii",playerid, killerid, reason);
}
return 1;
}
#if defined _ALS_OnPlayerDeath
#undef OnPlayerDeath
#else
#define _ALS_OnPlayerDeath
#endif
#define OnPlayerDeath AC_OnPlayerDeath
forward AC_OnPlayerDeath(playerid, killerid, reason);
//--------------OnPlayerDisconnect Hook-------------------
public OnPlayerDisconnect(playerid, reason)
{
//your OnPlayerDisconnect code here
if (gAC_HasCB[3])
{
return CallLocalFunction("AC_OnPlayerDisconnect", "ii",playerid, reason);
}
return 1;
}
#if defined _ALS_OnPlayerDisconnect
#undef OnPlayerDisconnect
#else
#define _ALS_OnPlayerDisconnect
#endif
#define OnPlayerDisconnect AC_OnPlayerDisconnect
forward AC_OnPlayerDisconnect(playerid, reason);
//--------------OnPlayerKeyStateChange Hook-------------------
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
//your OnPlayerKeyStateChange code here
if (gAC_HasCB[4])
{
return CallLocalFunction("AC_OnPlayerKeyStateChange", "iii",playerid, newkeys, oldkeys);
}
return 1;
}
#if defined _ALS_OnPlayerKeyStateChange
#undef OnPlayerKeyStateChange
#else
#define _ALS_OnPlayerKeyStateChange
#endif
#define OnPlayerKeyStateChange AC_OnPlayerKeyStateChange
forward AC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys);
//--------------OnPlayerSpawn Hook-------------------
public OnPlayerSpawn(playerid)
{
//your OnPlayerSpawn code here
if (gAC_HasCB[5])
{
return CallLocalFunction("AC_OnPlayerSpawn", "i",playerid);
}
return 1;
}
#if defined _ALS_OnPlayerSpawn
#undef OnPlayerSpawn
#else
#define _ALS_OnPlayerSpawn
#endif
#define OnPlayerSpawn AC_OnPlayerSpawn
forward AC_OnPlayerSpawn(playerid);
also redefining native functions you should also be using some sort of ALS
because if some other include try to redefine then it will break the code.
regards, J5
AW: [INC]How to make an Anti Weaponhack using Callback Hooks -
Tigerkiller - 29.05.2012
Hmm thanks for the tip but ye i have never usedthe funcidk
Respuesta: [INC]How to make an Anti Weaponhack using Callback Hooks -
Marricio - 29.05.2012
You should ignore the parachute, fist (weapon id 0) and any other weapon wich is acquired without hacking or giving it script-side.
Re: [INC]How to make an Anti Weaponhack using Callback Hooks -
ReneG - 30.05.2012
Good tutorial, a lot more could be explained. You should go more in-depth on what callback hooking is, be very helpful for those who want to know.
Re: AW: [INC]How to make an Anti Weaponhack using Callback Hooks -
Jonny5 - 30.05.2012
Quote:
Originally Posted by Tigerkiller
Hmm thanks for the tip but ye i have never usedthe funcidk 
|
well i just gave you the hole skeleton of what you need. You could in 5 mins fix this.
if your gonna teach you should try to teach the best practices,
This is why i dont write tutorials. Because I dont know enough on a unique subject
to write about it and teach others.
otherwise everyone who reads this and dont know any better
will think that's the best practice for using ALS code and will release their mods
with the same not so great ALS code.
just think about the
new str[256];
and how many STILL think its okay to use when their str is actually "hi"
I do like this tutorial though!!! so please dont take what i said as rude,
just like to see you improve your als code.
regards,
AW: [INC]How to make an Anti Weaponhack using Callback Hooks -
Tigerkiller - 06.06.2012
Hmm but why hook the function on the same way as for example OnGameModeInit ?
why dont define it ? ex: #define Func My_Func ?
can this causes errors or bugs or somethink else ?
Re: [INC]How to make an Anti Weaponhack using Callback Hooks -
Jonny5 - 06.06.2012
yes, because if someone else hooks it also in their include it will break their code or your code.
this is the hole reason behind ALS hooking method
without als if they try to define this and yours is already done
they will get an error stating a redefinition has taken place.
with als, you can check if someone else has already hooked this function
if so undefine else just define.
hope that made sense,