La pavé de ma vision sur l'anti bot et son fonctionnement

Inscrit
23 Janvier 2019
Messages
2
J'aime
3
#21
Dofus semble faire de l'analyse comportementale.
Un exemple qui se trouve dans le LuaFormulas

Code:
{
        "id": 18,
        "formulaName": "antibot_money_transfer_limitation",
        "luaFormula": ""
    },
Code:
function params()
    return 
end

function main()  
    return getLimitation(no_limit_flag, 10, 3000000, 4, 10, 2, best_character_level, played_time, subscribed_once)
end

function getLimitation( no_limit_flag, level_range, level_range_boost, level_max_ratio, played_time_expectation, subscription_boost_ratio, best_character_level, played_time, subscribed_once )
    -- Compute level ratio based on the level range, for the best character of an account, on a specific server
    assert(best_character_level > 0, "Best character level must be gt. 0");
    assert(level_range > 0, "Level range must be gt. 0");
    local raw_level_best_character_ratio = best_character_level / level_range;
    -- Compute cross-server cumulated account played time ratio based on a defined played time reference
    assert(played_time_expectation >= 0, "Cumulated played time must be ge. 0");
    assert(played_time >= 0, "Played time must be ge. 0")
    local raw_played_time_ratio = 0;\n  
    if played_time_expectation ~= 0 then
        raw_played_time_ratio = played_time / played_time_expectation;
    end\
    -- Check whether the player should have money transfer limitation or not
    assert(level_max_ratio >= 0, "Level max ratio must be ge. 0");
    assert(subscribed_once ~= nil, "Subscription status can not be nil");
    if (raw_level_best_character_ratio >= level_max_ratio ) and (raw_played_time_ratio >= 1) and subscribed_once then
        return no_limit_flag;
    end
    -- Compute boost, for the best character of an account, on a specific server
    local best_character_level_ratio = math.min(level_max_ratio, raw_level_best_character_ratio);
    assert(best_character_level_ratio > 0 and best_character_level_ratio <= level_max_ratio);
    assert(level_range_boost >= 0, "Level range boost must be ge. 0");
    local raw_best_character_level_boost = best_character_level_ratio * level_range_boost;
    local best_character_level_boost = math.max(0, raw_best_character_level_boost);
    -- Compute money transfer limit
    local raw_limit = level_range_boost + best_character_level_boost;
    local played_time_ratio = 1 + math.min(1, raw_played_time_ratio);
    raw_limit = raw_limit * played_time_ratio;
    assert(subscription_boost_ratio >= 1, "Subscription boost ratio must be ge. 1");
    if subscribed_once then
        raw_limit = raw_limit * subscription_boost_ratio;
    end
    local limit = math.max(no_limit_flag, raw_limit);
    assert(limit >= level_range_boost);
    return limit;
end
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
1 845
J'aime
213
#23
Le problème c'est que l'anti-bot ne peut pas avoir une vision très long terme, ça demande de l'espace pour stocker autant d'infos. Quelqu'un qui farm plusieurs heures d'affilés sans rien faire d'autres, c'est totalement possible. Quelqu'un qui connecte son bot manuellement peut parler à un joueur, faire une pause AFK, un échange avec un joueur, ... et puis le bot peut reprendre
Je ne suis pas d'accord,
Qu'est ce que ça coute d'avoir quelques variables en plus par compte sur la bdd ?
Le RDM consommait bien plus d'espace.
 
Inscrit
23 Janvier 2016
Messages
21
J'aime
5
#24
C'est obligé que ça soit du ML, c'est une simple classification qu'ils font : "bot" ou "pas bot" (un %).
et le ML est extrêmement fort pour faire ça, presque certain qu'un knn sur la fréquence par type de paquets reçus permet de détecter un bot au bout d'un certain temps... inutile de dire qu'il y a bien mieux maintenant, genre réseaux neuronaux

Très grossièrement (jsuis pas du domaine) : t'as des couches de neurones "layers" reliés entre eux. Les neurones de la première couche prenent des données brutes en entrée les autres couches prennent une combinaison des sorties des neurones de la couche précedente, et ce jusqu'à obtenir la sortie voulue. Chaque neurone correspond à une fonction f(x1,x2,x3,...,xn), qui sort une valeur correspondant à son activation. Le plus basique est le perceptron : un neurone qui correspond à un polynome de degré n qui sort 0 ou 1. (ex. f(x1,..,xn) = {1 si x1<5, 0 sinon} est un perceptron). Et c'est à peu près tout.

Ces fonctions sont "règlables", pour les régler on va mettre en entrée du réseau des paramètres, en sortie la sortie souhaité pour ces paramètres, et on va modifier les paramètres d'activation des neurones (leur fonction) pour que la sortie corresponde à l'entrée. C'est ce qu'on appelle l'entrainement.
ex. f(x1,..,xn) = {1 si x1<5, 0 sinon} peut être la fonction lié à un neurone après la première donnée, ensuite au bout de quelques données on pourrait se retrouver avec f(x1,..,xn) = {1 si (1 + 3*x1 + 2*x3) <18, 0 sinon}
Ici on peut mettre en entrée des statistiques sur les paquets, les infos du joueur, etc..
ça peut aller du temps moyen entre 2 actions à "isEmailValid", "isActiveInGuild", "nbInvalidSerializedPackets", etc..
les données, Ankama a du en récolter pas mal depuis le temps qu'ils nous bannissent.

Niveau stockage & calcul, on a pas besoin de stocker les données brutes, des statistiques suffisent, et on a pas besoin de temps réel. J'vois bien une archi avec apache kafka, etc..

Maintenant, si c'est bien du réseau de neurones, l'idée serait de pouvoir le tromper, et là ça risque d'être complexe mdr.
Dans le principe "tromper un réseau de classification" c'est les réseaux antagonistes, genre GAN

Inventé par Ian Goodfellow en genre 2015, le principe est d'avoir 2 réseaux de neurones : le premier est un réseau de classification entraîné, le second un algo qui génère qqch, et qui prend une entrée spéciale : la récompense, son but est de maximiser la récompense.
Et le concept est : on branche la sortie du second dans l'entrée du premier, et la sortie du premier sur la récompense du second.
Le second est entraîné à tromper le premier.

Exemple : on entraine le premier à reconnaître des visages humains, le second à générer des images à partir de bruit (image générée aléatoirement), entraîné pour avoir le meilleur score sur le premier (== générer des visages), et ça donne ça : https://thispersondoesnotexist.com/

Même si l'application qu'on va plus chercher à atteindre c'est ça : https://cdn-images-1.medium.com/max/2600/1*PmCgcjO3sr3CPPaCpy5Fgw.png on génère, sur une entrée du réseau 1 classique, un bruit qui utilise l'imprécision des poids du réseau de neurones pour changer la sortie.

Et pour faire ça sans Ankama, c'est impossible.

Après éventuellement, un truck sympa c'est entraîner un réseau de classification avec des données de jeu "non ban" et "ban" récoltées avec un sniffer par exemple. Ensuite, avant d'envoyer un paquet avec le bot, il faut le faire passer dans la classif, et ne pas l'envoyer si la sortie est "ban", ou même alerter si le % de chance de "ban" est supérieur à 40% et augmente par exemple.
 
Dernière édition:
Haut Bas