From 3ef0bcd45079234f50ce62ff317f0918bc347fbc Mon Sep 17 00:00:00 2001 From: Lorenc Date: Wed, 21 Dec 2016 02:27:43 +1100 Subject: [PATCH] pawn - anticheat --- pawno/include/anticheat/airbrake.inc | 114 ++++ pawno/include/anticheat/attachedobjects.inc | 177 +++++++ pawno/include/anticheat/autocbug.inc | 84 +++ pawno/include/anticheat/flying.inc | 89 ++++ pawno/include/anticheat/global.inc | 268 ++++++++++ pawno/include/anticheat/hitpoints.inc | 239 +++++++++ pawno/include/anticheat/hooks.inc | 545 ++++++++++++++++++++ pawno/include/anticheat/main.inc | 44 ++ pawno/include/anticheat/player.inc | 91 ++++ pawno/include/anticheat/proaim.inc | 83 +++ pawno/include/anticheat/remotejack.inc | 56 ++ pawno/include/anticheat/spectate.inc | 59 +++ pawno/include/anticheat/weapon.inc | 210 ++++++++ pawno/pawn.cfg | 1 + 14 files changed, 2060 insertions(+) create mode 100644 pawno/include/anticheat/airbrake.inc create mode 100644 pawno/include/anticheat/attachedobjects.inc create mode 100644 pawno/include/anticheat/autocbug.inc create mode 100644 pawno/include/anticheat/flying.inc create mode 100644 pawno/include/anticheat/global.inc create mode 100644 pawno/include/anticheat/hitpoints.inc create mode 100644 pawno/include/anticheat/hooks.inc create mode 100644 pawno/include/anticheat/main.inc create mode 100644 pawno/include/anticheat/player.inc create mode 100644 pawno/include/anticheat/proaim.inc create mode 100644 pawno/include/anticheat/remotejack.inc create mode 100644 pawno/include/anticheat/spectate.inc create mode 100644 pawno/include/anticheat/weapon.inc create mode 100644 pawno/pawn.cfg diff --git a/pawno/include/anticheat/airbrake.inc b/pawno/include/anticheat/airbrake.inc new file mode 100644 index 0000000..81300da --- /dev/null +++ b/pawno/include/anticheat/airbrake.inc @@ -0,0 +1,114 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com), Emmet_ (no email) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +#include < anticheat\global > +#include < anticheat\player > + +// Forwards + +public AC_ResetABDetected( playerid ); + +// Function Hook (SetPlayerPos) + +stock AC_SetPlayerPos( playerid, Float: x, Float: y, Float: z ) +{ + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + return SetPlayerPos( playerid, x, y, z ); +} + +#if defined _ALS_SetPlayerPos + #undef SetPlayerPos +#else + #define _ALS_SetPlayerPos +#endif +#define SetPlayerPos AC_SetPlayerPos + +// Function Hook (SetPlayerPosFindZ) + +stock AC_SetPlayerPosFindZ(playerid, Float:x, Float:y, Float:z) +{ + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + return SetPlayerPosFindZ( playerid, x, y, z ); +} + +#if defined _ALS_SetPlayerPosFindZ + #undef SetPlayerPosFindZ +#else + #define _ALS_SetPlayerPosFindZ +#endif +#define SetPlayerPosFindZ AC_SetPlayerPosFindZ + +// Functions + +stock bCheckForAirbrake( playerid, iTicks, iState ) +{ + if( iState == 0 || iState == 2 || iState == 3 || iState == 7 || iState == 9 ) + p_abLastTick[ playerid ] = iTicks + 1000; + + else if( !IsPlayerInAnyVehicle( playerid ) && GetPlayerSurfingVehicleID( playerid ) == INVALID_VEHICLE_ID && GetPlayerSurfingObjectID( playerid ) == INVALID_VEHICLE_ID ) // && !IsPlayerNPC( playerid ) + { + new + Float: iPacketLoss = NetStats_PacketLossPercent( playerid ); + + if( iTicks > p_abLastTick[ playerid ] && iPacketLoss < 0.8 ) + { + static + Float: x, Float: y, Float: z, + Float: distance + ; + + GetPlayerPos( playerid, x, y, z ); + + if( floatabs( p_abLastPosition[ playerid ] [ 2 ] - z ) < 1.0 ) + { + distance = GetPlayerDistanceFromPoint( playerid, p_abLastPosition[ playerid ] [ 0 ], p_abLastPosition[ playerid ] [ 1 ], p_abLastPosition[ playerid ] [ 2 ] ); + if( floatabs( distance ) >= 75.0 && ( floatabs( p_abLastPosition[ playerid ] [ 1 ] - y ) >= 50.0 || floatabs( p_abLastPosition[ playerid ] [ 0 ] - x ) >= 50.0 ) ) + { + if( ++p_abDetected{ playerid } >= 3 ) + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_AIRBRAKE ); + + if( p_abResetTimer[ playerid ] == -1 ) + p_abResetTimer[ playerid ] = SetTimerEx( "AC_ResetABDetected", 60000, false, "d", playerid ); + } + } + p_abLastTick[ playerid ] = iTicks + 1000; + } + + if( iTicks > p_abPosTick[ playerid ] ) + { + p_abPosTick[ playerid ] = iTicks + 1000; + GetPlayerPos( playerid, p_abLastPosition[ playerid ] [ 0 ], p_abLastPosition[ playerid ] [ 1 ], p_abLastPosition[ playerid ] [ 2 ] ); + } + } + return 1; +} + +public AC_ResetABDetected( playerid ) +{ + p_abDetected{ playerid } = 0; + p_abResetTimer[ playerid ] = -1; +} diff --git a/pawno/include/anticheat/attachedobjects.inc b/pawno/include/anticheat/attachedobjects.inc new file mode 100644 index 0000000..23100d2 --- /dev/null +++ b/pawno/include/anticheat/attachedobjects.inc @@ -0,0 +1,177 @@ +/* + * + * + */ + +#include < a_samp > + +enum E_ATTACHED_OBJECTS +{ + E_ENABLED, E_MODEL, E_BONE, + Float: E_X, Float: E_Y, Float: E_Z, + Float: E_RX, Float: E_RY, Float: E_RZ, + Float: E_SX, Float: E_SY, Float: E_SZ, + E_COLOR_1, E_COLOR_2 +}; + +new + g_aofix_AttachedPlayerData[ MAX_PLAYERS ] [ 10 ] [ E_ATTACHED_OBJECTS ] +; + +// Function Hook (GivePlayerWeapon) +stock AOFX_SetPlayerAttachedObject( playerid, index, modelid, bone, Float: fOffsetX = 0.0, Float: fOffsetY = 0.0, Float: fOffsetZ = 0.0, Float: fRotX = 0.0, Float: fRotY = 0.0, Float: fRotZ = 0.0, Float: fScaleX = 1.0, Float: fScaleY = 1.0, Float: fScaleZ = 1.0, materialcolor1 = 0, materialcolor2 = 0 ) +{ + if( 0 < index < 9 ) + { + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_ENABLED ] = true; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_MODEL ] = modelid; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_BONE ] = bone; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_COLOR_1 ] = materialcolor1; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_COLOR_2 ] = materialcolor2; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_X ] = fOffsetX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_Y ] = fOffsetY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_Z ] = fOffsetZ; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RX ] = fRotX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RY ] = fRotY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RZ ] = fRotZ; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SX ] = fScaleX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SY ] = fScaleY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SZ ] = fScaleZ; + } + return SetPlayerAttachedObject( playerid, index, modelid, bone, Float: fOffsetX = 0.0, Float: fOffsetY = 0.0, Float: fOffsetZ = 0.0, Float: fRotX = 0.0, Float: fRotY = 0.0, Float: fRotZ = 0.0, Float: fScaleX = 1.0, Float: fScaleY = 1.0, Float: fScaleZ = 1.0, materialcolor1 = 0, materialcolor2 = 0 ); +} + +#if defined _ALS_SetPlayerAttachedObject + #undef SetPlayerAttachedObject +#else + #define _ALS_SetPlayerAttachedObject +#endif +#define SetPlayerAttachedObject AOFX_SetPlayerAttachedObject + +// Function Hook (ResetPlayerWeapons) + +stock AC_IsPlayerAttachedObjectSlotUsed( playerid, index ) +{ + if( 0 < index < 9 && g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_MODEL ] != INVALID_OBJECT_ID ) + return true; + + return RemovePlayerAttachedObject( playerid, index ); +} + +#if defined _ALS_IsPlayerAttachedObjectSlotUsed + #undef IsPlayerAttachedObjectSlotUsed +#else + #define _ALS_IsPlayerAttachedObjectSlotUsed +#endif +#define IsPlayerAttachedObjectSlotUsed AC_IsPlayerAttachedObjectSlotUsed + +// Function Hook (ResetPlayerWeapons) + +stock AC_RemovePlayerAttachedObject( playerid, index ) +{ + if( 0 < index < 9 ) + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_MODEL ] = INVALID_OBJECT_ID; + + return RemovePlayerAttachedObject( playerid, index ); +} + +#if defined _ALS_RemovePlayerAttachedObject + #undef RemovePlayerAttachedObject +#else + #define _ALS_RemovePlayerAttachedObject +#endif +#define RemovePlayerAttachedObject AC_RemovePlayerAttachedObject + +// Callback Hook (OnPlayerEditAttachedObject) + +public OnPlayerEditAttachedObject( playerid, response, index, modelid, boneid, Float: fOffsetX, Float: fOffsetY, Float: fOffsetZ, Float: fRotX, Float: fRotY, Float: fRotZ, Float: fScaleX, Float: fScaleY, Float: fScaleZ ) +{ + // If the attached object was saved, update some variables. + if( response && ( 0 < index < 9 ) ) { + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_ENABLED ] = true; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_MODEL ] = modelid; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_BONE ] = boneid; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_X ] = fOffsetX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_Y ] = fOffsetY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_Z ] = fOffsetZ; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RX ] = fRotX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RY ] = fRotY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_RZ ] = fRotZ; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SX ] = fScaleX; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SY ] = fScaleY; + g_aofix_AttachedPlayerData[ playerid ] [ index ] [ E_SZ ] = fScaleZ; + } + + #if defined AOFX_OnPlayerEditAttachedObject + return AOFX_OnPlayerEditAttachedObject( playerid, response, index, modelid, boneid, Float: fOffsetX, Float: fOffsetY, Float: fOffsetZ, Float: fRotX, Float: fRotY, Float: fRotZ, Float: fScaleX, Float: fScaleY, Float: fScaleZ ); + #else + return 1; + #endif +} + +#if defined AOFX_OnPlayerEditAttachedObject + forward AOFX_OnPlayerEditAttachedObject( playerid, response, index, modelid, boneid, Float: fOffsetX, Float: fOffsetY, Float: fOffsetZ, Float: fRotX, Float: fRotY, Float: fRotZ, Float: fScaleX, Float: fScaleY, Float: fScaleZ ); +#endif +#if defined _ALS_OnPlayerEditAttachedObject + #undef OnPlayerEditAttachedObject +#else + #define _ALS_OnPlayerEditAttachedObject +#endif +#define OnPlayerEditAttachedObject AOFX_OnPlayerEditAttachedObject + +// Callback Hook (OnPlayerKeyStateChange) + +public OnPlayerKeyStateChange( playerid, newkeys, oldkeys ) { + new + weaponid = GetPlayerWeapon( playerid ); + + if( weaponid == WEAPON_SNIPER ) { + // Pressed key + if( ( newkeys & 0x80 ) == 0x80 ) { + TogglePlayerAttachedObjects( playerid, false ); + } + // Released aim key + else if( ( ( newkeys & 0x80 ) != 0x80 ) && ( ( oldkeys & 0x80 ) == 0x80 ) ) { + TogglePlayerAttachedObjects( playerid, true ); + } + } + + #if defined AOFX_OnPlayerKeyStateChange + return AOFX_OnPlayerKeyStateChange( playerid, newkeys, oldkeys ); + #else + return 1; + #endif +} + +#if defined AOFX_OnPlayerKeyStateChange + forward AOFX_OnPlayerKeyStateChange( playerid, newkeys, oldkeys ); +#endif +#if defined _ALS_OnPlayerKeyStateChange + #undef OnPlayerKeyStateChange +#else + #define _ALS_OnPlayerKeyStateChange +#endif +#define OnPlayerKeyStateChange AOFX_OnPlayerKeyStateChange + +// Function (TogglePlayerAttachedObjects) + +stock TogglePlayerAttachedObjects( playerid, bool: show = true ) { + for( new i = 0, modelid; i < sizeof( g_aofix_AttachedPlayerData[ ] ); i++ ) { + if( show ) { + if( g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_MODEL ] != INVALID_OBJECT_ID ) { + SetPlayerAttachedObject( playerid, i, g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_MODEL ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_BONE ], + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_X ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_Y ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_Z ], + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_RX ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_RY ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_RZ ], + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_SX ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_SY ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_SZ ], + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_COLOR_1 ], g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_COLOR_2 ] + ); + } + } else { + if( ( modelid = g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_MODEL ] ) != INVALID_OBJECT_ID ) { + RemovePlayerAttachedObject( playerid, i ); + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_ENABLED ] = false; + g_aofix_AttachedPlayerData[ playerid ] [ i ] [ E_MODEL ] = modelid; // Gets reset to INVALID_OBJECT_ID otherwise + } + } + } +} \ No newline at end of file diff --git a/pawno/include/anticheat/autocbug.inc b/pawno/include/anticheat/autocbug.inc new file mode 100644 index 0000000..6b7e064 --- /dev/null +++ b/pawno/include/anticheat/autocbug.inc @@ -0,0 +1,84 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < anticheat\global > +#include < anticheat\player > + +// Definitions (Global) + +#define AUTOCBUG_TICKS_DEAGLE ( 500 ) // prev 600 +#define AUTOCBUG_TICKS_SHOTGUN ( 850 ) +#define AUTOCBUG_TICKS_COUNTRY ( 750 ) +#define AUTOCBUG_TICKS_SNIPER ( 750 ) + +// Functions (Player) + +stock vAutoCbugKeyState( playerid, newkeys, oldkeys ) +{ + if( !p_cbugKeyTicks[ playerid ] ) + p_cbugKeyTicks[ playerid ] = GetTickCount( ), p_cbugWarns{ playerid } = 0; + + if( ( ( ( newkeys & ( KEY_CROUCH ) ) == ( KEY_CROUCH ) ) || ( ( oldkeys & ( KEY_CROUCH ) ) == ( KEY_CROUCH ) ) ) ) + p_cbugKeyTicks[ playerid ] = GetTickCount( ), p_cbugWarns{ playerid } = 0; +} + +stock vCheckForAutoCbug( playerid, weaponid ) +{ + // Anti-Rapid Fire + if( !p_cbugFireTicks[ playerid ] ) p_cbugFireTicks[ playerid ] = GetTickCount( ); + else + { + new + iTicks = GetTickCount( ), + iInterval = iTicks - p_cbugFireTicks[ playerid ], + iKeyInterval = iTicks - p_cbugKeyTicks[ playerid ], + iHardInterval = 1000 + ; + + if( weaponid == WEAPON_DEAGLE || weaponid == WEAPON_SHOTGUN || weaponid == WEAPON_RIFLE || weaponid == WEAPON_SNIPER ) + { + new + iCompare = iKeyInterval - iInterval, + Float: fOwnPacketLoss = NetStats_PacketLossPercent( playerid ) + ; + + switch( weaponid ) + { + case WEAPON_DEAGLE: iHardInterval = AUTOCBUG_TICKS_DEAGLE; + case WEAPON_SHOTGUN: iHardInterval = AUTOCBUG_TICKS_SHOTGUN; + case WEAPON_RIFLE: iHardInterval = AUTOCBUG_TICKS_COUNTRY; + case WEAPON_SNIPER: iHardInterval = AUTOCBUG_TICKS_SNIPER; + } + + if( iInterval < iHardInterval && iCompare > 1500 && fOwnPacketLoss < 0.8 ) { + if( p_cbugWarns{ playerid }++ >= 2 ) { + printf( "[autocbug detect] %d detected (wep %d, interval %d, compare %d, warns %d)", playerid, weaponid, iInterval, iCompare, p_cbugWarns{ playerid }); + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_AUTOCBUG ); + } + } + } + p_cbugFireTicks[ playerid ] = iTicks; + } +} \ No newline at end of file diff --git a/pawno/include/anticheat/flying.inc b/pawno/include/anticheat/flying.inc new file mode 100644 index 0000000..7532131 --- /dev/null +++ b/pawno/include/anticheat/flying.inc @@ -0,0 +1,89 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < anticheat\global > +#include < anticheat\player > + +#define squared(%0) (%0*%0) + +static const Float: aWaterPlaces[ 20 ] [ 4 ] = +{ + { 30.00, 2313.00, -1417.0, 23.000 }, { 15.00, 1280.00, -773.00, 1083.0 }, { 25.00, 2583.00, 2385.00, 15.000 }, { 20.00, 225.000, -1187.0, 74.000 }, + { 50.00, 1973.00, -1198.0, 17.000 }, { 180.0, 1937.00, 1589.00, 9.0000 }, { 55.00, 2142.00, 1285.00, 8.0000 }, { 45.00, 2150.00, 1132.00, 8.0000 }, + { 55.00, 2089.00, 1915.00, 10.000 }, { 32.00, 2531.00, 1567.00, 9.0000 }, { 21.00, 2582.00, 2385.00, 17.000 }, { 33.00, 1768.00, 2853.00, 10.000 }, + { 47.00, -2721.0, -466.00, 4.0000 }, { 210.0, -671.00, -1898.0, 6.0000 }, { 45.00, 1240.00, -2381.0, 9.0000 }, { 50.00, 1969.00, -1200.0, 18.000 }, + { 10.00, 513.000, -1105.0, 79.000 }, { 20.00, 193.000, -1230.0, 77.000 }, { 30.00, 1094.00, -672.00, 113.00 }, { 20.00, 1278.00, -805.00, 87.000 } +}; + +stock vCheckForFlyHacks( playerid, iTicks ) +{ + if( iTicks > p_FlyHacksTick[ playerid ] ) + { + new + pSurfingObject = GetPlayerSurfingObjectID( playerid ), + pSurfingVehicle = GetPlayerSurfingVehicleID( playerid ) + ; + + if( pSurfingVehicle == INVALID_VEHICLE_ID && pSurfingObject == INVALID_OBJECT_ID ) + { + new + iAnimation = GetPlayerAnimationIndex( playerid ); + + if( iAnimation == 1538 || iAnimation == 1539 || iAnimation == 1543 ) + { + if( !ac_IsPlayerInWater( playerid ) ) + { + if( p_FlyHacksWarns{ playerid }++ >= 2 ) + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_FLYHACKS ), p_FlyHacksWarns{ playerid } = 3; + } + else p_FlyHacksWarns{ playerid } = 0; + } + } + + p_FlyHacksTick[ playerid ] = iTicks + 1000; + } +} + +stock ac_IsPlayerInWater( playerid ) +{ + static + Float: X, Float: Y, Float: Z, i; + + if( GetPlayerPos( playerid, X, Y, Z ) ) + { + if( ac_IsPointInArea( X, Y, 2347.080, 521.70, 2372.65, 545.1971 ) || ac_IsPointInArea( X, Y, 2286.61, 521.70, 2301.45, 545.1971 ) ) + return false; // Kar Fix + + if( ac_PointDistance( X, Y, -965.0, 2438.0 ) <= squared( 700.0 ) && Z < 44.0 ) + return true; + + for( i = 0; i < sizeof( aWaterPlaces ); i++ ) + if( ac_PointDistance( X, Y, aWaterPlaces[ i ] [ 1 ], aWaterPlaces[ i ] [ 2 ] ) <= squared( aWaterPlaces[ i ] [ 0 ] ) && Z < aWaterPlaces[ i ] [ 3 ] ) + return true; + + return Z < 1.9 ? !( ac_PointDistance( X, Y, 618.4129, 863.3164 ) < squared( 200.0 ) ) : false; + } + return false; +} \ No newline at end of file diff --git a/pawno/include/anticheat/global.inc b/pawno/include/anticheat/global.inc new file mode 100644 index 0000000..8ca83d7 --- /dev/null +++ b/pawno/include/anticheat/global.inc @@ -0,0 +1,268 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +// Definitions (Global) + +#define AC_MAX_DETECTIONS ( 13 ) +#define AC_DEFAULT_TEAM ( 1337 ) +#define AC_DEBUG ( true ) + + +#if !defined MAX_CLASSES + #define MAX_CLASSES ( 300 ) +#endif + +#if !defined MAX_WEAPONS + #define MAX_WEAPONS ( 55 ) +#endif + +// Variables (Global) + +enum +{ + CHEAT_TYPE_WEAPON, + //CHEAT_TYPE_CARWARP, + //CHEAT_TYPE_MONEY, + //CHEAT_TYPE_PLAYERBUGGER, + //CHEAT_TYPE_PICKUP_SPAM, + CHEAT_TYPE_SPECTATE, + //CHEAT_TYPE_FAKEKILL, + CHEAT_TYPE_REMOTE_JACK, + //CHEAT_TYPE_PING_LIMIT, + CHEAT_TYPE_SPEED_HACK, + //CHEAT_TYPE_JETPACK, + CHEAT_TYPE_HEALTH, + CHEAT_TYPE_ARMOUR, + CHEAT_TYPE_AIRBRAKE, + CHEAT_TYPE_PROAIM, + CHEAT_TYPE_AUTOCBUG, + CHEAT_TYPE_FLYHACKS +}; + +enum E_CLASS_DATA +{ + E_WEAPONS[ 3 ] +}; + +stock + bool: bIsDetectionEnabled [ AC_MAX_DETECTIONS ] = { true, ... }, + + mAvailableSpawns [ MAX_CLASSES ] [ E_CLASS_DATA ], + //g_iWeaponPickup [ MAX_PICKUPS ], + + + s_ValidDamageGiven[] = { + 1, // 0 - Fist + 1, // 1 - Brass knuckles + 1, // 2 - Golf club + 1, // 3 - Nitestick + 0, // 4 - Knife + 1, // 5 - Bat + 1, // 6 - Shovel + 1, // 7 - Pool cue + 1, // 8 - Katana + 1, // 9 - Chainsaw + 1, // 10 - Dildo + 1, // 11 - Dildo 2 + 1, // 12 - Vibrator + 1, // 13 - Vibrator 2 + 1, // 14 - Flowers + 1, // 15 - Cane + 0, // 16 - Grenade + 0, // 17 - Teargas + 0, // 18 - Molotov + 0, // 19 - Vehicle M4 (custom) + 0, // 20 - Vehicle minigun + 0, // 21 + 1, // 22 - Colt 45 + 1, // 23 - Silenced + 1, // 24 - Deagle + 1, // 25 - Shotgun + 1, // 26 - Sawed-off + 1, // 27 - Spas + 1, // 28 - UZI + 1, // 29 - MP5 + 1, // 30 - AK47 + 1, // 31 - M4 + 1, // 32 - Tec9 + 1, // 33 - Cuntgun + 1, // 34 - Sniper + 0, // 35 - Rocket launcher + 0, // 36 - Heatseeker + 0, // 37 - Flamethrower + 1, // 38 - Minigun + 0, // 39 - Satchel + 0, // 40 - Detonator + 1, // 41 - Spraycan + 1, // 42 - Fire extinguisher + 0, // 43 - Camera + 0, // 44 - Night vision + 0, // 45 - Infrared + 1, // 46 - Parachute + 0, // 47 - Fake pistol + 0, // 48 - Pistol whip (custom) + 0, // 49 - Vehicle + 0, // 50 - Helicopter blades + 0, // 51 - Explosion + 0, // 52 - Car park (custom) + 0, // 53 - Drowning + 0 // 54 - Splat + }, + + Float: s_ValidMaxDamage[] = { + 6.6, // 0 - Fist + 6.6, // 1 - Brass knuckles + 6.6, // 2 - Golf club + 6.6, // 3 - Nitestick + 6.7, // 4 - Knife (varies with back stab) + 6.6, // 5 - Bat + 6.6, // 6 - Shovel + 6.6, // 7 - Pool cue + 6.6, // 8 - Katana + 27.1, // 9 - Chainsaw + 6.6, // 10 - Dildo + 6.6, // 11 - Dildo 2 + 6.6, // 12 - Vibrator + 6.6, // 13 - Vibrator 2 + 6.6, // 14 - Flowers + 6.6, // 15 - Cane + 82.5, // 16 - Grenade + 0.0, // 17 - Teargas + 0.1, // 18 - Molotov + 0.0, // 19 - Vehicle M4 (custom) + 0.0, // 20 - Vehicle minigun + 0.0, // 21 + 8.25, // 22 - Colt 45 + 13.2, // 23 - Silenced + 46.2, // 24 - Deagle + 49.5, // 25 - Shotgun + 49.5, // 26 - Sawed-off + 39.6, // 27 - Spas + 6.6, // 28 - UZI + 8.3, // 29 - MP5 + 9.9, // 30 - AK47 + 9.9, // 31 - M4 + 6.6, // 32 - Tec9 + 24.8, // 33 - Cuntgun + 61.9, // 34 - Sniper + 82.5, // 35 - Rocket launcher + 82.5, // 36 - Heatseeker + 0.1, // 37 - Flamethrower + 46.2, // 38 - Minigun + 0.0, // 39 - Satchel (apparently 20, not synced anyway) + 0.0, // 40 - Detonator + 0.4, // 41 - Spraycan + 0.4, // 42 - Fire extinguisher + 0.0, // 43 - Camera + 0.0, // 44 - Night vision + 0.0, // 45 - Infrared + 6.6 // 46 - Parachute + }, + + Float: s_WeaponRange[] = { + 0.0, // 0 - Fist + 0.0, // 1 - Brass knuckles + 0.0, // 2 - Golf club + 0.0, // 3 - Nitestick + 0.0, // 4 - Knife + 0.0, // 5 - Bat + 0.0, // 6 - Shovel + 0.0, // 7 - Pool cue + 0.0, // 8 - Katana + 0.0, // 9 - Chainsaw + 0.0, // 10 - Dildo + 0.0, // 11 - Dildo 2 + 0.0, // 12 - Vibrator + 0.0, // 13 - Vibrator 2 + 0.0, // 14 - Flowers + 0.0, // 15 - Cane + 0.0, // 16 - Grenade + 0.0, // 17 - Teargas + 0.0, // 18 - Molotov + 90.0, // 19 - Vehicle M4 (custom) + 75.0, // 20 - Vehicle minigun (custom) + 0.0, // 21 + 35.0, // 22 - Colt 45 + 35.0, // 23 - Silenced + 35.0, // 24 - Deagle + 40.0, // 25 - Shotgun + 35.0, // 26 - Sawed-off + 40.0, // 27 - Spas + 35.0, // 28 - UZI + 45.0, // 29 - MP5 + 70.0, // 30 - AK47 + 90.0, // 31 - M4 + 35.0, // 32 - Tec9 + 100.0, // 33 - Cuntgun + 320.0, // 34 - Sniper + 0.0, // 35 - Rocket launcher + 0.0, // 36 - Heatseeker + 0.0, // 37 - Flamethrower + 75.0, // 38 - Minigun + 0.0, // 39 - Satchel (apparently 20, not synced anyway) + 0.0, // 40 - Detonator + 0.0, // 41 - Spraycan + 0.0, // 42 - Fire extinguisher + 0.0, // 43 - Camera + 0.0, // 44 - Night vision + 0.0, // 45 - Infrared + 0.0 // 46 - Parachute + }, + + Iterator:classes +; + +// Forwards (Global) + +public OnPlayerCheatDetected( playerid, detection ); + +// Functions (Global) + +stock detectionToString( iDetection ) { + new + szString[ 16 ] = "unknown"; + + switch( iDetection ) { + case CHEAT_TYPE_ARMOUR: szString = "Armour Hacks"; + case CHEAT_TYPE_HEALTH: szString = "Health Hacks"; + case CHEAT_TYPE_WEAPON: szString = "Weapon Hacks"; + case CHEAT_TYPE_SPECTATE: szString = "Spectate Hacks"; + case CHEAT_TYPE_AIRBRAKE: szString = "Airbrake"; + case CHEAT_TYPE_PROAIM: szString = "Silent Aimbot"; + case CHEAT_TYPE_AUTOCBUG: szString = "Auto CBUG"; + case CHEAT_TYPE_FLYHACKS: szString = "Fly Hacks"; + case CHEAT_TYPE_REMOTE_JACK: szString = "Remote Jacking"; + } + + return szString; +} + +stock ac_IsPointInArea( Float: X, Float: Y, Float: minx, Float: maxx, Float: miny, Float: maxy ) + return ( X > minx && X < maxx && Y > miny && Y < maxy ); + +stock Float: ac_PointDistance( Float: X, Float: Y, Float: dstX, Float: dstY ) + return ( ( X - dstX ) * ( X - dstX ) ) + ( ( Y - dstY ) * ( Y - dstY ) ); diff --git a/pawno/include/anticheat/hitpoints.inc b/pawno/include/anticheat/hitpoints.inc new file mode 100644 index 0000000..c89f408 --- /dev/null +++ b/pawno/include/anticheat/hitpoints.inc @@ -0,0 +1,239 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#if !defined AC_HITPOINTS_INCLUDED + #include < a_samp > + + #include < anticheat\global > + #include < anticheat\player > + + // Forwards + public OnPlayerTakePlayerDamage ( playerid, issuerid, &Float: amount, weaponid, bodypart ); + public OnPlayerDeathEx ( playerid, killerid, reason, Float: damage, bodypart ); + + // Function (AC_GetPlayerHealth) + + stock Float: AC_GetPlayerHealth( playerid ) + return p_PlayerHealth[ playerid ] [ E_POINTS ]; + + // Function (AddPlayerHealth) + + stock AC_AddPlayerHealth( playerid, Float:amount ) + { + p_PlayerHealth[ playerid ] [ E_POINTS ] += amount; + p_PlayerHealth[ playerid ] [ E_SYNCED ] = false; + + return SetPlayerHealth( playerid, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + } + + // Function Hook (SetPlayerHealth) + + stock AC_SetPlayerHealth( playerid, Float:amount ) + { + p_PlayerHealth[ playerid ] [ E_POINTS ] = amount; + p_PlayerHealth[ playerid ] [ E_SYNCED ] = false; + + if( amount <= 0.0 && p_acSpawned{ playerid } ) + { + if( ( GetTickCount( ) - p_LastTookDamage[ playerid ] ) > 2500 ) + p_LastDamageIssuer[ playerid ] = INVALID_PLAYER_ID, p_LastWeaponIssuer[ playerid ] = 47; + + p_acSpawned{ playerid } = false; // They're dead! + OnPlayerDeathEx( playerid, p_LastDamageIssuer[ playerid ], p_LastWeaponIssuer[ playerid ], 3.3, 3 ); + } + + return SetPlayerHealth( playerid, amount ); + } + + #if defined _ALS_SetPlayerHealth + #undef SetPlayerHealth + #else + #define _ALS_SetPlayerHealth + #endif + #define SetPlayerHealth AC_SetPlayerHealth + + // Function Hook (SetPlayerArmour) + + stock AC_SetPlayerArmour( playerid, Float:amount ) + { + p_PlayerArmour[ playerid ] [ E_POINTS ] = amount; + p_PlayerArmour[ playerid ] [ E_SYNCED ] = false; + return SetPlayerArmour( playerid, amount ); + } + + #if defined _ALS_SetPlayerArmour + #undef SetPlayerArmour + #else + #define _ALS_SetPlayerArmour + #endif + #define SetPlayerArmour AC_SetPlayerArmour + + // Function Hook (SetPlayerTeam) + + stock AC_SetPlayerTeam( playerid, teamid ) + { + if( teamid != AC_DEFAULT_TEAM ) + printf("[ACWarning] You cannot use SetPlayerTeam as you have hitpoint hack detection enabled (teamid %d, default %d).", teamid, AC_DEFAULT_TEAM ); + + return SetPlayerTeam( playerid, AC_DEFAULT_TEAM ); + } + + #if defined _ALS_SetPlayerTeam + #undef SetPlayerTeam + #else + #define _ALS_SetPlayerArmour + #endif + #define SetPlayerTeam AC_SetPlayerTeam + + // Functions (Player) + stock vCheckForHealthHacks( playerid, iTicks ) + { + new + Float: currentHealth, + Float: currentArmour + ; + GetPlayerHealth( playerid, currentHealth ); + GetPlayerArmour( playerid, currentArmour ); + + // Lag Calculations + new + Float: fHitDamage = p_LastDamageIssued[ playerid ], + Float: fArmourDamage, + Float: fHealthDamage + ; + + if( fHitDamage > currentArmour ) { + fArmourDamage = currentArmour; + fHealthDamage = fHitDamage - currentArmour; + } + else fArmourDamage = fHitDamage; + + // Begin Health Hack Detection + if( iTicks > p_PlayerHealth[ playerid ] [ E_UPDATE_TIME ] ) + { + new currentHealthInt = floatround( currentHealth, floatround_floor ); + new healthShouldBeInt = floatround( p_PlayerHealth[ playerid ] [ E_POINTS ], floatround_floor ); + + if( currentHealthInt == healthShouldBeInt ) + p_PlayerHealth[ playerid ] [ E_SYNCED ] = true; + + if( !p_PlayerHealth[ playerid ] [ E_SYNCED ] ) + { + if( currentHealthInt > healthShouldBeInt ) + { + switch( p_PlayerHealth[ playerid ] [ E_UPDATE_FAIL ]++ ) + { + case 0 .. 9: SetPlayerHealth( playerid, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + case 10: SendClientMessage( playerid, 0xa9c4e4ff, "You have been kicked as you are desynced from the server. Please relog!" ), KickPlayerTimed( playerid ), printf("[health] Player %d was desynced thus kicked.", playerid); + } + } + } + else + { + p_PlayerHealth[ playerid ] [ E_UPDATE_FAIL ] = 0; + + if( healthShouldBeInt > currentHealthInt ) + p_PlayerHealth[ playerid ] [ E_POINTS ] = currentHealth; + + if( currentHealthInt > healthShouldBeInt && currentHealthInt <= 255 && currentHealthInt > 0 ) + SetPlayerHealth( playerid, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + + currentHealthInt = floatround( currentHealth, floatround_floor ); + healthShouldBeInt = floatround( p_PlayerHealth[ playerid ] [ E_POINTS ], floatround_floor ); + + new dmgOne = floatround( currentHealthInt - fHealthDamage, floatround_floor ); + new dmgTwo = floatround( currentHealthInt - fHealthDamage, floatround_ceil ); + + if( !( currentHealthInt == healthShouldBeInt || dmgOne == healthShouldBeInt || dmgTwo == healthShouldBeInt ) ) + { + SetPlayerHealth( playerid, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + //printf("[health][%d] %d seems to health hack (server health: %d and client health: %d, health dmg: %f, armour dmg: %f).", playerid, playerid, healthShouldBeInt, currentHealthInt, fHealthDamage, fArmourDamage ); + } + } + p_PlayerHealth[ playerid ] [ E_UPDATE_TIME ] = iTicks + 1000; + } + + // Begin Armour Hack Detection + if( iTicks > p_PlayerArmour[ playerid ] [ E_UPDATE_TIME ] ) + { + new currentArmourInt = floatround( currentArmour, floatround_floor ); + new ArmourShouldBeInt = floatround( p_PlayerArmour[ playerid ] [ E_POINTS ], floatround_floor ); + + if( currentArmourInt == ArmourShouldBeInt ) + p_PlayerArmour[ playerid ] [ E_SYNCED ] = true; + + if( !p_PlayerArmour[ playerid ] [ E_SYNCED ] ) + { + if( currentArmourInt > ArmourShouldBeInt ) + { + switch( p_PlayerArmour[ playerid ] [ E_UPDATE_FAIL ]++ ) + { + case 0 .. 9: SetPlayerArmour( playerid, p_PlayerArmour[ playerid ] [ E_POINTS ] ); + case 10: SendClientMessage( playerid, 0xa9c4e4ff, "You have been kicked as you are desynced from the server. Please relog!" ), KickPlayerTimed( playerid ), printf("[armour] Player %d was desynced thus kicked.", playerid); + } + } + } + else + { + p_PlayerArmour[ playerid ] [ E_UPDATE_FAIL ] = 0; + + if( ArmourShouldBeInt > currentArmourInt ) + p_PlayerArmour[ playerid ] [ E_POINTS ] = currentArmour; + + if( currentArmourInt > ArmourShouldBeInt && currentArmourInt <= 255 && currentArmourInt > 0 ) + SetPlayerArmour( playerid, p_PlayerArmour[ playerid ] [ E_POINTS ] ); + + currentArmourInt = floatround( currentArmour, floatround_floor ); + ArmourShouldBeInt = floatround( p_PlayerArmour[ playerid ] [ E_POINTS ], floatround_floor ); + + new dmgOne = floatround( currentArmourInt - fArmourDamage, floatround_floor ); + new dmgTwo = floatround( currentArmourInt - fArmourDamage, floatround_ceil ); + + if( !( currentArmourInt == ArmourShouldBeInt || dmgOne == ArmourShouldBeInt || dmgTwo == ArmourShouldBeInt ) ) + { + SetPlayerArmour( playerid, p_PlayerArmour[ playerid ] [ E_POINTS ] ); + //printf("[armour] %d seems to armour hack (server armour: %d and client armour: %d, health dmg: %f, armour dmg: %f).", playerid, ArmourShouldBeInt, currentArmourInt, fHealthDamage, fArmourDamage ); + } + } + p_PlayerArmour[ playerid ] [ E_UPDATE_TIME ] = iTicks + 1000; + } + } + + /* + @function ForcePlayerKill + @description forces a kill on a player + @return void + */ + stock ForcePlayerKill( playerid, killerid, weaponid ) + { + SetPVarInt( playerid, "KillerID", killerid ); + SetPVarInt( playerid, "WeaponID", weaponid ); + SetPVarInt( playerid, "CustomKill", 1 ); + + SetPlayerHealth( playerid, -1 ); + } + + #define AC_HITPOINTS_INCLUDED +#endif diff --git a/pawno/include/anticheat/hooks.inc b/pawno/include/anticheat/hooks.inc new file mode 100644 index 0000000..8bfca59 --- /dev/null +++ b/pawno/include/anticheat/hooks.inc @@ -0,0 +1,545 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#if !defined AC_INCLUDED + #include < a_samp > + + // Function Hook (PutPlayerInVehicle) + + stock AC_PutPlayerInVehicle(playerid, vehicleid, seatid) + { + // Remote Jacking + p_remoteJackData[ playerid ] [ E_LAST_VEH ] = vehicleid; + + // Airbreak + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + return PutPlayerInVehicle(playerid, vehicleid, seatid); + } + + #if defined _ALS_PutPlayerInVehicle + #undef PutPlayerInVehicle + #else + #define _ALS_PutPlayerInVehicle + #endif + #define PutPlayerInVehicle AC_PutPlayerInVehicle + + // Callback Hook (OnPlayerConnect) + + public OnPlayerConnect( playerid ) + { + if ( !IsPlayerNPC( playerid ) ) + { + // Remove Vending Machines + RemoveBuildingForPlayer( playerid, 1302, 0.0, 0.0, 0.0, 6000.0 ); + RemoveBuildingForPlayer( playerid, 1209, 0.0, 0.0, 0.0, 6000.0 ); + RemoveBuildingForPlayer( playerid, 955, 0.0, 0.0, 0.0, 6000.00 ); + RemoveBuildingForPlayer( playerid, 956, 0.0, 0.0, 0.0, 6000.00 ); + RemoveBuildingForPlayer( playerid, 1775, 0.0, 0.0, 0.0, 6000.0 ); + RemoveBuildingForPlayer( playerid, 1776, 0.0, 0.0, 0.0, 6000.0 ); + RemoveBuildingForPlayer( playerid, 1977, 0.0, 0.0, 0.0, 6000.0 ); + + // Reset Variables + p_PlayerHealth [ playerid ] [ E_UPDATE_FAIL ] = 0; + p_PlayerArmour [ playerid ] [ E_UPDATE_FAIL ] = 0; + p_acSpawned { playerid } = false; + //p_SpectatePermission { playerid } = false; + p_abDetected { playerid } = 0; + p_abResetTimer [ playerid ] = -1; + p_abLastTick [ playerid ] = GetTickCount( ) + 3000; + p_FlyHacksWarns { playerid } = 3; + p_cbugWarns { playerid } = 0; + + for ( new i = 0; i < MAX_WEAPONS; i++ ) + p_PlayerHasWeapon [ playerid ] { i } = false; + } + + #if defined SAMPAC_OnPlayerConnect + return SAMPAC_OnPlayerConnect( playerid ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerConnect + forward SAMPAC_OnPlayerConnect( playerid ); + #endif + #if defined _ALS_OnPlayerConnect + #undef OnPlayerConnect + #else + #define _ALS_OnPlayerConnect + #endif + #define OnPlayerConnect SAMPAC_OnPlayerConnect + + // Callback Hook (OnPlayerSpawn) + + public OnPlayerSpawn( playerid ) + { + // General + p_acSpawned{ playerid } = true; + + // Health/Armour Hack + p_PlayerHealth[ playerid ] [ E_UPDATE_FAIL ] = 0; + p_PlayerHealth[ playerid ] [ E_POINTS ] = 100.0; + + p_PlayerArmour[ playerid ] [ E_UPDATE_FAIL ] = 0; + p_PlayerArmour[ playerid ] [ E_POINTS ] = 0.0; + + SetPlayerTeam( playerid, AC_DEFAULT_TEAM ); // Set everyone the same team + + // Weapon Hack + for ( new i = 0; i < 3; i++ ) + { + new + weaponid = mAvailableSpawns[ p_SelectedClassID[ playerid ] ] [ E_WEAPONS ] [ i ]; + + if( weaponid != -1 && weaponid < MAX_WEAPONS ) + p_PlayerHasWeapon[ playerid ] { weaponid } = true; + } + + // Airbrake + p_abDetected{ playerid } = 0; + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + + #if defined SAMPAC_OnPlayerSpawn + return SAMPAC_OnPlayerSpawn( playerid ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerSpawn + forward SAMPAC_OnPlayerSpawn( playerid ); + #endif + #if defined _ALS_OnPlayerSpawn + #undef OnPlayerSpawn + #else + #define _ALS_OnPlayerSpawn + #endif + #define OnPlayerSpawn SAMPAC_OnPlayerSpawn + + // Callback Hook (OnPlayerDeath) + + public OnPlayerDeath(playerid, killerid, reason) + { + if ( !IsPlayerNPC( playerid ) ) + { + // Health/Armour Hack + if( GetPVarInt( playerid, "CustomKill" ) ) + { + new + customKiller = GetPVarInt( playerid, "KillerID" ); + + OnPlayerDeathEx( playerid, customKiller != playerid ? customKiller : INVALID_PLAYER_ID, GetPVarInt( playerid, "WeaponID" ), 3.3, 3 ); + + DeletePVar( playerid, "KillerID" ); + DeletePVar( playerid, "WeaponID" ); + DeletePVar( playerid, "CustomKill" ); + } + + else if( GetPlayerVehicleID( playerid ) && ac_IsPlayerSpawned( playerid ) ) // Died in Vehicle + { + if( ( GetTickCount( ) - p_LastTookDamage[ playerid ] ) > 2500 ) + p_LastDamageIssuer[ playerid ] = INVALID_PLAYER_ID, p_LastWeaponIssuer[ playerid ] = 51; + + p_acSpawned{ playerid } = false; // They're dead! + OnPlayerDeathEx( playerid, p_LastDamageIssuer[ playerid ], p_LastWeaponIssuer[ playerid ], 3.3, 3 ); + } + + // General + p_acSpawned{ playerid } = false; + + // Airbrake + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + } + + #if defined SAMPAC_OnPlayerDeath + return SAMPAC_OnPlayerDeath(playerid, killerid, reason); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerDeath + forward SAMPAC_OnPlayerDeath(playerid, killerid, reason); + #endif + #if defined _ALS_OnPlayerDeath + #undef OnPlayerDeath + #else + #define _ALS_OnPlayerDeath + #endif + #define OnPlayerDeath SAMPAC_OnPlayerDeath + + // Callback Hook (OnPlayerTakeDamage) + + public OnPlayerTakeDamage( playerid, issuerid, Float: amount, weaponid, bodypart ) + { + new + is_npc = IsPlayerNPC( issuerid ); + + p_LastTookDamage[ playerid ] = GetTickCount( ); + p_LastDamageIssuer[ playerid ] = issuerid; + p_LastWeaponIssuer[ playerid ] = weaponid; + p_LastDamageIssued[ playerid ] = amount; + + //if( !( issuerid != INVALID_PLAYER_ID && IsPlayerInAnyVehicle( issuerid ) && GetPlayerVehicleSeat( issuerid ) == 0 && ( weaponid == WEAPON_M4 || weaponid == WEAPON_MINIGUN ) ) ) + // return 0; + + // Allow hunter damage/sparrow + if( !( issuerid != INVALID_PLAYER_ID && IsPlayerInAnyVehicle( issuerid ) && GetPlayerVehicleSeat( issuerid ) == 0 && ( weaponid == WEAPON_M4 || weaponid == WEAPON_MINIGUN ) ) && !is_npc ) + { + // Ignore unreliable and invalid damage + if( weaponid < 0 || weaponid >= sizeof( s_ValidDamageGiven ) || s_ValidDamageGiven[ weaponid ] ) + return 0; + } + + if( ac_IsPlayerSpawned( playerid ) ) + { + if( issuerid != INVALID_PLAYER_ID && ! is_npc ) + { + if( OnPlayerTakePlayerDamage( playerid, issuerid, amount, weaponid, bodypart ) ) + { + new Float: tmp, Float: tmp_amount = amount; + + if( p_PlayerArmour[ playerid ] [ E_POINTS ] ) + { + if( ( tmp = p_PlayerArmour[ playerid ] [ E_POINTS ] - tmp_amount ) < 0.0 ) { + tmp_amount -= p_PlayerArmour[ playerid ] [ E_POINTS ]; + p_PlayerArmour[ playerid ] [ E_POINTS ] = 0.0; + } else { + p_PlayerArmour[ playerid ] [ E_POINTS ] = tmp; + tmp_amount = 0.0; + } + } + + if( ( p_PlayerHealth[ playerid ] [ E_POINTS ] -= tmp_amount ) < 0.0 ) { + p_acSpawned{ playerid } = false; // They're dead! + OnPlayerDeathEx( playerid, issuerid, weaponid, amount, bodypart ); + } + + SetPlayerArmour( playerid, p_PlayerArmour[ playerid ] [ E_POINTS ] ); + SetPlayerHealth( playerid, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + } + } + else + { + new Float: tmp, Float: tmp_amount = amount; + + if( !( weaponid == 53 || weaponid == 54 || weaponid == 50 ) && p_PlayerArmour[ playerid ] [ E_POINTS ] ) + { + if( ( tmp = p_PlayerArmour[ playerid ] [ E_POINTS ] - tmp_amount ) < 0.0 ) { + tmp_amount -= p_PlayerArmour[ playerid ] [ E_POINTS ]; + p_PlayerArmour[ playerid ] [ E_POINTS ] = 0.0; + } else { + p_PlayerArmour[ playerid ] [ E_POINTS ] = tmp; + tmp_amount = 0.0; + } + } + + //printf("OnPlayerTakeDamage( %d, %d, %f, %d, %d ) %f", playerid, issuerid, amount, weaponid, bodypart, p_PlayerHealth[ playerid ] [ E_POINTS ] ); + if( ( p_PlayerHealth[ playerid ] [ E_POINTS ] -= tmp_amount ) <= ( weaponid == 37 ? 0.99999 : 0.0 ) ) { + p_acSpawned{ playerid } = false; // They're dead! + if ( weaponid == 37 ) SetPlayerHealth( playerid, -1 ); + OnPlayerDeathEx( playerid, issuerid, weaponid, amount, bodypart ); + } + } + } + + #if defined SAMPAC_OnPlayerTakeDamage + return SAMPAC_OnPlayerTakeDamage(playerid, issuerid, amount, weaponid, bodypart); + #else + return 0; + #endif + } + + #if defined SAMPAC_OnPlayerTakeDamage + forward SAMPAC_OnPlayerTakeDamage(playerid, issuerid, Float: amount, weaponid, bodypart); + #endif + #if defined _ALS_OnPlayerTakeDamage + #undef OnPlayerTakeDamage + #else + #define _ALS_OnPlayerTakeDamage + #endif + #define OnPlayerTakeDamage SAMPAC_OnPlayerTakeDamage + + + // Callback Hook (OnPlayerGiveDamage) + + public OnPlayerGiveDamage( playerid, damagedid, Float: amount, weaponid, bodypart ) + { + // Ignore unreliable and invalid damage + if ( weaponid < 0 || weaponid >= sizeof( s_ValidDamageGiven ) || !s_ValidDamageGiven[ weaponid ] ) + return 0; + + if( weaponid < 0 || weaponid >= sizeof( s_ValidMaxDamage ) || amount > s_ValidMaxDamage[ weaponid ] + 2.0 ) // 2.0 safety margin + return 0; + + if( damagedid == INVALID_PLAYER_ID ) + return 0; + + if( IsPlayerInAnyVehicle( playerid ) && GetPlayerVehicleSeat( playerid ) == 0 && ( weaponid == WEAPON_M4 || weaponid == WEAPON_MINIGUN ) ) + return 0; + + if ( !IsPlayerNPC( damagedid ) ) + { + if( !ac_IsPlayerSpawned( damagedid ) ) + return 0; + + if( ( !IsPlayerStreamedIn( playerid, damagedid ) && !( GetTickCount( ) - p_acUpdateTime[ damagedid ] >= 2595 ) ) || !IsPlayerStreamedIn( damagedid, playerid ) ) + return 0; + + //printf("OnPlayerGiveDamage( %d, %d, %f, %d, %d )", playerid, damagedid, amount, weaponid, bodypart ); + //p_LastTookDamage[ damagedid ] = GetTickCount( ); + //p_LastDamageIssuer[ damagedid ] = playerid; + //p_LastWeaponIssuer[ damagedid ] = weaponid; + //p_LastDamageIssued[ damagedid ] = amount; + + if( OnPlayerTakePlayerDamage( damagedid, playerid, amount, weaponid, bodypart ) ) + { + new + Float: tmp, + Float: distance = GetDistanceBetweenPlayers( playerid, damagedid ), // Calc distance between players + Float: tmp_amount = amount // this amount is extremely unreliable + ; + //printf("Proposed dmg %f kinda %f (min: %f, max: %f, rng: %f)", amount, tmp_amount, GetWeaponMinRange( weaponid ), GetWeaponMaxRange( weaponid ), distance ); + + if( distance > s_WeaponRange[ weaponid ] + 2.0 ) + return 0; //printf(" INVALID RANGE %f (MAX %f)", distance, GetWeaponMaxRange( weaponid ) ), 0; + + if( p_PlayerArmour[ damagedid ] [ E_POINTS ] ) + { + if( ( tmp = p_PlayerArmour[ damagedid ] [ E_POINTS ] - tmp_amount ) < 0.0 ) { + tmp_amount -= p_PlayerArmour[ damagedid ] [ E_POINTS ]; + p_PlayerArmour[ damagedid ] [ E_POINTS ] = 0.0; + } else { + p_PlayerArmour[ damagedid ] [ E_POINTS ] = tmp; + tmp_amount = 0.0; + } + } + + if( ( p_PlayerHealth[ damagedid ] [ E_POINTS ] -= tmp_amount ) < 0.0 ) { + p_acSpawned{ damagedid } = false; // They're dead! + OnPlayerDeathEx( damagedid, playerid, weaponid, amount, bodypart ); + } + + SetPlayerArmour( damagedid, p_PlayerArmour[ damagedid ] [ E_POINTS ] ); + SetPlayerHealth( damagedid, p_PlayerHealth[ damagedid ] [ E_POINTS ] ); + } + } + + #if defined SAMPAC_OnPlayerGiveDamage + return SAMPAC_OnPlayerGiveDamage( playerid, damagedid, Float: amount, weaponid, bodypart ); + #else + return 0; + #endif + } + + #if defined SAMPAC_OnPlayerGiveDamage + forward SAMPAC_OnPlayerGiveDamage( playerid, damagedid, Float: amount, weaponid, bodypart ); + #endif + #if defined _ALS_OnPlayerGiveDamage + #undef OnPlayerGiveDamage + #else + #define _ALS_OnPlayerGiveDamage + #endif + #define OnPlayerGiveDamage SAMPAC_OnPlayerGiveDamage + + // Hook (OnPlayerStateChange) + + public OnPlayerStateChange( playerid, newstate, oldstate ) + { + if ( !IsPlayerNPC( playerid ) ) + { + // Spectate Hacks + /*if( oldstate == PLAYER_STATE_SPECTATING && newstate != PLAYER_STATE_SPECTATING ) { + p_PlayerSpectateUpdateTime[ playerid ] = GetTickCount( ) + 1250; + p_SpectatePermission{ playerid } = false; // Bugs otherwise dunno why + }*/ + + // Weapon Hacks - credits to wups + if( newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER ) + { + switch ( GetVehicleModel( GetPlayerVehicleID( playerid ) ) ) + { + case 457: + p_PlayerHasWeapon[ playerid ] { 2 } = true; + + case 592, 577, 511, 512, 520, 593, 553, 476, 519, 460, 513, 548, 425, 417, 487, 488, 497, 563, 447, 469, 539: + p_PlayerHasWeapon[ playerid ] { 46 } = true; + + case 596, 597, 598, 599: + p_PlayerHasWeapon[ playerid ] { 25 } = true; + } + } + + // Airbrake + p_abLastTick[ playerid ] = GetTickCount( ) + 3000; + } + + #if defined SAMPAC_OnPlayerStateChange + return SAMPAC_OnPlayerStateChange( playerid, newstate, oldstate ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerStateChange + forward SAMPAC_OnPlayerStateChange( playerid, newstate, oldstate ); + #endif + #if defined _ALS_OnPlayerStateChange + #undef OnPlayerStateChange + #else + #define _ALS_OnPlayerStateChange + #endif + #define OnPlayerStateChange SAMPAC_OnPlayerStateChange + + // Hook (OnPlayerUpdate) + + public OnPlayerUpdate( playerid ) + { + if( !ac_IsPlayerSpawned( playerid ) ) + return 0; // Not Spawned, No SYNC! + + if( !IsPlayerNPC( playerid ) ) + { + new + iState = GetPlayerState( playerid ); + + p_acUpdateTime[ playerid ] = GetTickCount( ); + //bCheckForSpectatingHacks ( playerid, iState, iTicks ); + + if( iState != PLAYER_STATE_SPECTATING ) + { + bCheckForAirbrake ( playerid, p_acUpdateTime[ playerid ], iState ); + vCheckForHealthHacks ( playerid, p_acUpdateTime[ playerid ] ); + vCheckForFlyHacks ( playerid, p_acUpdateTime[ playerid ] ); + //vWeaponHackCheck ( playerid, p_acUpdateTime[ playerid ] ); + bCheckPlayerRemoteJacking ( playerid ); + } + } + + #if defined SAMPAC_OnPlayerUpdate + return SAMPAC_OnPlayerUpdate( playerid ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerUpdate + forward SAMPAC_OnPlayerUpdate( playerid ); + #endif + #if defined _ALS_OnPlayerUpdate + #undef OnPlayerUpdate + #else + #define _ALS_OnPlayerUpdate + #endif + #define OnPlayerUpdate SAMPAC_OnPlayerUpdate + + // Hook (OnPlayerRequestClass) + + public OnPlayerRequestClass( playerid, classid ) + { + // General + p_acSpawned{ playerid } = false; + p_SelectedClassID[ playerid ] = classid; + + #if defined SAMPAC_OnPlayerRequestClass + return SAMPAC_OnPlayerRequestClass( playerid, classid ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerRequestClass + forward SAMPAC_OnPlayerRequestClass( playerid, classid ); + #endif + #if defined _ALS_OnPlayerRequestClass + #undef OnPlayerRequestClass + #else + #define _ALS_OnPlayerRequestClass + #endif + #define OnPlayerRequestClass SAMPAC_OnPlayerRequestClass + + // Callback Hook (OnPlayerKeyStateChange) + + public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) + { + if( !IsPlayerNPC( playerid ) ) + { + vWeaponHackCheck ( playerid, newkeys ); + vAutoCbugKeyState ( playerid, newkeys, oldkeys ); + } + + + #if defined SAMPAC_OnPlayerKeyStateChange + return SAMPAC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerKeyStateChange + forward SAMPAC_OnPlayerKeyStateChange(playerid, newkeys, oldkeys); + #endif + #if defined _ALS_OnPlayerKeyStateChange + #undef OnPlayerKeyStateChange + #else + #define _ALS_OnPlayerKeyStateChange + #endif + #define OnPlayerKeyStateChange SAMPAC_OnPlayerKeyStateChange + + // Callback Hook (OnPlayerWeaponShot) + + public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ) + { + //printf("OnPlayerWeaponShot(%d, %d, %d, %d, %f, %f, %f)",playerid, weaponid, hittype, hitid, fX, fY, fZ); + + new + iState = GetPlayerState( playerid ); + + if( iState == PLAYER_STATE_WASTED || !ac_IsPlayerSpawned( playerid ) ) + return 0; // Why bother, he's dead! + + vCheckForAutoCbug( playerid, weaponid ); + vCheckForSilentAimbot( playerid, hittype, hitid ); + + #if defined SAMPAC_OnPlayerWeaponShot + return SAMPAC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, fX, fY, fZ); + #else + return 1; + #endif + } + + #if defined SAMPAC_OnPlayerWeaponShot + forward SAMPAC_OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ); + #endif + #if defined _ALS_OnPlayerWeaponShot + #undef OnPlayerWeaponShot + #else + #define _ALS_OnPlayerWeaponShot + #endif + #define OnPlayerWeaponShot SAMPAC_OnPlayerWeaponShot + + #define AC_INCLUDED +#endif diff --git a/pawno/include/anticheat/main.inc b/pawno/include/anticheat/main.inc new file mode 100644 index 0000000..0c70592 --- /dev/null +++ b/pawno/include/anticheat/main.inc @@ -0,0 +1,44 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > +#include < foreach > + +#if !defined AC_INCLUDED + #include < anticheat\global > + #include < anticheat\player > + + #include < anticheat\hitpoints > + #include < anticheat\weapon > + //#include < anticheat\spectate > + #include < anticheat\airbrake > + #include < anticheat\proaim > + #include < anticheat\autocbug > + #include < anticheat\flying > + + #include < anticheat\hooks > + + #define AC_INCLUDED +#endif \ No newline at end of file diff --git a/pawno/include/anticheat/player.inc b/pawno/include/anticheat/player.inc new file mode 100644 index 0000000..511116a --- /dev/null +++ b/pawno/include/anticheat/player.inc @@ -0,0 +1,91 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +// Macro Definitions (Global) + +#define ac_IsPlayerSpawned(%0) (p_acSpawned{%0}) + +// Variables (Player) + +enum E_PLAYER_HITPOINTS +{ + Float: E_POINTS, E_UPDATE_TIME, E_UPDATE_FAIL, + bool: E_SYNCED +}; + +enum E_PLAYER_REMOTEJACK +{ + Float: E_LAST_X, Float: E_LAST_Y, Float: E_LAST_Z, + E_LAST_VEH +}; + +new + // General + bool: p_acSpawned [ MAX_PLAYERS char ], + p_acUpdateTime [ MAX_PLAYERS ], + + // Health/Armour + Float: p_PlayerHealth [ MAX_PLAYERS ] [ E_PLAYER_HITPOINTS ], + Float: p_PlayerArmour [ MAX_PLAYERS ] [ E_PLAYER_HITPOINTS ], + Float: p_LastDamageIssued [ MAX_PLAYERS ], + p_LastTookDamage [ MAX_PLAYERS ], + p_LastDamageIssuer [ MAX_PLAYERS ] = { INVALID_PLAYER_ID, ... }, + p_LastWeaponIssuer [ MAX_PLAYERS ], + + // Weapon Hacks + bool: p_PlayerHasWeapon [ MAX_PLAYERS ] [ MAX_WEAPONS char ], + //p_PlayerWeaponUpdateTime [ MAX_PLAYERS ], + p_SelectedClassID [ MAX_PLAYERS ], + + // Spectating + //bool: p_SpectatePermission [ MAX_PLAYERS char ], + //p_PlayerSpectateUpdateTime [ MAX_PLAYERS ], + + // Airbrake + Float: p_abLastPosition [ MAX_PLAYERS ] [ 3 ], + p_abLastTick [ MAX_PLAYERS ], + p_abPosTick [ MAX_PLAYERS ], + p_abDetected [ MAX_PLAYERS char ], + p_abResetTimer [ MAX_PLAYERS ], + + // Pro-Aim + p_silentAimbotLastCalled [ MAX_PLAYERS ], + + // Auto Cbug + p_cbugKeyTicks [ MAX_PLAYERS ], + p_cbugFireTicks [ MAX_PLAYERS ], + p_cbugWarns [ MAX_PLAYERS char ], + + // Flying + p_FlyHacksTick [ MAX_PLAYERS ], + p_FlyHacksWarns [ MAX_PLAYERS char ], + + // Remote Jacking + p_remoteJackData [ MAX_PLAYERS ] [ E_PLAYER_REMOTEJACK ] +; + +// Functions (Player) diff --git a/pawno/include/anticheat/proaim.inc b/pawno/include/anticheat/proaim.inc new file mode 100644 index 0000000..9e2029a --- /dev/null +++ b/pawno/include/anticheat/proaim.inc @@ -0,0 +1,83 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +#include < anticheat\global > +#include < anticheat\player > + +#define ac_GetDistanceBetweenPoints(%0,%1,%2,%3,%4,%6) \ + (VectorSize(%0-%3,%1-%4,%2-%6)) + +// Callback Hook (OnPlayerWeaponShot) + +stock vCheckForSilentAimbot( playerid, hittype, hitid ) +{ + static + Float: fVictimX, Float: fVictimY, Float: fVictimZ, + Float: fCameraX, Float: fCameraY, Float: fCameraZ, + Float: fVectorX, Float: fVectorY, Float: fVectorZ, + Float: fHitPosX, Float: fHitPosY, Float: fHitPosZ + ; + + if( hittype == BULLET_HIT_TYPE_PLAYER && IsPlayerConnected( hitid ) && ! IsPlayerNPC( hitid ) ) + { + GetPlayerPos( hitid, fVictimX, fVictimY, fVictimZ ); + GetPlayerCameraPos( playerid, fCameraX, fCameraY, fCameraZ ); + GetPlayerCameraFrontVector( playerid, fVectorX, fVectorY, fVectorZ ); + GetPlayerLastShotVectors( playerid, fHitPosX, fHitPosY, fHitPosZ, fHitPosX, fHitPosY, fHitPosZ ); + + //printf("%f = %f, %f = %f, %f = %f\n", fX + fVictimX, fHitPosX, fY + fVictimY, fHitPosY, fZ + fVictimZ, fHitPosZ ); + + fCameraX += 4.0 * fVectorX; + fCameraY += 4.0 * fVectorY; + fCameraZ += 4.0 * fVectorZ; + + new Float: fCamera = ac_GetDistanceBetweenPoints( fHitPosX, fHitPosY, fHitPosZ, fCameraX, fCameraY, fCameraZ ); + new Float: fRadius = ac_GetDistanceBetweenPoints( fHitPosX, fHitPosY, fHitPosZ, fVictimX, fVictimY, fVictimZ ); + new Float: fPlayerDis = GetPlayerDistanceFromPoint( playerid, fVictimX, fVictimY, fVictimZ ); + + if( GetPlayerSurfingVehicleID( playerid ) == INVALID_VEHICLE_ID && GetPlayerSurfingVehicleID( hitid ) == INVALID_VEHICLE_ID && !IsPlayerInAnyVehicle( hitid ) ) + { + new + Float: fHitPacketLoss = NetStats_PacketLossPercent( hitid ), + Float: fOwnPacketLoss = NetStats_PacketLossPercent( playerid ), + iLastUpdateInterval = GetTickCount( ) - p_acUpdateTime[ hitid ] // AFK Check + ; + + if( fCamera < 1.20 && fPlayerDis > 4.0 && fPlayerDis < 300.0 && fRadius > 4.0 && fOwnPacketLoss < 0.8 && fHitPacketLoss < 0.8 && iLastUpdateInterval < 3000 ) { + new + iTicks = GetTickCount( ); + + if( iTicks - p_silentAimbotLastCalled[ playerid ] <= 5000 ) { + printf("[PRO-AIM] Detected %d - last %dms", playerid, iTicks - p_silentAimbotLastCalled[ playerid ]); + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_PROAIM ); + } + + p_silentAimbotLastCalled[ playerid ] = iTicks; + } + } + } +} diff --git a/pawno/include/anticheat/remotejack.inc b/pawno/include/anticheat/remotejack.inc new file mode 100644 index 0000000..8f663bb --- /dev/null +++ b/pawno/include/anticheat/remotejack.inc @@ -0,0 +1,56 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +#include < anticheat\global > +#include < anticheat\player > + +// Function (bCheckPlayerRemoteJacking) + +stock bCheckPlayerRemoteJacking( playerid ) +{ + new iVehicle = GetPlayerVehicleID( playerid ); + + if( !IsPlayerInAnyVehicle( playerid ) ) + GetPlayerPos( playerid, p_remoteJackData[ playerid ] [ E_LAST_X ], p_remoteJackData[ playerid ] [ E_LAST_Y ], p_remoteJackData[ playerid ] [ E_LAST_Z ] ); + + if( ( iVehicle != p_remoteJackData[ playerid ] [ E_LAST_VEH ] ) && ( iVehicle != 0 ) && ( GetPlayerState( playerid ) == PLAYER_STATE_DRIVER ) ) + { + new + Float: fDistance = GetVehicleDistanceFromPoint( iVehicle, p_remoteJackData[ playerid ] [ E_LAST_X ], p_remoteJackData[ playerid ] [ E_LAST_Y ], p_remoteJackData[ playerid ] [ E_LAST_Z ] ), + Float: fOffset = 10.0 + ; + + if( ( GetVehicleModel( iVehicle ) == 577 ) || ( GetVehicleModel( iVehicle ) == 592 )) fOffset = 25.0; // Andromanda | AT-400 + + if( fDistance > fOffset ) + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_REMOTE_JACK ); + + GetPlayerPos( playerid, p_remoteJackData[ playerid ] [ E_LAST_X ], p_remoteJackData[ playerid ] [ E_LAST_Y ], p_remoteJackData[ playerid ] [ E_LAST_Z ] ); + p_remoteJackData[ playerid ] [ E_LAST_VEH ] = iVehicle; + } + return 1; +} \ No newline at end of file diff --git a/pawno/include/anticheat/spectate.inc b/pawno/include/anticheat/spectate.inc new file mode 100644 index 0000000..431f4f3 --- /dev/null +++ b/pawno/include/anticheat/spectate.inc @@ -0,0 +1,59 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +#include < anticheat\global > +#include < anticheat\player > + +// Function Hook (GivePlayerWeapon) + +stock AC_TogglePlayerSpectating( playerid, toggle ) +{ + p_PlayerSpectateUpdateTime[ playerid ] = GetTickCount( ) + 1250; + p_SpectatePermission{ playerid } = true; + return TogglePlayerSpectating( playerid, toggle ); +} + +#if defined _ALS_TogglePlayerSpectating + #undef TogglePlayerSpectating +#else + #define _ALS_TogglePlayerSpectating +#endif +#define TogglePlayerSpectating AC_TogglePlayerSpectating + +// Function (bCheckForSpectatingHacks) + +stock bCheckForSpectatingHacks( playerid, iState, iTicks ) +{ + if( iTicks > p_PlayerSpectateUpdateTime[ playerid ] ) + { + if( iState == PLAYER_STATE_SPECTATING && !p_SpectatePermission{ playerid } ) { + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_SPECTATE ); + printf("[spectate] [%d] %d seems to spectate hack (state id %d, perm %d).", GetTickCount( ), playerid, iState, p_SpectatePermission{ playerid } ); + } + p_PlayerSpectateUpdateTime[ playerid ] = iTicks + 1000; + } +} \ No newline at end of file diff --git a/pawno/include/anticheat/weapon.inc b/pawno/include/anticheat/weapon.inc new file mode 100644 index 0000000..7dec931 --- /dev/null +++ b/pawno/include/anticheat/weapon.inc @@ -0,0 +1,210 @@ +/* + PROJECT <> SA:MP Anticheat Plug-in + LICENSE <> See LICENSE in the top level directory. + AUTHOR(S) <> Lorenc_ (zeelorenc@hotmail.com) + PURPOSE <> Providing datastructures for the internal SA:MP Server. + + + Copyright (C) 2014 SA:MP Anticheat Plug-in. + + The Project is available on https://github.com/myudev/SAMPAC + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . +*/ + +#include < a_samp > + +#include < anticheat\global > +#include < anticheat\player > + +// Function Hook (GivePlayerWeapon) + +stock AC_GivePlayerWeapon( playerid, weaponid, ammo ) +{ + //p_PlayerWeaponUpdateTime[ playerid ] = GetTickCount( ) + 2000; + + if( weaponid < MAX_WEAPONS ) + p_PlayerHasWeapon[ playerid ] { weaponid } = true; + + return GivePlayerWeapon( playerid, weaponid, ammo ); +} + +#if defined _ALS_GivePlayerWeapon + #undef GivePlayerWeapon +#else + #define _ALS_GivePlayerWeapon +#endif +#define GivePlayerWeapon AC_GivePlayerWeapon + +// Function Hook (ResetPlayerWeapons) + +stock AC_ResetPlayerWeapons( playerid ) +{ + new + bReset = ResetPlayerWeapons( playerid ); + + //p_PlayerWeaponUpdateTime[ playerid ] = GetTickCount( ) + 2000; + + for ( new i = 0; i < MAX_WEAPONS; i++ ) + p_PlayerHasWeapon[ playerid ] { i } = false; + + return bReset; +} + +#if defined _ALS_ResetPlayerWeapons + #undef ResetPlayerWeapons +#else + #define _ALS_ResetPlayerWeapons +#endif +#define ResetPlayerWeapons AC_ResetPlayerWeapons + +// Function Hook (SetSpawnInfo) + +stock AC_SetSpawnInfo( playerid, team, skin, Float: x, Float: y, Float: z, Float: Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ) +{ + if ( weapon1 != -1 && weapon1 < MAX_WEAPONS ) p_PlayerHasWeapon[ playerid ] { weapon1 } = true; + if ( weapon2 != -1 && weapon2 < MAX_WEAPONS ) p_PlayerHasWeapon[ playerid ] { weapon2 } = true; + if ( weapon3 != -1 && weapon3 < MAX_WEAPONS ) p_PlayerHasWeapon[ playerid ] { weapon3 } = true; + + return SetSpawnInfo( playerid, team, skin, x, y, z, Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ); +} + +#if defined _ALS_SetSpawnInfo + #undef SetSpawnInfo +#else + #define _ALS_SetSpawnInfo +#endif +#define SetSpawnInfo AC_SetSpawnInfo + +// Function Hook (AddPlayerClass) + +stock AC_AddPlayerClass( skin, Float: x, Float: y, Float: z, Float: Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ) +{ + new + classid = Iter_Free(classes); + + if( classid != -1 ) + { + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 0 ] = weapon1; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 0 ] = static_cast(params[7]); + + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 1 ] = weapon2; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 1 ] = static_cast(params[9]); + + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 2 ] = weapon3; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 2 ] = static_cast(params[11]); + + Iter_Add(classes, classid); + } + return AddPlayerClass( skin, x, y, z, Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ); +} + +#if defined _ALS_AddPlayerClass + #undef AddPlayerClass +#else + #define _ALS_AddPlayerClass +#endif +#define AddPlayerClass AC_AddPlayerClass + +// Function Hook (AddPlayerClass) + +stock AC_AddPlayerClassEx( teamid, skin, Float:x, Float:y, Float:z, Float:Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ) +{ + new + classid = Iter_Free(classes); + + if( classid != -1 ) + { + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 0 ] = weapon1; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 0 ] = static_cast(params[7]); + + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 1 ] = weapon2; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 1 ] = static_cast(params[9]); + + mAvailableSpawns[ classid ] [ E_WEAPONS ] [ 2 ] = weapon3; + //mAvailableSpawns[ classid ] [ E_WEAPONS_AMMO ] [ 2 ] = static_cast(params[11]); + + Iter_Add(classes, classid); + } + return AddPlayerClassEx( teamid, skin, x, y, z, Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo ) +} + +#if defined _ALS_AddPlayerClassEx + #undef AddPlayerClassEx +#else + #define _ALS_AddPlayerClassEx +#endif +#define AddPlayerClassEx AC_AddPlayerClassEx + +// Function Hook (CreateDynamicPickup) + +stock AC_CreateDynamicPickup( modelid, type, Float: x, Float: y, Float: z, worldid = -1, interiorid = -1, playerid = -1, Float: streamdistance = 100.0 ) +{ + new + id = CreateDynamicPickup( modelid, type, x, y, z, worldid, interiorid, playerid, streamdistance ); + + if( type == 2 || type == 3 || type == 15 || type == 22 ) + { + for( new i = 0; i < MAX_WEAPONS; i ++ ) + if( GetWeaponModel( i ) == modelid ) + SetGVarInt( "ac_WeaponPickup", i, id ); + } + return id; +} + +#if defined _ALS_CreateDynamicPickup + #undef CreateDynamicPickup +#else + #define _ALS_CreateDynamicPickup +#endif +#define CreateDynamicPickup AC_CreateDynamicPickup + +// Functions + +stock vWeaponHackCheck( playerid, keys ) +{ + if( ( keys & KEY_FIRE ) && ac_IsPlayerSpawned( playerid ) ) { + new + iWeapon = GetPlayerWeapon( playerid ); + + if( iWeapon > -1 && iWeapon < MAX_WEAPONS ) + { + if( !p_PlayerHasWeapon[ playerid ] { iWeapon } && ( iWeapon != 0 && iWeapon != 40 ) ) { + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_WEAPON ); + printf("[weapon] %d seems to weapon hack (weapon id %d).", playerid, iWeapon ); + } + } + } +} + +/*stock vWeaponHackCheck( playerid, iTicks ) +{ + if( iTicks > p_PlayerWeaponUpdateTime[ playerid ] ) + { + new + iWeapon, iAmmo; + + for( new iSlot = 0; iSlot != 13; iSlot++ ) + { + GetPlayerWeaponData( playerid, iSlot, iWeapon, iAmmo ); + + if( !p_PlayerHasWeapon[ playerid ] { iWeapon } && ( iAmmo > 0 && iWeapon != 0 && iWeapon != 40 ) ) { + CallLocalFunction( "OnPlayerCheatDetected", "dd", playerid, CHEAT_TYPE_WEAPON ); + printf("[weapon] %d seems to weapon hack (weapon id %d).", playerid, iWeapon ); + break; + } + } + p_PlayerWeaponUpdateTime[ playerid ] = iTicks + 750; + } +}*/ \ No newline at end of file diff --git a/pawno/pawn.cfg b/pawno/pawn.cfg new file mode 100644 index 0000000..bef8191 --- /dev/null +++ b/pawno/pawn.cfg @@ -0,0 +1 @@ +-d3 -r \ No newline at end of file