Other available versions. Ordered by newest to oldest versions:
Just so you know, we don't know the file format for every file. If it's just a bunch of random characters, it's probably a .zip or .jar.
options:
prefix: &e[&cAAAC&e]
punish: true # Should the players get kicked?
max-vl: 5 # The amount of times that the player can fail the checks before getting kicked
# AAAC 1.0 BY pingwinek#9268, usage of any code in this project for any use wheter commercial or non commercial is permitted if given credit.
# NOTE, aaac (AdvancedAntiAutoClicker) will NOT ban anyone, it will just send notifications to admins.
# The purpose here is to detect autoclickers over a long period of time, dont expect it to detect autoclickers when a fight lasts 2 seconds okay?
# It's meant to detect closet cheating on practice/pvp servers, not on your aternos survival server. It's also the (first?) anti autoclicker made in skript to utilize concepts used in modern anticheats like deviation, consistency or kurtosis. (And actually utilizing those at least semi-properly)
# Additionaly, nothing here is skidded, i spent a long time coding everything myself, the methods used to detect autoclicking are known to almost everyone and used in a variety of anticheats, this is a proof of concept.
# Current checks include:
# Autoclicker
# (A) Limit - A hard cps limit (WARNING, BASED ON ARM SWING EVENT)
# (B) Blatant - Little to no difference between cps values
# (C) Deviation - Average deviation in a list of differences between cps values
# (D) Rounded - Rounded max and min values from a list of differences
# (E) Difference - Experimental check, similar to the rounded check
# (F) Kurtosis - Basic kurtosis algorithm
# (G) Frequency - Checks for repeated rounded cps values
# (H) Range - Deviation but improved a bit
# (I) Pattern - Quick pattern comparison check
# Permissions:
# aaac.notify - any person having this permission can viev alerts and toggle them on/off
# CAUTION! DEV OPTIONS.
# Do not touch these values unless you have taken a look at the code and understand what they're doing.
# I already configured them to not false flag, but if you do find them less than ideal, feel free to experiment a bit.
armswing-limit: 31
armswing-buffer: 16
min-cps: 6.1
difference-min: 0.14
difference-buffer: 8
deviation-min: 0.29
deviation-buffer: 2
kurtosis-max: 0.44
range-limit: 0.33
version: 1.2 # DO NOT CHANGE
on load:
wait 2.5 seconds
set {_version} to text from "http://site21231.web1.titanaxe.com/api.php"
if "{@version}" is not "%{_version}%":
send "{@prefix} &fAn update is available!" to console
send "{@prefix} &fDownload at: https://forums.skunity.com/resources/aaac-advancedantiautoclicker.1573/" to console
else:
send "{@prefix} &fYou are running the lastest version of AAAC (%{_version}%)" to console
function alert(p: player, check: text, moreinfo: text="null"):
add 1 to {aaac::flags::%{_p}%}
if {aaac::flags::%{_p}%} > {@max-vl}:
if {@punish} = true:
kick {_p} due to "{@prefix} &fAutoclicking is not allowed!"
delete {aaac::flags::%{_p}%}
loop all players:
check [loop-player has permission "aaac.notify"]->[{aaac::alerts::%loop-player%} = true]
if {_moreinfo} != "null":
send formatted "<tooltip:Cps: %{aaac::armswings::%{_p}%}%%nl%%{_moreinfo}%>{@prefix} &f%{_p}% failed &c%{_check}%" to loop-player
else:
send formatted "<tooltip:Cps: %{aaac::armswings::%{_p}%}%>{@prefix} &f%{_p}% failed &c%{_check}%" to loop-player
command /alerts:
permission: aaac.notify
permission message: {@prefix} &cYou don't have the permission required to use this command.
trigger:
if {aaac::alerts::%player%} = false:
set {aaac::alerts::%player%} to true
send "{@prefix} &fAlerts enabled"
stop
if {aaac::alerts::%player%} = true:
set {aaac::alerts::%player%} to false
send "{@prefix} &fAlerts disabled"
stop
if {aaac::alerts::%player%} is not set:
set {aaac::alerts::%player%} to true
send "{@prefix} &fAlerts enabled"
stop
on left click: # ON LEFT CLICK SUPREMACY!!!11!!
if {aaac::cps::%player%} > {@min-cps}:
if size of {aaac::cps::list::%player%::*} = 10:
if size of {aaac::patterns::%player%::*} > 4:
delete {aaac::patterns::%player%::*}
if {aaac::patterns::%player%::*} contains "%{aaac::cps::list::%player%::*}%":
alert(player, "Autoclicker I &f(Pattern)", "Pattern: %{aaac::cps::list::%player%::*}%") # Pattern comparison (This check is ASS, do not skid it.)
else:
add "%{aaac::cps::list::%player%::*}%" to {aaac::patterns::%player%::*}
set {aaac::cps::average::%player%} to sum({aaac::cps::list::%player%::*}) / 10
add difference between {aaac::cps::average::%player%} and {aaac::previous::cps::average::%player%} to {aaac::difference::list::%player%::*}
add difference between {aaac::cps::average::%player%} and {aaac::previous::cps::average::%player%} to {aaac::comparison::list::%player%::*}
if size of {aaac::comparison::list::%player%::*} >= 5:
loop {aaac::comparison::list::%player%::*}:
set {_squared} to (loop-value - {_mean})^2
set {_sum} to {_sum} + {_squared}
set {_stddev} to sqrt({_sum} / 8)
if {_stddev} < {@range-limit}:
add 1 to {aaac::range::flag::%player%}
if {aaac::range::flag::%player%} > 2:
delete {aaac::range::flag::%player%}
alert(player, "Autoclicker H &f(Range)", "Difference: %{_stddev}%") # Improved deviation check
set {_diff} to difference between min({aaac::comparison::list::%player%::*}) and max({aaac::comparison::list::%player%::*})
if "%{_diff}%" does not contain ".":
add 1 to {aaac::rounded::flag::%player%}
if {aaac::rounded::flag::%player%} >= 3:
delete {aaac::rounded::flag::%player%}
alert(player, "Autoclicker D &f(Rounded)", "Difference: %{_diff}%") # Detects ass randomization
set {_diff::experimental} to rounded down max({aaac::comparison::list::%player%::*}) - rounded down min({aaac::comparison::list::%player%::*})
if {_diff::experimental} = 0:
add 1 to {aaac::difference::flag::%player%}
if {aaac::difference::flag::%player%} >= 3:
alert(player, "Autoclicker E &f(Difference)") # Difference between min and max but rounded, yay.
delete {aaac::difference::flag::%player%}
else:
if {aaac::difference::flag::%player%} > 0:
remove 1 from {aaac::difference::flag::%player%}
delete {aaac::comparison::list::%player%::*}
if size of {aaac::difference::list::%player%::*} >= 8:
set {_mean} to sum({aaac::difference::list::%player%::*}) / 8
loop {aaac::difference::list::%player%::*}:
set {_squared} to (loop-value - {_mean})^2
set {_sum} to {_sum} + {_squared}
set {_stddev} to sqrt({_sum} / 8)
if {_stddev} < {@deviation-min}:
add 1 to {aaac::deviation::flag::%player%}
if {aaac::deviation::flag::%player%} >= {@deviation-buffer}:
alert(player, "Autoclicker C &f(Deviation)", "Deviation: %{_stddev}%") # Deviation, that's it, deviation. I mean average deviation.
else:
if {aaac::deviation::flag::%player%} > 0:
remove 1 from {aaac::deviation::flag::%player%}
loop {aaac::difference::list::%player%::*}:
add ((loop-value - {_mean}) / {_stddev})^4 to {_kurtosis}
set {_kurtosis} to {_kurtosis} * size of {aaac::difference::list::%player%::*} * (size of {aaac::difference::list::%player%::*} + 1) / ((size of {aaac::difference::list::%player%::*} - 1) * (size of {aaac::difference::list::%player%::*} - 2) * (size of {aaac::difference::list::%player%::*} - 3)) - 3 * (size of {aaac::difference::list::%player%::*} - 1)^2 / ((size of {aaac::difference::list::%player%::*} - 2) * (size of {aaac::difference::list::%player%::*} - 3))
if {_kurtosis} < {@kurtosis-max}:
alert(player, "Autoclicker F &f(Kurtosis)", "Kurtosis result: %{_kurtosis}%") # Kurtosis (veri cool).
delete {aaac::difference::list::%player%::*}
if difference between {aaac::cps::average::%player%} and {aaac::previous::cps::average::%player%} < {@difference-min}:
add 1 to {aaac::difference::flag::%player%}
if {aaac::difference::flag::%player%} >= {@difference-buffer}:
alert(player, "Autoclicker B &f(Blatant)", "Difference: %difference between {aaac::cps::average::%player%} and {aaac::previous::cps::average::%player%}%") # Very basic, meant to detect impossible/too small difference when clicking, hence why its called blatant
else:
if {aaac::difference::flag::%player%} > 0:
remove 1 from {aaac::difference::flag::%player%}
set {aaac::previous::cps::average::%player%} to {aaac::cps::average::%player%}
delete {aaac::cps::average::%player%}
add {aaac::cps::%player%} to {aaac::cps::list::%player%::*}
if size of {aaac::cps::list::%player%::*} >= 15:
loop {aaac::cps::list::%player%::*}:
add 1 to {_frequency::%rounded down loop-value%}
set {_flagged} to false
delete {aaac::cps::list::%player%::*}
loop 25 times:
if {_frequency::%loop-value%} >= 12:
add 1 to {aaac::frequency::flag::%player%}
if {aaac::frequency::flag::%player%} >= 3:
alert(player, "Autoclicker G &f(Frequency)", "Frequency: %{_frequency::%loop-value%}%/15") # This check detects small randomization over 1-2 cps.
delete {aaac::frequency::flag::%player%}
set {_flagged} to true
stop loop
if {_flagged} = false:
if {aaac::frequency::flag::%player%} > 0:
remove 1 from {aaac::frequency::flag::%player%}
add 1 to {aaac::cps::%player%}
wait 1 second
remove 1 from {aaac::cps::%player%}
on arm swing: # Worse than on left click, i made sure to only use it for a limit check.
if {aaac::armswings::%player%} > {@armswing-limit}:
add 1 to {aaac::limit::flag::%player%}
if {aaac::limit::flag::%player%} > {@armswing-buffer}:
alert(player, "Autoclicker A &f(Limit)", "Swings: %{aaac::armswings::%player%}%%nl%Limit: {@armswing-limit}") # Limit check, basic, simple, yay.
delete {aaac::limit::flag::%player%}
else:
if {aaac::limit::flag::%player%} > 0:
remove 1 from {aaac::limit::flag::%player%}
add 1 to {aaac::armswings::%player%}
wait 1 second
remove 1 from {aaac::armswings::%player%}
on join:
set {aaac::cps::%player%} to 0
set {aaac::armswings::%player%} to 0
set {aaac::flags::%player%} to 0
on quit:
# No leaving variables/lists behind to avoid performance/skript issues
# Deletion of main variables
delete {aaac::cps::%player%}
delete {aaac::armswings::%player%}
delete {aaac::flags::%player%}
# Deletion of lists
delete {aaac::cps::list::%player%::*}
delete {aaac::comparison::list::%player%::*}
delete {aaac::difference::list::%player%::*}
delete {aaac::patterns::%player%::*}
# Deletion of buffers
delete {aaac::limit::flag::%player%}
delete {aaac::frequency::flag::%player%}
delete {aaac::difference::flag::%player%}
delete {aaac::deviation::flag::%player%}
delete {aaac::rounded::flag::%player%}
delete {aaac::range::flag::%player%}
# Deletion of various other variables
delete {aaac::cps::average::%player%}
delete {aaac::previous::cps::average::%player%}