JeuWeb - Crée ton jeu par navigateur
lutter contre les scripts automatiques - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : lutter contre les scripts automatiques (/showthread.php?tid=3278)



lutter contre les scripts automatiques - zeppelin - 21-11-2008

Bonjour tout le monde!

Depuis peu, j'ai un soucis sur mon jeu (http://mystical-war.ch)... Il s'agit de script automatiques en javaScript, balancé avec des addOns firefox ou autre (greasemonkey par exemple).

Ils actualisent automatiquement une page (ou plutôt un bouton, je passe par de l'ajax) et pillent une fois la somme voulue atteinte. Ensuite hop achat direct en quelques milisecondes! :-(

J'ai écris un script qui enregistres les actions régulières et suspects, mais que puis-je faire de plus?

Merci d'avance! ;-)


RE: lutter contre les scripts automatiques - Melimelo - 21-11-2008

ou encore les actions que tu enregistres, tu les analyse aussi détermine les joueurs qui trichent les bans ou leur envoi un averto. Et s'il recommence ban définitif ...


RE: lutter contre les scripts automatiques - Seren - 21-11-2008

Est-ce que côté serveur, dans le script appelé par Ajax, tu ne peux pas mettre une protection/vérification ? Par exemple, il faut bien vérifier avant chaque achat que la somme restante est suffisante, pas se fier à une information "vieille" de quelques secondes.

Si ça ne suffit pas, tu sauvegarde une timer ou un timestamp en session : à chaque fois qu'une action est réalisée et tu le mets à T + 0.5 sec.

Tant que ce timer n'est pas passé ça rejette l'action, ça limite à deux actions par secondes. ( soit pour toutes les actions, soit pour une action particulière genre achat ).

Ensuite à toi de régler la durée de ce timer..

Code :
// en (très très) pseudo code :)

global $TimerLimit;

if (time < $TimerLimit)
{  
   return error;
}
else
{
   $TimerLimit = time() + 0.5;
   DoAction();
   return success;
}

En logiciel bas niveau, on met souvent des timer très court "anti-rebond" sur des ports d'interruptions, ça évite qu'un signal d'interruption qui varient rapidement et déclenchent dix fois l'appel à la routine d'interruption qu lieu d'une seule fois.


RE: lutter contre les scripts automatiques - Ter Rowan - 21-11-2008

je ne sais pas si dans l'exemple présenté, le captcha convienne. En effet on ne va pas demander à un joueur de lire/écouter/.... à chaque action de sa part

Là on est dans le cas où le joueur s'est identifié dans le jeu puis lance un bot

Perso - je suis sûr que j'ai fait n'importe quoi mais je me lance-, développant aussi en Ajax, j'ai mis en place un "verrou" logique pour certains types d'interraction.

Ex :

se déplacer = utilisation du verrou

manger = utilisation du verrou

afficher une partie de l'inventaire = pas de verrou

ramasser quelque chose par terre si ça ne consomme pas de temps ou des réserves limitées = pas de verrou (pas encore fait mais comme je ne ramasse que des "id", pas besoin)

ramasser quelque chose par terre si ça consomme du temps ou des réserves limitées = verrou (là y a pas d'id pour les réserves)

créer un objet = verrou

grosso modo tout ce qui "consomme" ou "génère" quelque choseest "verrouillé"

Alors ce que j'appelle Verrou c'est simplement d'empêcher le joueur de faire une action verrouillable avant que la précédente action verrouillable ne soit terminée. Comme je suis en asynchrone, je ne me base pas sur le client mais sur le serveur

mon système est simple (et probablement foireux)

dans la table personnage, j ai un champ "verrou" qui porte la valeur 0 si pas de verrou et un nombre aléatoire sinon.

chaque lancement d'action verrouillable fonctionne ainsi :

1) le joueur lance l'action
2) le client lance un premier ordre ajax pour demander le verrou
3.1) si le verrou du personnage est disponible, la bdd est mise à jour (un entier aléatoire) et le serveur donne en réponse ajax la valeur du verrou
3.2) si le verrou du personnage est indisponible (la valeur n'est pas à 0) le serveur donne un refus en réponse ajax
4) si le retour ajax est accepté, le client lance un second ordre ajax pour demander l'action, en donnant la valeur du verrou
5) le serveur recoit un ordre d'action avec son verrou, il teste si le verrou est correct, si oui lance l'action et répond, si non, ne fait rien
6) une fois le retour de l'action réalisée, le client lance le troisième ordre ajax, demandant de déverouiller le personnage (en donnant la valeur du verrou)
7) le serveur identifie si le verrou est le bon, si c'est le cas, met à 0 le verrou, ne fait rien sinon.

bon après un peu de temps à utiliser ce système je me demande si il est utile de lancer trois aller retours ajax (verrouillage , action, déverrouillage) ou si il ne suffit pas de verrouiller/déverrouiller directement dans les scripts d'action. L'idée de départ était de ne pas solliciter le serveur avec des "gros scripts php". Les scripts de verrouillage et déverrouillage doivent faire 10-15 lignes chacun, contrairement aux scripts possibles pour les diverses actions

à noter ça a l air de pas trop mal marcher, dès que je suis sur un bug, une action testée interdite, etc... le personnage est complètement verrouillé. Et surtout rien n'est posé côté client, tout est côté serveur

mais il y a peut être énormément de failles, à voir avec vous


RE: lutter contre les scripts automatiques - orditeck - 21-11-2008

Je dirais comme oxman... tu pourrais mettre un système de captcha mais seulement si tu trouves des actions louches sur le compte.


RE: lutter contre les scripts automatiques - Ter Rowan - 21-11-2008

bah c'est ce que je dis le captcha c'est bien à l'inscription, mais on va pas mettre du captcha a chaque action

ça me paraît anti game play au possible


RE: lutter contre les scripts automatiques - Zamentur - 21-11-2008

Ter Rowan a écrit :bon après un peu de temps à utiliser ce système je me demande si il est utile de lancer trois aller retours ajax (verrouillage , action, déverrouillage) ou si il ne suffit pas de verrouiller/déverrouiller directement dans les scripts d'action. L'idée de départ était de ne pas solliciter le serveur avec des "gros scripts php". Les scripts de verrouillage et déverrouillage doivent faire 10-15 lignes chacun, contrairement aux scripts possibles pour les diverses actions
Et t'as raison de te poser la question!
Il vaut mieux mettre un appel à tes fonction verrouiller déverouiller au début et à la fin des partie de script posant problème.
Parce que si tu lance une requete ajax pour vérouiller
puis une autre poiyr avoir la page
puis encore une autre pour déverrouiller

Et bien tu vas avoir des temps d'attente quand tu sera en serveur de production, car ta requete HTTP devra arriver jusqu'au serveur et revenir ce qui peut prendre jusqu'à 3 secondes...
Soit 9 secondes!!!!

La table gérant les vérou devrait etre une table de type memory, et non myisam ou innodb. Ainsi cette table sera toujours en mèmoire RAM, et donc accessible très rapidement. car il ne faut pas oublier qu'une requete c'est long. En plus çà te permetra de savoir qui est connecté au site ou non.


RE: lutter contre les scripts automatiques - keke - 21-11-2008

Ter rowan, je réagis sur ce point :

Citation :ramasser quelque chose par terre si ça ne consomme pas de temps ou des réserves limitées = pas de verrou (pas encore fait mais comme je ne ramasse que des "id", pas besoin)

Supposons que joueur A et joueur B veulent récupérer un objet à terre (une arme).
Joueur A se penche et prend l'arme, pendant ce temps, joueur B ne raffraichit pas sa page.
Joueur A se barre très loin (vend l'arme a un marchand). Quelques instants plus-tard, Joueur B se réveille et se penche pour récuperer l'arme qu'il a devant lui (il avait pas rafraichit sa page, il peut donc cliquer). Si rien n'est fait pour protéger l'action ... il risque de voler l'arme au marchand.
Dans ce cas, on se rend compte que les ID peuvent aussi générer des anomalies ^^.

La notion de verrou me semble donc à la fois techniquement délicate et en même temps difficilement applicable tout le temps.

Le pseudo-ce de Seren me semble une alternative bien plus adapté à tes différents cas. Si tu veux interdire à un joueur de combattre de manière trop rapproche (l'effet de la touche F5 par exemple), il suffit d'enregistrer la donnée statique : heure_dernier_combat; puis à chaque assaut vérifier que la date système n'est pas inférieur à heure_dernier_combat + 1h par exemple. Si c'est le cas, indiquer au joueur qu'il est trop fatigué pour attaquer, que ses tourelles n'ont pas eue le temps de refroidir ...

Kéké qui jalouse un peu ceux qui manient aussi bien l'AJAX ^^. On m'a suggéré aujourd'hui des modifs pour mon Tchat, mais techniquement je vais avoir du mal à y répondre.


A - Ter Rowan - 21-11-2008

keke, non ton cas ne marche pas (enfin, dans ma situation)

en effet il y a deux contrôles :

1) les verrous en cas d'action impactante si multiplié (j'attaque plusieurs fois l'adversaire)

2) les contrôles de "propriétés"
typiquement si je prends un objet au sol c'est que l'objet est au sol et que je suis sur le même lieu que l'objet

ainsi

si A et B arrivent sur le même lieu et voient les deux la même épée

si A donne l'ordre de prendre l'épée en premier, le contrôle dit que l'épée est au sol, l'action se réalise, l'épée va chez A

si B donne l'ordre de prendre l'épée après A, le contrôle dit que l'épée n'est plus au sol, donc l'action ne se réalise pas, donc l'épée reste chez A

grosso modo, je ne calcule rien chez le client, celui ci donne des "ordres" si ces ordres sont faux il ne se passe rien (bon sauf faille de ma part)

maintenant dans le cas d'accès quasi simultané, on dira que c'est le dernier qui a parlé

si A et B on les contrôles ok, alors c'est le dernier update qui a raison :

l'épée considérée a un id qui est unique dans la table des ressources
et ne peut être qu'à un endroit à la fois


ce que je me demandais c'était si j'implémentais un truc du genre :

"vous voyez A prendre l'épée au sol"

mais bon ça m a l air couteux même pour l'avancement de mon projet (en dehors de la charge serveur / volume)


RE: lutter contre les scripts automatiques - Ter Rowan - 21-11-2008

Zamentur a écrit :La table gérant les vérou devrait etre une table de type memory, et non myisam ou innodb. Ainsi cette table sera toujours en mèmoire RAM, et donc accessible très rapidement. car il ne faut pas oublier qu'une requete c'est long. En plus çà te permetra de savoir qui est connecté au site ou non.

et mer...credi encore un nouveau truc à comprendre.... tsssss ^^