Код:
#include <a_samp>
#include <foreach>
#include <zcmd>
#include <sscanf2>
#define COLOR_WHITE 0xFFFFFFFF
#define RELEASED(%0) \
(((newkeys & (%0)) != (%0)) && ((oldkeys & (%0)) == (%0)))
/*
13 - slot id
1- weapon id, 2 - ammo
Feature things:
*/
new Weapons[MAX_PLAYERS][13][2], bool:Spawned[MAX_PLAYERS], bool:CanCheck[MAX_PLAYERS];
main() { }
public OnGameModeInit()
{
AddPlayerClass(0, 1958.33, 1343.12, 15.36, 269.15, 0, 0, 0, 0, 0, 0);
print("Serveris paleistas.");
return true;
}
public OnPlayerConnect(playerid)
{
Spawned[playerid] = false;
CanCheck[playerid] = false;
AC_ResetPlayerWeapons(playerid, true);
return true;
}
public OnPlayerSpawn(playerid)
{
CanCheck[playerid] = false;
Spawned[playerid] = true;
return true;
}
public OnPlayerDeath(playerid, killerid, reason)
{
Spawned[playerid] = false;
return true;
}
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if (RELEASED(KEY_FIRE))
{
new slotid = GetWeaponSlotByWepID(GetPlayerWeapon(playerid));
SetTimerEx("AC_UpdatePlayerWeaponAmmo", 100, false, "ii", playerid, slotid);
}
return true;
}
public OnPlayerDisconnect(playerid, reason)
{
return true;
}
public OnPlayerCommandPerformed( playerid, cmdtext[], success )
{
if( !success )
{
SendClientMessage(playerid, COLOR_WHITE, "Komanda nerasta.");
return true;
}
else
{
new pName[ MAX_PLAYER_NAME ];
GetPlayerName( playerid, pName, MAX_PLAYER_NAME );
printf( "[ID:%i] %s has called command: %s.", playerid, pName, cmdtext );
return true;
}
}
/*COMMAND:kill(playerid, params[])
{
SetPlayerHealth(playerid, 0.0);
return true;
}
COMMAND:ginklus(playerid, params[])
{
ResetPlayerWeapons(playerid);
return true;
}
COMMAND:ginkla(playerid, params[])
{
new weaponid, ammo;
if(sscanf(params, "ii", weaponid, ammo)) SendClientMessage(playerid, COLOR_WHITE, "Komandos naudojimas: /ginkla [weapon id] [ammo]");
else
{
GivePlayerWeapon(playerid, weaponid, ammo);
}
return true;
}
COMMAND:iginklus(playerid, params[])
{
AC_ResetPlayerWeapons(playerid);
return true;
}
COMMAND:iginkla(playerid, params[])
{
new weaponid, ammo;
if(sscanf(params, "ii", weaponid, ammo)) SendClientMessage(playerid, COLOR_WHITE, "Komandos naudojimas: /iginkla [weapon id] [ammo]");
else
{
AC_GivePlayerWeapon(playerid, weaponid, ammo);
}
return true;
}
stock DebugWeapons(playerid)
{
new tempWeapon[1][2];
print("[AC] Starting weapons debug...");
for (new i = 0; i < 13; i++)
{
GetPlayerWeaponData(playerid, i, tempWeapon[0][0], tempWeapon[0][1]);
printf("[AC] Weapon slot id: %d, weapon id: %i, weapon ammo: %i", i, tempWeapon[0][0], tempWeapon[0][1]);
}
print("[AC] Finished weapons debug.");
}*/
stock AC_ResetPlayerWeapons(playerid, bool:connect = false)
{
// *** WARNING: Reset weapons when connected ***
CanCheck[playerid] = false;
ResetPlayerWeapons(playerid);
for (new i = 0; i < 13; i++)
{
if(connect) Weapons[playerid][i][0] = 0;
Weapons[playerid][i][1] = 0;
}
}
stock AC_NullPlayerWeapons(playerid)
{
// *** WARNING: Null weapons before saving ***
CanCheck[playerid] = false;
for (new slotid = 0; slotid < 13; slotid++)
{
if(IsWeaponFireable(Weapons[playerid][slotid][0]) && Weapons[playerid][slotid][1] == 0) AC_RemovePlayerWeapon(playerid, slotid);
}
}
stock AC_GivePlayerWeapon(playerid, weaponid, ammo)
{
CanCheck[playerid] = false;
new slotid = GetWeaponSlotByWepID(weaponid), finalAmmo = ammo;
if(IsWeaponsInSameSlot(AC_GetPlayerWeaponIDFromSlot(playerid, slotid), weaponid)) finalAmmo += AC_GetPlayerWeaponAmmoFromSlot(playerid, slotid);
if(IsWeaponFireable(weaponid) && finalAmmo == 0) Weapons[playerid][slotid][1] = 0;
else
{
Weapons[playerid][slotid][0] = weaponid;
Weapons[playerid][slotid][1] = finalAmmo;
}
GivePlayerWeapon(playerid, weaponid, ammo);
}
stock AC_RegivePlayerWeapons(playerid)
{
CanCheck[playerid] = false;
for (new slotid = 0; slotid < 13; slotid++)
{
GivePlayerWeapon(playerid, Weapons[playerid][slotid][0], Weapons[playerid][slotid][1]);
}
}
forward AC_UpdatePlayerWeaponAmmo(playerid, slotid);
public AC_UpdatePlayerWeaponAmmo(playerid, slotid)
{
new weaponid, ammo;
GetPlayerWeaponData(playerid, slotid, weaponid, ammo);
if(IsWeaponFireable(weaponid) && Weapons[playerid][slotid][0] == weaponid) Weapons[playerid][slotid][1] = ammo;
}
stock AC_RemovePlayerWeapon(playerid, slotid)
{
Weapons[playerid][slotid][0] = 0;
Weapons[playerid][slotid][1] = 0;
}
public OnPlayerUpdate(playerid)
{
foreach(Player, i)
{
if(Spawned[i])
{
if(!CanCheck[i]) CanCheck[i] = true;
else
{
if(GetPlayerWeapon(i) == 0)
{
for (new slotid = 0; slotid < 13; slotid++)
{
AC_CheckPlayerWeapon(i, slotid);
}
}
else AC_CheckPlayerWeapon(i);
}
}
}
return true;
}
stock AC_CheckPlayerWeapon(playerid, slotid = -1)
{
new tempWeapon[1][2];
if(slotid == -1) slotid = GetWeaponSlotByWepID(GetPlayerWeapon(playerid));
GetPlayerWeaponData(playerid, slotid, tempWeapon[0][0], tempWeapon[0][1]);
if(tempWeapon[0][0] != 0)
{
if(tempWeapon[0][0] != AC_GetPlayerWeaponIDFromSlot(playerid, slotid) || (IsWeaponFireable(tempWeapon[0][0]) && tempWeapon[0][1] > AC_GetPlayerWeaponAmmoFromSlot(playerid, slotid)))
{
// kick
printf("[ID:%i] is kicked for gun cheats", playerid);
SendClientMessage(playerid, COLOR_WHITE, "KICKED");
printf("[ID:%i] is kicked for gun cheats. Wep id %i, ammo %i, ac wep id %i, ammo %i", playerid, tempWeapon[0][0], tempWeapon[0][1], Weapons[playerid][slotid][0], Weapons[playerid][slotid][1]);
}
else if(IsWeaponFireable(tempWeapon[0][0]) && AC_GetPlayerWeaponAmmoFromSlot(playerid, slotid) > tempWeapon[0][1]) Weapons[playerid][slotid][1] = tempWeapon[0][1];
}
}
stock GetWeaponSlotByWepID(weaponid)
{
switch (weaponid)
{
case 0, 1 : return 0;
case 2..9 : return 1;
case 22..24 : return 2;
case 25..27 : return 3;
case 28, 29, 32: return 4;
case 30, 31 : return 5;
case 33, 34 : return 6;
case 35..38 : return 7;
case 16..19, 39: return 8;
case 41..43 : return 9;
case 10..15 : return 10;
case 44..46 : return 11;
case 40 : return 12;
}
return -1;
}
stock IsWeaponFireable(weaponid)
{
switch (weaponid)
{
case 0..15, 40, 44..46: return false;
}
return true;
}
stock IsWeaponsInSameSlot(oldweaponid, newweaponid)
{
if(GetWeaponSlotByWepID(oldweaponid) == GetWeaponSlotByWepID(newweaponid)) return true;
return false;
}
stock AC_GetPlayerWeaponIDFromSlot(playerid, slotid) return Weapons[playerid][slotid][0];
stock AC_GetPlayerWeaponAmmoFromSlot(playerid, slotid) return Weapons[playerid][slotid][1];
Why in this anti-cheat when player release key_fire, then server update ammo? if player in that time will make ammo with ******s?