PDA

Просмотр полной версии : [Античит] Анти Weapon/Ammo Hack



vovandolg
25.09.2016, 23:37
Описание:

Зайдя на большинство серверов с интересной механикой прокачки скиллов оружия или где много разного оружия выдающегося по рангу или по какому то званию наверное наблюдали как игроки нубцы которые только вошли на серв уже бегают с таким же арсеналом как и деды этого серва, обычно владельцы сервов пишут античит на оружие по рангам или часам, но опять же получили Вы ранг выше/ниже и можете добавить себе патронов или вовсе включить их бесконечность и так далее, я думаю это всё не правильно и игрокам которые давно играют не в кайф видеть такие печальные картины, ещё на 0.3e я начал писать этот античит на оружие, единственно что не хватало там так это отслеживания выстрела(пытался знаете сделать костыль с Key State мол мышкой клацнул и выстрел), но как то надоело костылеписание это и поменял версию на 0.3.7 и добился полного успеха в написании этого античита на оружия и патроны к ним, либо мой античит не кому не охото обходить, либо он действительно уже дошёл до успеха, но мне кажется первый вариант :crazy:


Плюсы

Видит выдачу любого левого оружия
Видит выдачу любого левого патрона
Видит подмену оружия в слоте
Контролирует б/к на бесконечность
Данный код будет ловить читера как пешком так и в авто
Максимально складный код без мусора
Всё это без ложных вызовов (Если внимательно прочитать код и поставить в нужном месте свою проверку на AFK)

Минусы

На водительском месте не функционирует один(важный) каллбек, тем самым водительское место пришлось зафиксить



Код(v 0.4):

Pastebin (http://pastebin.com/HDx0j76m)
Или же


/*

Античит на оружие и патроны. [ver. 0.4] (By vovandolg)
Специально для портала Pro-Pawn (http://www.pro-pawn.ru)


Логи разработки:
[0.4]
- Патроны теперь записываются с каждого слота в отдельный массив
(так будет правильнее и удобнее для дальнейшей разработки мода на оружейные механики)
- Водительское место было зафиксено скрытием оружия из рук игрока
(слишком много уязвимости на водительском месте)

[0.3]
- Проверка на подмену оружия в слоте (например: AK-47 можно было заменить на M4)
- Более детальная проверка на наличие парашюта при десантировании с воздушных транспортов

[0.2]
- Фикс ложного вызова античита при смерти
- Более детальная проверка на Infinity ammo
*/

#include <a_samp>
#include <foreach>

#define TIME_GLOBAL_UPDATE (1000) //кол-во миллисекунд для апдейта таймера античита
#define MAX_SLOT_WEAP (13) //кол-во слотов оружия у игрока
#define MAX_TICK_PAUSE_AC (3) //кол-во раз игнора античита на игрока, 3 - стабильно
#define SLOT_WEAPON_PARACHUTE (11) //id слота в котором у игрока находится парашют
#define FIX_SPAWN_RESET_WEAP //закомментировать если фикс сброса оружия при смерти не нужен

#define FIX_DRIVER_WEAPONS //закомментировать если фикс скрытия оружия у водителя не нужен

#if defined FIX_DRIVER_WEAPONS
#define MAX_DHW_TIMER (1500)
//кол-во миллисекунд для таймера(скрытие оружия у водителя при посадке)
#endif


main(){}


new pPauseAC_one[MAX_PLAYERS char],
pPauseAC_two[MAX_PLAYERS char],
pState[MAX_PLAYERS char],
pWeapon[MAX_SLOT_WEAP][MAX_PLAYERS char],
pAmmo[MAX_SLOT_WEAP][MAX_PLAYERS],
pUseVehicleID[MAX_PLAYERS],
timglobal;

static const weapon_slot[47] =
{
0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
10, 10, 10, 10, 10, 10,
8, 8, 8,
0, 0, 0, //19-21
2, 2, 2,
3, 3, 3,
4, 4,
5, 5,
4,
6, 6,
7, 7, 7, 7,
8,
12,
9, 9, 9,
11, 11, 11
};

//--------------------[ Перехватим-ка функции :3 ]------------------------------
stock GivePlayerWeaponAC(playerid, weaponid, amount)
{
if(IsPlayerConnected(playerid) == 0) return 0;
new w_slot = weapon_slot[weaponid];
pPauseAC_one{playerid} = MAX_TICK_PAUSE_AC;
pWeapon[w_slot]{playerid} = weaponid;
pAmmo[w_slot][playerid] += amount;
GivePlayerWeapon(playerid, weaponid, amount);
#if defined FIX_DRIVER_WEAPONS
if(pState{playerid} == PLAYER_STATE_DRIVER)
{
SetTimerEx(!"DriverHidesWeapons", MAX_DHW_TIMER, false, "i", playerid);
}
#endif
return 1;
}
#if defined _ALS_GivePlayerWeapon
#undef GivePlayerWeapon
#else
#define _ALS_GivePlayerWeapon
#endif
#define GivePlayerWeapon GivePlayerWeaponAC

stock ResetPlayerWeaponsAC(playerid)
{
if(IsPlayerConnected(playerid) == 0) return 0;
pPauseAC_one{playerid} = MAX_TICK_PAUSE_AC;
ResetPlayerWeapons(playerid);
for(new i; i < MAX_SLOT_WEAP; i++)
{
pWeapon[i]{playerid} = 0;
pAmmo[i][playerid] = 0;
}
return 1;
}
#if defined _ALS_ResetPlayerWeapons
#undef ResetPlayerWeapons
#else
#define _ALS_ResetPlayerWeapons
#endif
#define ResetPlayerWeapons ResetPlayerWeaponsAC

//Для перехвата можно ещё SetPlayerAmmo/SetSpawnInfo добавить,
//но на основе этих функций можете сами слепить ...
//------------------------------------------------------------------------------


public OnGameModeInit()
{
SetGameModeText(!"AntiCheat Test");
AddPlayerClass(0, 0.0, 0.0, 4.0, 0.0, -1,-1,-1,-1,-1,-1);
CreateVehicle(411, 7.0, 7.0, 6.0, 0.0, 0, 0, 60, 1);
CreateVehicle(425, 9.0, 8.0, 7.0, 0.0, 0, 0, 60, 1);
CreateVehicle(461, 10.0, 9.0, 8.0, 0.0, 0, 0, 60, 1);
timglobal = SetTimer(!"OnGlobalUpdate", TIME_GLOBAL_UPDATE, true);
return 1;
}

public OnGameModeExit()
{
KillTimer(timglobal);
return 1;
}


public OnPlayerDisconnect(playerid)
{
for(new i; i < MAX_SLOT_WEAP; i++)
{
pWeapon[i]{playerid} = 0;
pAmmo[i][playerid] = 0;
}
return 0;
}

//Паблик затронут только для того чтобы выдать оружие
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys & KEY_YES) // Y
{
GivePlayerWeapon(playerid, 24, 1);
GivePlayerWeapon(playerid, 28, 2);
GivePlayerWeapon(playerid, 31, 3);
GivePlayerWeapon(playerid, 34, 4);
}
if(newkeys & KEY_NO) // N
{
GivePlayerWeapon(playerid, 23, 1);
GivePlayerWeapon(playerid, 29, 2);
GivePlayerWeapon(playerid, 30, 3);
GivePlayerWeapon(playerid, 33, 4);
}
return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
pState{playerid} = newstate;
if(newstate == PLAYER_STATE_WASTED || (newstate == PLAYER_STATE_ONFOOT &&
(oldstate == PLAYER_STATE_DRIVER || oldstate == PLAYER_STATE_PASSENGER)))
{
pUseVehicleID[playerid] = 0;
}
#if defined FIX_DRIVER_WEAPONS
if(newstate == PLAYER_STATE_DRIVER)
{
SetTimerEx(!"DriverHidesWeapons", MAX_DHW_TIMER, false, "i", playerid);
}
#endif
return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
//Точно не скажу нужен ли тут сброс оружия,
//но на ранних версиях SA:MP наблюдался баг показания неверных данных в GPWD
#if defined FIX_SPAWN_RESET_WEAP
ResetPlayerWeapons(playerid);
#else
for(new i; i < MAX_SLOT_WEAP; i++)
{
pWeapon[i]{playerid} = 0;
pAmmo[i][playerid] = 0;
}
#endif
return 1;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
pUseVehicleID[playerid] = vehicleid;
return 1;
}

public OnPlayerExitVehicle(playerid)
{
//Парашют при выходе с воздушного транспорта )-_-(
if(IsAirTransport(GetVehicleModel(pUseVehicleID[playerid])) == 1)
{
pPauseAC_one{playerid} = MAX_TICK_PAUSE_AC - 1;
pWeapon[SLOT_WEAPON_PARACHUTE]{playerid} = WEAPON_PARACHUTE;
pAmmo[SLOT_WEAPON_PARACHUTE][playerid] = 1;
}
return 1;
}

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
//Боремся с Infinity Ammo ^-^
new wslot = weapon_slot[weaponid];
if(pAmmo[wslot][playerid] > 0)
{
pPauseAC_two{playerid} = MAX_TICK_PAUSE_AC - 1;
pAmmo[wslot][playerid]--;
}
else return 0;
return 1;
}


forward OnGlobalUpdate();
public OnGlobalUpdate()
{
foreach(new i: Player)
{
//Проверяем игрока на то что он живой и бегает по карте
//Рекомендую сюда всунуть ещё свою проверку игроков на AFK
if(pState{i} == 7 || pState{i} == 8) continue;

if(pPauseAC_two{i} > 0) pPauseAC_two{i}--;
if(pPauseAC_one{i} > 0)
{
pPauseAC_one{i}--;
continue;
}

new weaponid[MAX_SLOT_WEAP],
weaponammo[MAX_SLOT_WEAP];

for(new s; s < MAX_SLOT_WEAP; s++)
{
//Начинаем записывать инфу оружия и б/п из слота
GetPlayerWeaponData(i, s, weaponid[s], weaponammo[s]);

//Проверяем на обход в минус или на Infinitiy ammo
if(pAmmo[s][i] < 0 || weaponammo[s] < 0)
{
printf("[part] Player[%i] slot[%i] pAmmo[%i] weaponammo[%i], kick!", i, s, pAmmo[s][i], weaponammo[s]);
SendClientMessage(i, -1, !"Айяй, бесконечные патроны юзаешь или обошёл?![#001]");
ResetPlayerWeapons(i);
//Kick(i);
break;
}

//Совпало ли оружие в слоте с тем которое выдавал сервер
if(weaponid[s] > 0 && weaponid[s] != pWeapon[s]{i})
{
printf("[part] Player[%i] pWeapon[%i] slot[%i] weaponid[%i], kick!", i, pWeapon[s]{i}, s, weaponid[s]);
SendClientMessage(i, -1, !"Айяй, я тебе такой ствол не давал![#002]");
ResetPlayerWeapons(i);
//Kick(i);
break;
}

if(pPauseAC_two{i} > 0) continue;

//Если кол-во записанных патронов в слоте меньше чем найденных(хакнутых)
if(pAmmo[s][i] < weaponammo[s])
{
if(pPauseAC_one{i} == 0 && pPauseAC_two{i} == 0)
{
printf("[part] Player[%i] slot[%i] pAmmo[%i] weaponammo[%i], kick!", i, s, pAmmo[s][i], weaponammo[s]);
SendClientMessage(i, -1, !"Айяй, патроны воруешь![#003]");
ResetPlayerWeapons(i);
//Kick(i);
break;
}
else break;
}

//Если кол-во записанных патронов в слоте больше чем найденных,
//то обновим кол-во патронов в переменной слота оружия
else if(pAmmo[s][i] > weaponammo[s])
{
if(pPauseAC_one{i} == 0 && pPauseAC_two{i} == 0) pAmmo[s][i] = weaponammo[s];
else break;
}
//Если кол-во записанных патронов в слоте равно найденным,
//то не теребонькаем систему ;D
}
}
return 1;
}

#if defined FIX_DRIVER_WEAPONS
forward DriverHidesWeapons(playerid);
public DriverHidesWeapons(playerid)
return SetPlayerArmedWeapon(playerid, 0);
#endif

//Является ли указанный vehid воздушным транспортом, 1 - да | 0 - нет
stock IsAirTransport(vehid)
{
switch(vehid)
{
case 417,425,447,460,469,476,487,488,497,511..513,
519,520,548,553,563,577,592,593: return 1;
}
return 0;
}



Автор античита:

vovandolg



Античит был написан по полученным знаниям этого замечательного форума!

Nexius_Tailer
26.09.2016, 00:24
Молодец, довольно просто реализовано.
Единственный пока найденный минус - бесконечная стрельба возможна до тех пор, пока читеру это не надоест, т.к. реагировать античит начинает только после прекращения стрельбы. Наказание слишком уж запаздывает.

vovandolg
26.09.2016, 00:33
Молодец, довольно просто реализовано.
Единственный пока найденный минус - бесконечная стрельба возможна до тех пор, пока читеру это не надоест, т.к. реагировать античит начинает только после прекращения стрельбы. Наказание слишком уж запаздывает.

Ну для простеньких РПшек или ДМ это норма) если читера будет постоянно кикать ему тоже надоест, а если поставить Ban по IP то он пару разов или разок так сделает и больше не зайдёт, это я говорю как владелец серва на вкладке, они когда видят что их кикает и обойти не могут сразу пуканы подгорают и прекращают коннектится...
В общем так спокойнее стало и за экономику в плане оружия и патронов стало честнее.

Nexius_Tailer
26.09.2016, 09:25
Так если бы его кикало. Во время стрельбы с бесконечными патронами никого не кикает (а только после её прекращения). Следовательно, перед киком такой желанный игрок ещё пол сервера перебить успеет.

vovandolg
26.09.2016, 14:37
Так если бы его кикало. Во время стрельбы с бесконечными патронами никого не кикает (а только после её прекращения). Следовательно, перед киком такой желанный игрок ещё пол сервера перебить успеет.

Поверь не кому не захочется идти маленькими шажками с зажатыми кнопками мыши и ливать весь серв
Это тоже читеров бесит..

Nexius_Tailer
26.09.2016, 16:42
"Поверь-не поверь", а уязвимость у античита на бесконечные патроны есть.

vovandolg
26.09.2016, 16:54
Что нибудь придумаю попозже(как освобожусь от долбанного огорода)

m1n1vv
26.09.2016, 17:19
if (ammo < 0) // у игрока бесконечные патроны
//или
if (ammo == -31073) // у игрока бесконечные патроны

vovandolg
26.09.2016, 17:48
if (ammo < 0) // у игрока бесконечные патроны
//или
if (ammo == -31073) // у игрока бесконечные патроны

Обрисую ситуацию почему я именно так сделал, если игроку выдать через игру ствол и он активирует Infinity ammo у него не будет минуса, у него просто не будут отниматься патроны, а кол-во патронов в минусе можно настроить по разному хоть -31073, хоть -31074 и так далее, поэтому я и поставил < 0

m1n1vv
26.09.2016, 18:36
А если так?

new
ac_time[MAX_PLAYERS],
ac_ammo[MAX_PLAYERS];

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(GetTickCount() > ac_time[playerid])
{
new
ammo = ac_ammo[playerid];

ac_ammo[playerid] = GetPlayerAmmo(playerid);
ac_time[playerid] = GetTickCount() + 1000;

if (ammo == ac_ammo[playerid])
SendClientMessage(playerid, -1, !"Infinity ammo +");
else
SendClientMessage(playerid, -1, !"Infinity ammo -");
}
return 1;
}

vovandolg
26.09.2016, 19:49
Обновил код до версии 0.2:hi:

- - - Добавлено - - -


А если так?

new
ac_time[MAX_PLAYERS],
ac_ammo[MAX_PLAYERS];

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(GetTickCount() > ac_time[playerid])
{
static
ammo = ac_ammo[playerid];

ac_ammo[playerid] = GetPlayerAmmo(playerid);
ac_time[playerid] = GetTickCount() + 1000;

if (ammo == ac_ammo[playerid])
SendClientMessage(playerid, -1, !"Infinity ammo +");
else
SendClientMessage(playerid, -1, !"Infinity ammo -");
}
return 1;
}

Так же думал сделать по началу, потом подумал, а что если миниган начнет стрелять))

m1n1vv
26.09.2016, 19:53
Обновил код до версии 0.2:hi:

- - - Добавлено - - -



Так же думал сделать по началу, потом подумал, а что если миниган начнет стрелять))

Я бы за миниган так же кикал. Оружие дисбаланса.

DeimoS
26.09.2016, 20:19
Обновил код до версии 0.2:hi:

- - - Добавлено - - -



Так же думал сделать по началу, потом подумал, а что если миниган начнет стрелять))

Для минигана и другого скорострельного оружия просто делаешь "буфер" из 5-10 патрон. То бишь, если значение, возвращённое GetPlayerWeaponData, не совпадает с значением из массива на эти самые 5-10 патрон - игнорируешь. Иначе - читер.
Либо просто можно задержку делать в GetPlayerWeaponData, но всё равно могут быть ложные.


Вот мой вариант античита на оружие, которое я писал ещё году в 2014. Писал я его не для себя и как пример, так что за 100% работоспособность не ручаюсь (точнее, работать-то он будет, но вот на ложные срабатывания особо не тестировал) :dntknw:
И да, код оставил нетронутым. Вот так я писал в 2014 году :lol:


#include <AntiGunCheat>

public OnPlayerConnect(playerid)
{
ClearGunAnticheatInfoOPC(playerid);
return 1;
}

forward CheckPlayerWeapon(playerid);
public CheckPlayerWeapon(playerid)
{
if(!IsPlayerConnected(playerid)) goto CheckPlayerWeapon_end;
if(GetPlayerState(playerid) != PLAYER_STATE_WASTED)
{
if(gun_ac_giveweapon_time[playerid][0] > GetTickCount()) return 1;
for(new i = 0, weapon[2]; i != 13; i++)
{
GetPlayerWeaponData_Ex(playerid, i, weapon[0], weapon[1]);
if(gun_ac_weapon[playerid][i] == -1 && weapon[0] || gun_ac_weapon[playerid][i] != -1 && gun_ac_weapon[playerid][i] != weapon[0])
{
ResetPlayerWeaponsEx(playerid);
new string[64+MAX_PLAYER_NAME+3];
GetPlayerName(playerid, string, MAX_PLAYER_NAME);
format(string, sizeof(string), "Игрок %s [ID: %d] был кикнут по подозрению в использовании Gun Cheat (оружие)", string, playerid);
SendClientMessageToAll(-1, string);
Kick(playerid);
return 0;
}
if(weapon[0] != 46 && (gun_ac_ammo[playerid][i] == -1 && weapon[1] || gun_ac_ammo[playerid][i] != -1 && gun_ac_ammo[playerid][i] != weapon[1]))
{
if(gun_ac_giveweapon_time[playerid][1] > GetTickCount()) return 1;
ResetPlayerWeaponsEx(playerid);
new string[78+MAX_PLAYER_NAME+3];
GetPlayerName(playerid, string, MAX_PLAYER_NAME);
format(string, sizeof(string), "Игрок %s [ID: %d] был кикнут по подозрению в использовании Gun Cheat (патроны)", string, playerid);
SendClientMessageToAll(-1, string);
Kick(playerid);
return 0;
}
}
}
SetTimerEx("CheckPlayerWeapon", 15000, false, "i", playerid);
CheckPlayerWeapon_end:
return 1;
}

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(0 < weaponid < 46)
{
new weapon_slot = GetWeaponSlot(weaponid);
gun_ac_ammo[playerid][weapon_slot]--;
if(gun_ac_ammo[playerid][weapon_slot] == 0)
{
gun_ac_weapon[playerid][weapon_slot] = -1;
gun_ac_ammo[playerid][weapon_slot] = -1;
}
else
{
if(gun_ac_weapon[playerid][weapon_slot] == -1 && weaponid || gun_ac_ammo[playerid][weapon_slot] != -1 && gun_ac_weapon[playerid][weapon_slot] != weaponid)
{
ResetPlayerWeaponsEx(playerid);
new string[64+MAX_PLAYER_NAME+3];
GetPlayerName(playerid, string, MAX_PLAYER_NAME);
format(string, sizeof(string), "Игрок %s [ID: %d] был кикнут по подозрению в использовании Gun Cheat (оружие)", string, playerid);
SendClientMessageToAll(-1, string);
Kick(playerid);
return 0;
}
new ammo;
GetPlayerWeaponData_Ex(playerid, weapon_slot, ammo, ammo);

if(gun_ac_ammo[playerid][weapon_slot] == -1 && ammo || gun_ac_ammo[playerid][weapon_slot] != -1 && gun_ac_ammo[playerid][weapon_slot]+1 != ammo)
{
if(gun_ac_giveweapon_time[playerid][1] > GetTickCount()) return 1;
ResetPlayerWeaponsEx(playerid);
new string[78+MAX_PLAYER_NAME+3];
GetPlayerName(playerid, string, MAX_PLAYER_NAME);
format(string, sizeof(string), "Игрок %s [ID: %d] был кикнут по подозрению в использовании Gun Cheat (патроны)", string, playerid);
SendClientMessageToAll(-1, string);
Kick(playerid);
return 0;
}
}
}
return 1;
}



new gun_ac_weapon[MAX_PLAYERS][13],
gun_ac_ammo[MAX_PLAYERS][13],
gun_ac_giveweapon_time[MAX_PLAYERS][2];

stock ClearGunAnticheatInfoOPC(playerid)
{
for(new i; i != 13; i++)
{
gun_ac_weapon[playerid][i] = -1;
gun_ac_ammo[playerid][i] = -1;
}
gun_ac_giveweapon_time[playerid][0] = -1;
gun_ac_giveweapon_time[playerid][1] = -1;
SetTimerEx("CheckPlayerWeapon", 15000, false, "i", playerid);
ResetPlayerWeapons(playerid);
return 1;
}

stock GetPlayerWeaponData_Ex(playerid, slot, &weapons, &ammo)
{
new tick = GetTickCount();
if(gun_ac_giveweapon_time[playerid][1] >= tick) gun_ac_giveweapon_time[playerid][1] = tick+1500;
GetPlayerWeaponData(playerid, slot, weapons, ammo);
return 1;
}

stock GivePlayerWeaponEx(playerid, weaponid, ammo)
{
if(!(0 < weaponid < 46))
{
SendClientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}В функцие GivePlayerWeapon используется неверный ID оружия");
SendClientMessage(playerid, 0xFFFFFFFF, "Пожалуйста, сообщите об этом администрации сервера");
return 1;
}
new weapon[2];
GetPlayerWeaponData_Ex(playerid, GetWeaponSlot(weaponid), weapon[0], weapon[1]);
gun_ac_weapon[playerid][GetWeaponSlot(weaponid)] = weaponid;
if(weaponid == weapon[0]) gun_ac_ammo[playerid][GetWeaponSlot(weaponid)] += ammo;
else gun_ac_ammo[playerid][GetWeaponSlot(weaponid)] = ammo;
gun_ac_giveweapon_time[playerid][1] = GetTickCount()+1500;
GivePlayerWeapon(playerid, weaponid, ammo);
return 1;
}
#define GivePlayerWeapon GivePlayerWeaponEx

stock ResetPlayerWeaponsEx(playerid)
{
for(new i = 0; i != 13; i++)
{
gun_ac_weapon[playerid][i] = -1;
if(gun_ac_ammo[playerid][i] != -1) printf(gun_ac_ammo[playerid][i]);
gun_ac_ammo[playerid][i] = -1;
}
ResetPlayerWeapons(playerid);
return 1;
}
#define ResetPlayerWeapons ResetPlayerWeaponsEx

stock GetWeaponSlot(weaponid)
{
switch(weaponid)
{
case 0..1: return 0;
case 2..9: return 1;
case 10..15: return 10;
case 16..18, 39: return 8;
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 40: return 12;
case 41..43: return 9;
case 44..46: return 11;
}
return 0;
}


Может кто найдёт что-то интересное для себя в этом говнокоде :dntknw:

vovandolg
26.09.2016, 20:33
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(0 < weaponid < 46)

Меня только одно интересует, разве может сработать этот паблик если стрелять не с этого условия 0 < weaponid < 46?
И чем?

DeimoS
26.09.2016, 20:44
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(0 < weaponid < 46)

Меня только одно интересует, разве может сработать этот паблик если стрелять не с этого условия 0 < weaponid < 46?
И чем?

https://wiki.sa-mp.com/wiki/OnPlayerWeaponShot

http://i.imgur.com/XTApv7Q.png

vovandolg
26.09.2016, 20:47
Для минигана и другого скорострельного оружия просто делаешь "буфер" из 5-10 патрон. То бишь, если значение, возвращённое GetPlayerWeaponData, не совпадает с значением из массива на эти самые 5-10 патрон - игнорируешь. Иначе - читер.
Либо просто можно задержку делать в GetPlayerWeaponData, но всё равно могут быть ложные.

Я защиту 0.2 обкатаю на своём ходовом сервере, отпишусь тут будут ли ложные, но я сейчас прыгал летал скакал как жаленный в попу и не чего не выдавало ложно) единственно что не хватает в коде это афк системы, но я думаю не для кого не проблема ставить афк систему, поэтому я считаю что в основном античит стал более комфортным и рабочим, только благодаря Anti Infinity ammo теперь даже игнорирование GPWD не поможет, я думаю не кто не обойдёт такую систему пока что...

- - - Добавлено - - -


https://wiki.sa-mp.com/wiki/OnPlayerWeaponShot

http://i.imgur.com/XTApv7Q.png

Нууу так там же написано что игрок может хакнуть для себя и отправлять пули, для античита наоборот нормально он его за такое и впоимает, или я английский не так перевел?

m1n1vv
26.09.2016, 22:14
Сейчас проверил свой код на миниган. 0 ложных срабатываний.

vovandolg
27.09.2016, 05:31
Один инвалид с г-и любезно обосрал мой код))
Но при этом ещё и рассказал толковый баг(с подменой оружия в слотах), поэтому update 0.3:hi:

- - - Добавлено - - -


Сейчас проверил свой код на миниган. 0 ложных срабатываний.

Вариант то не плохой, но 2 функции за 1 выстрел вызывать не знаю даже...

m1n1vv
27.09.2016, 15:48
А что насчет NOP Weapon Data?

vovandolg
27.09.2016, 16:42
А что насчет NOP Weapon Data?


только благодаря Anti Infinity ammo теперь даже игнорирование GPWD не поможет, я думаю не кто не обойдёт такую систему пока что...
Как то так наверное)) Всё довольно хорошо связано между собой, поэтому наврятли получится долго поиграть...

vovandolg
28.09.2016, 04:34
0.4
На водительском месте не работает OPWS :facepalm:, а значит беск. патроны уязвимы там
Патроны теперь как и оружие записываются в свой слот
Лишних выстрелов не будет если античит заметит лишние патроны

Enrique_Black
25.04.2017, 21:31
А где учет кастета в машине? Если у меня будет кастет то его все ровно заменит на кулак. Понимаю это не к чему но все же)

ziggi
25.04.2017, 22:14
Не понял прикола с pUseVehicleID, этот массив используется только в OnPlayerExitVehicle, но в этом нет смысла, ибо OnPlayerExitVehicle уже передаёт id транспорта, из которого вышли: OnPlayerExitVehicle.

Web
26.04.2017, 01:02
Не понял прикола с pUseVehicleID, этот массив используется только в OnPlayerExitVehicle, но в этом нет смысла, ибо OnPlayerExitVehicle уже передаёт id транспорта, из которого вышли: OnPlayerExitVehicle.

Ну и если игрока выкинуть из транспорта, то OnPlayerExitVehicle не будет вызван.

ziggi
26.04.2017, 11:51
Ну и если игрока выкинуть из транспорта, то OnPlayerExitVehicle не будет вызван.

В скрипте он используется только для выдачи парашюта, поэтому OnPlayerExitVehicle вполне достаточно.

vovandolg
26.04.2017, 16:32
А где учет кастета в машине? Если у меня будет кастет то его все ровно заменит на кулак. Понимаю это не к чему но все же)

А зачем тебе за рулём нужно оружие? Да ещё в придачу то что ты им не сможешь бить или стрелять)))
________________

В скрипте он используется только для выдачи парашюта, поэтому OnPlayerExitVehicle вполне достаточно.

Это моя "плохая" привычка писать совместимость с другими античитами))
Так и так метеорит не упадёт от такого хука с переменной или без неё,
но лучше если будет ловить выходящего/вытолкнутого игрока 100%.

Enrique_Black
26.04.2017, 17:14
А зачем тебе за рулём нужно оружие? Да ещё в придачу то что ты им не сможешь бить или стрелять)))

Ну я думаю если делать то делать и разницы сможешь бить или нет особо нету. Ну это мое мнение.


Ну ладно, докопаюсь к гольф клюшке?
При выходе из 457 тачки выдается гольф клюшка и кстати долеко не каждый раз как в случае с парашутом.

ziggi
26.04.2017, 19:29
Ну ладно, докопаюсь к гольф клюшке?
При выходе из 457 тачки выдается гольф клюшка и кстати долеко не каждый раз как в случае с парашутом.

Недавно где-то это обсуждалось, оказалось, что это "фишка" собейта.

vasyok28
26.04.2017, 21:27
Кому понадобиться оружие в транспорте, думаю решит проблему ракнет менеджером

DeimoS
26.04.2017, 21:46
Недавно где-то это обсуждалось, оказалось, что это "фишка" собейта.

"Где-то (http://forum.sa-mp.com/showpost.php?p=3857629&postcount=15024)" - для тех, кому интересны подробности

Enrique_Black
26.04.2017, 23:13
"Где-то (http://forum.sa-mp.com/showpost.php?p=3857629&postcount=15024)" - для тех, кому интересны подробности

Благодарствую)

vovandolg
27.04.2017, 02:08
Надо в шапке форума написать "если хочешь научится скриптингу снеси папку клео и собейта" ...

Так и хочется залить все примеры переписок где людям читы портят скриптинг и они даже не предполагают что это так и есть.

DeimoS
27.04.2017, 02:29
Надо в шапке форума написать "если хочешь научится скриптингу снеси папку клео и собейта" ...

Так и хочется залить все примеры переписок где людям читы портят скриптинг и они даже не предполагают что это так и есть.

То же самое можно и про любые другие моды сказать: будь то текстурные или какие-либо ещё :)
Вообще, если ты занимаешься написанием скриптов для SA-MP, то тебе следует иметь дополнительную ванильную (без каких-либо модов) версию игры, с помощью которой можно будет проверять свои скрипты на работоспособность. Так можно и какие-либо изъяны, а-ля проблемы с текстдравами, отловить, и проверить: крашит/лагает из-за модификаций GTA или это в моде ошибка.
В общем-то это правило применимо для любых видов разработки. Всегда полезно побыть в шкуре рядового пользователя твоим продуктом :) Можно много багов и недочётов таким способом отловить.

JohnConor
18.05.2017, 12:08
То же самое можно и про любые другие моды сказать: будь то текстурные или какие-либо ещё :)
Вообще, если ты занимаешься написанием скриптов для SA-MP, то тебе следует иметь дополнительную ванильную (без каких-либо модов) версию игры, с помощью которой можно будет проверять свои скрипты на работоспособность. Так можно и какие-либо изъяны, а-ля проблемы с текстдравами, отловить, и проверить: крашит/лагает из-за модификаций GTA или это в моде ошибка.
В общем-то это правило применимо для любых видов разработки. Всегда полезно побыть в шкуре рядового пользователя твоим продуктом :) Можно много багов и недочётов таким способом отловить.

Соглашусь как-то долго не мог понять почему у маппера не запускается некоторые текстдравы, а как потом выяснилось проблема крылась в GTA