Python Présentation d'un bot atypique

Inscrit
1 Juin 2020
Messages
43
Reactions
29
#1
Bonjour à tous.

Après de nombreux mois ( 9 pour etre précis) je suis heureux de pouvoir faire un petit post de présentation d'un bot que j'ai codé entièrement seul sur mon temps libre. Avant toute chose quelques disclaimers :
1 : Je ne suis pas informaticien. Je fais ça par passion avant toute chose et parce que ce domaine me passionne. Mon approche est clairement non optimisée et très certainement beaucoup d'entres vous auraient fait mieux.
2 : Si vous avez des suggestions sur les méthodes que j'emploie ou des remarques a faire, je serai très heureux de les lire
3 : L'objectif de ce post est simplement de partager ma joie et mon engouement avec des gens suceptibles d'etre intéréssés !
4 : Pour des raisons de référencement ( et au cas ou ) CaT désigne ce que l'on fait dans D0ufs pour trouver un coffre qui a des dents

1 - Description du projet

Il s'agit d'un bot CaT codé en Python, n'utilisant pas la moindre interprétation de paquet. Toutes les informations sont lues, et réalisées via des méthodes les plus "human like" possibles. Cela diminue certes l'efficacité, mais a l'interet majeur d'etre ( selon moi ) parfaitement indétectable. Le principe est l'utilisation de la détection d'image basique couplé a des entrées clavier/souris élémentaires pour perform du début a la fin une CaT. Les CaT étant déclinées en 3 grandes étapes, la suite de ce post servira a expliciter mon cheminement en espérant que cette brève introduction vous ait intéréssé.

2 - Outils utilisés pour les actions basiques

Les entrées clavier/souris :

Initialement je m'étais servi de la librairie d'AutoIt 3 très facilement implémentable en Python via pyAutoIt. Cette librairie permet l'interaction avec des "Controls". L'objectif étant de pouvoir avoir un programme qui fonctionne avec des inputs clavier/souris basique sans pour autant monopoliser l'ordinateur. Les fonctions de click et de send sur Control d'AutoIt fonctionnait de façon relativement irrégulière ( la fenetre du jeu étant en soit dépourvue de control concret ). Le désavantage majeur de ces fonctions est qu'elles ont ( et on me corrigera si je dis de la merde ) une espèce de "focus" propre ( je sais pas comment dire ça ). Mais typiquement, pour copier/coller un message dans le chat, on s'attendrait a simplement faire un clic dans le chat, puis Ctrl A + Ctrl X. Cependant, après le ControlClick, le focus de la fenetre du jeu est "reset" et les entrées clavier qui suivent ne vont pas dans le chat, mais directement dans la fenetre. ( Donc on ouvre l'interface alliance par exemple ).
Pour remédier a ce problème j'ai donc opté pour des fonctions beaucoup plus "bas niveau" si je puis dire de SendMessage et PostMessage avec des codes Hexa. Cela a le mérite d'etre non seulement moins irrégulier et beaucoup plus fiable , mais de permettre un total fonctionnement en background.

La capture d'image :

Le fonctionnement du bot se faisant en background, le répérage d'image doit lui aussi se faire en background. Pour se faire j'ai opté pour la fonction PrintWindow qui permet a partir du handle de la fenetre d'en obtenir une capture d'écran. Ceci dit, il est a noté que la fenetre ne doit pas etre minimisée pour que cette fonction puisse opérer. Une simple modification de l'état de la fenetre a priori permet d'ignorer cette limite.

Et ... c'est tout .. Vu que l'approche était human like, j'avais besoin que le soft soit capable de voir , cliquer et écrire.. Il ne lui reste plus qu'a réfléchir...

3 - Arriver sur la map de départ

Si on ignore les étapes assez simples pour arriver dans la malle, l'obtention de la map de départ se fait elle aussi en capture d'image. Après avoir standardisé la position de la map ( via un dézoom et un recadrage pour etre sur de voir a la fois B0nTA et Brak ) j'ai fais un template matching avec openCV pour rechercher le jalon de départ. Un shift clic et la position se retrouve dans mon chat que je vais copier coller ( via postMessage ) . J'analyse ensuite mon presse papier pour connaitre X et Y. Ensuite via une List de tuple contenant le nom, et les coordonnées de tous les zaaps du jeu, je crée un MinHeap dans lequel j'enregistre la différence de maps entre la map de départ et la position pour savoir quel est le zaap le plus proche. Une fois ceci fait , HavreSac > Zaap > Clic > Entrée du nom de ce zaap le plus proche. Par la suite un "/clear" et un "/travel X Y" me permettent alors d'arriver sur la map de départ. ( Le /clear sert a détecter le message m'indiquant etre arrivé )

4 - Réaliser la CaT

Une fois sur la map de départ commence un processus assez complexe de "lecture". Comme on peut s'y attendre j'ai utilisé Tesseract via un outil nommé Capture2Text. Je fais donc un screenshot de la fenetre, que je crop pour le faire correspondre au premier hint. Je lis ensuite cet indice avec C2T qui me donne un string ressemblant plus ou moins au vrai hint. Ma réso de base étant de 800 x 600 pour réduire le stress du GPU, les mots lus sont parfois très très loin du hint recherché. Je compare donc le string obtenu avec un dictionnaire de tous les hints du jeu via la distance de levenshtein et j'en conclus que celui qui a la plus courte correspond au hint a chercher. J'ai a priori téléchargé toute la base de données d'indice d'un site d'indice, ce qui me permet d'avoir un fichier texte de plus de 35 000 positions d'indices que je charge lors de l'exécution. De ce fait , le programme sait d'ores et déjà des qu'il lit un indice, ou il se trouve. Il se rend alors sur cette map et valide l'indice. Rien de compliqué. La difficulté arrive pour les taupes (on va les appeler comme ça .. )

Trouver les taupes :

Pour trouver les taupes , j'ai commencé par les screenshots dans toutes les orientations. J'ai découpé le fond le et appliquer un masque pour que le template matching d'openCV ignore le contexte des taupes. Elles sont alors détectées quelque soit la map. Seul problème quand on en voit qu'une partie du corps ou quoi. Mais j'ai ma solution pour ça. En couplant l'application d'un masque a openCV et en configurant correctement les cutoffs de détection, a l'heure actuelle, mon bot n'ignore jamais une taupe si elle est visible a l'écran ( chose dont je m'assure en masquant l'HUD quand on en cherche une

5 - Gagner le combat

On arrive a la partie , de très loin , la plus complexe et celle qui m'a pris le plus de temps.

La première étape est l'analyse des cases disponibles et non disponibles de la map. Pour se faire j'analyse en boucle toutes les cases de la map et j'en analyse la couleur ce qui me permet ensuite de créer un Set() d'objet Cellules qui me permet de savoir si elles sont accessibles ou pas.

Ensuite dans un combat est de savoir ou l'on se trouve et ou se trouve l'ennemi. Sur ce point précis, openCV et le template matching ont été pris en très grand défaut pour une raison simple. Tout template matching, quelqu'en soit la méthode doit a priori etre fait sur une échelle de gris. Le combat étant en mode créature pour standardiser la détection d'image, on se rend assez vite compte que le mode créa d'un mob et le mode créa d'un perso ( en échelle de gris ) se ressemble énormément. Il n'était donc pas rare que le bot inversent les deux et prennent mon perso pour l'ennemi et vice versa.

Pour contrer ça, dans l'analyse des cases pour savoir si elles sont pratiquables, je réalise en meme temps une analyse de 40x40 pixels autour du centre de la case. Cette analyse sert a comparer les pixels de ce rectangle avec la couleur des pixels connus de l'ennemi et de mon perso. En effet j'ai a priori extrait via un script externe un array de tous les pixels discriminants de mon perso et de l'ennemi via des screenshots dans toutes les directions.

De ce fait en meme temps que l'analyse des cases, le code vérifie si mon personnage ou l'ennemi se trouve sur cette case en comptant les pixels communs avec les pixels connus. A la fin de l'exécution il enregistre les cases qui avaient le plus de pixels communs. Cela a l'avantage colossal comparé a une détection d'image openCV d'ingorer si le personnage est coupé par un élément du décor .

Cette méthode est garantie et jamais le bot ne s'est trompé dans la position de l'ennemi et de mon personnage. On pourrait croire que cela prend du temps mais avec un travail d'optimisation approfondi, notamment via l'utilisation de Heaps, de Set() plutot que des Lists et autre, il faut moins de 5 secondes au programme pour analyser toutes les cases et savoir ou sont les personnages.
1603812386959.png
La meme méthode est utilisée par la suite mais sans analyser la praticabilité de toutes les cases. Ce qui fait que détecter personnage et ennemi prend moins d'une demi seconde.

Maintenant qu'on sait ou sont les protagonistes du combat, il s'agit de faire se déplacer mon personnage pour aller taper l'ennemi.

Pour se faire j'utilise le célibrissime algorithme A star ( A*). Je n'irai pas en détail mais cet algorithme permet de trouver le chemin le plus court possible vers une cible. A tous ceux qui s'y aventurent , prenez garde a bien chronométrer vos différentes étapes pour ne pas avoir un pathfinding qui prennent 3000 ans. Le gif suivant illustre la méthode de l'algorithme dans mon programme. (cf, dans sa première version, ce pathfinding prenait environ 277 secondes ... Comme quoi , avoir un code optimisé c'est assez utile xD )



Ainsi a chaque tour, on détecte le nombre de PM de notre perso et on clique sur la PM-ième case de notre path pour se déplacer.. puis on tape .. et on fait ça jusqu'a la fin .. Et voila , le tour est joué, plus qu'a faire ça en boucle.

6 - Limites et conclusion
.
Vous vous doutez évidemment qu'il y a pas mal de limites a ce fonctionnement. Certaines choses seraient bien plus optimisées si j'avais les connaissances requises pour les faire. Je pourrais par exemple avoir un world path finding ou détecter via l'interprétation de paquet la position de l'ennemi. Bien plus de choses seraient accessibles via l'interprétation de paquets et je compte les ajouter quand j'en aurai le temps.

J'ai appris le python pour créer ce projet ( il y a maintenant 2 mois que je code en python et les 7 d'avant j'apprenais le javascript parce que de base ce projet était sous Actionaz .. ) a partir de connaissances éparses en C, Java .. C'est mon premier projet de "grande ampleur" ( a mon échelle ) et tout commentaire, idée ( ou meme de l'aide pour enfin comprendre ces satanés paquets ... ) est bienvenu.

Cordialement
 
Inscrit
19 Avril 2020
Messages
2
Reactions
1
#2
Félicitations !
Bon courage pour la suite, j’espère avoir des nouvelles.
 
Inscrit
18 Juillet 2018
Messages
2
Reactions
1
#5
Salut valchimiiste et félicitations !

Je trouve ça génial parce que j'ai fait exactement la même chose sur mon temps libre mais en C# ! Quand je dis exactement la même chose, c'est quasiment au mot près ! Mais je ne l'utilise plus puisque je ne joue plus en ce moment..
 
Inscrit
1 Juin 2020
Messages
43
Reactions
29
#6
Gg bonne chance pour la suite.
Merci beaucoup !

Je trouve ça génial parce que j'ai fait exactement la même chose sur mon temps libre mais en C# ! Quand je dis exactement la même chose, c'est quasiment au mot près ! Mais je ne l'utilise plus puisque je ne joue plus en ce moment..
Haha . Comme quoi suffit d'avoir les idées héhé. Maintenant j'aimerais rajouter de quoi acquérir les informations via les paquets mais ça ce sera dans un prochain épisode vu que j'y arrive pas pour l'instant haha.

Merci pour les encouragements !
 
Inscrit
27 Septembre 2016
Messages
3
Reactions
3
#7
Super projet ! Je suis en train de faire quasiment la même chose en python aussi ! J'utilise uniquement Tesseract pour le moment :D

Par contre j'ai cherché (comme toi) pour obtenir une base de tous les indices avec les positions mais en vain... Un indice de où tu l'as obtenue ?
 
Inscrit
1 Juin 2020
Messages
43
Reactions
29
#8
Sur un site d'indiçage bien connu. Tu l'as certainement déjà utilisé :) . Je peux pas en dire plus ^_^'
 
Inscrit
27 Septembre 2016
Messages
3
Reactions
3
#9
Oui je vois !
Mais je parlai plus dans la manière de faire :D
Je vais me débrouiller :)
 
Inscrit
2 Novembre 2020
Messages
1
Reactions
0
#10
Bonjour à tous.

Après de nombreux mois ( 9 pour etre précis) je suis heureux de pouvoir faire un petit post de présentation d'un bot que j'ai codé entièrement seul sur mon temps libre. Avant toute chose quelques disclaimers :
1 : Je ne suis pas informaticien. Je fais ça par passion avant toute chose et parce que ce domaine me passionne. Mon approche est clairement non optimisée et très certainement beaucoup d'entres vous auraient fait mieux.
2 : Si vous avez des suggestions sur les méthodes que j'emploie ou des remarques a faire, je serai très heureux de les lire
3 : L'objectif de ce post est simplement de partager ma joie et mon engouement avec des gens suceptibles d'etre intéréssés !
4 : Pour des raisons de référencement ( et au cas ou ) CaT désigne ce que l'on fait dans D0ufs pour trouver un coffre qui a des dents

1 - Description du projet

Il s'agit d'un bot CaT codé en Python, n'utilisant pas la moindre interprétation de paquet. Toutes les informations sont lues, et réalisées via des méthodes les plus "human like" possibles. Cela diminue certes l'efficacité, mais a l'interet majeur d'etre ( selon moi ) parfaitement indétectable. Le principe est l'utilisation de la détection d'image basique couplé a des entrées clavier/souris élémentaires pour perform du début a la fin une CaT. Les CaT étant déclinées en 3 grandes étapes, la suite de ce post servira a expliciter mon cheminement en espérant que cette brève introduction vous ait intéréssé.

2 - Outils utilisés pour les actions basiques

Les entrées clavier/souris :

Initialement je m'étais servi de la librairie d'AutoIt 3 très facilement implémentable en Python via pyAutoIt. Cette librairie permet l'interaction avec des "Controls". L'objectif étant de pouvoir avoir un programme qui fonctionne avec des inputs clavier/souris basique sans pour autant monopoliser l'ordinateur. Les fonctions de click et de send sur Control d'AutoIt fonctionnait de façon relativement irrégulière ( la fenetre du jeu étant en soit dépourvue de control concret ). Le désavantage majeur de ces fonctions est qu'elles ont ( et on me corrigera si je dis de la merde ) une espèce de "focus" propre ( je sais pas comment dire ça ). Mais typiquement, pour copier/coller un message dans le chat, on s'attendrait a simplement faire un clic dans le chat, puis Ctrl A + Ctrl X. Cependant, après le ControlClick, le focus de la fenetre du jeu est "reset" et les entrées clavier qui suivent ne vont pas dans le chat, mais directement dans la fenetre. ( Donc on ouvre l'interface alliance par exemple ).
Pour remédier a ce problème j'ai donc opté pour des fonctions beaucoup plus "bas niveau" si je puis dire de SendMessage et PostMessage avec des codes Hexa. Cela a le mérite d'etre non seulement moins irrégulier et beaucoup plus fiable , mais de permettre un total fonctionnement en background.

La capture d'image :

Le fonctionnement du bot se faisant en background, le répérage d'image doit lui aussi se faire en background. Pour se faire j'ai opté pour la fonction PrintWindow qui permet a partir du handle de la fenetre d'en obtenir une capture d'écran. Ceci dit, il est a noté que la fenetre ne doit pas etre minimisée pour que cette fonction puisse opérer. Une simple modification de l'état de la fenetre a priori permet d'ignorer cette limite.

Et ... c'est tout .. Vu que l'approche était human like, j'avais besoin que le soft soit capable de voir , cliquer et écrire.. Il ne lui reste plus qu'a réfléchir...

3 - Arriver sur la map de départ

Si on ignore les étapes assez simples pour arriver dans la malle, l'obtention de la map de départ se fait elle aussi en capture d'image. Après avoir standardisé la position de la map ( via un dézoom et un recadrage pour etre sur de voir a la fois B0nTA et Brak ) j'ai fais un template matching avec openCV pour rechercher le jalon de départ. Un shift clic et la position se retrouve dans mon chat que je vais copier coller ( via postMessage ) . J'analyse ensuite mon presse papier pour connaitre X et Y. Ensuite via une List de tuple contenant le nom, et les coordonnées de tous les zaaps du jeu, je crée un MinHeap dans lequel j'enregistre la différence de maps entre la map de départ et la position pour savoir quel est le zaap le plus proche. Une fois ceci fait , HavreSac > Zaap > Clic > Entrée du nom de ce zaap le plus proche. Par la suite un "/clear" et un "/travel X Y" me permettent alors d'arriver sur la map de départ. ( Le /clear sert a détecter le message m'indiquant etre arrivé )

4 - Réaliser la CaT

Une fois sur la map de départ commence un processus assez complexe de "lecture". Comme on peut s'y attendre j'ai utilisé Tesseract via un outil nommé Capture2Text. Je fais donc un screenshot de la fenetre, que je crop pour le faire correspondre au premier hint. Je lis ensuite cet indice avec C2T qui me donne un string ressemblant plus ou moins au vrai hint. Ma réso de base étant de 800 x 600 pour réduire le stress du GPU, les mots lus sont parfois très très loin du hint recherché. Je compare donc le string obtenu avec un dictionnaire de tous les hints du jeu via la distance de levenshtein et j'en conclus que celui qui a la plus courte correspond au hint a chercher. J'ai a priori téléchargé toute la base de données d'indice d'un site d'indice, ce qui me permet d'avoir un fichier texte de plus de 35 000 positions d'indices que je charge lors de l'exécution. De ce fait , le programme sait d'ores et déjà des qu'il lit un indice, ou il se trouve. Il se rend alors sur cette map et valide l'indice. Rien de compliqué. La difficulté arrive pour les taupes (on va les appeler comme ça .. )

Trouver les taupes :

Pour trouver les taupes , j'ai commencé par les screenshots dans toutes les orientations. J'ai découpé le fond le et appliquer un masque pour que le template matching d'openCV ignore le contexte des taupes. Elles sont alors détectées quelque soit la map. Seul problème quand on en voit qu'une partie du corps ou quoi. Mais j'ai ma solution pour ça. En couplant l'application d'un masque a openCV et en configurant correctement les cutoffs de détection, a l'heure actuelle, mon bot n'ignore jamais une taupe si elle est visible a l'écran ( chose dont je m'assure en masquant l'HUD quand on en cherche une

5 - Gagner le combat

On arrive a la partie , de très loin , la plus complexe et celle qui m'a pris le plus de temps.

La première étape est l'analyse des cases disponibles et non disponibles de la map. Pour se faire j'analyse en boucle toutes les cases de la map et j'en analyse la couleur ce qui me permet ensuite de créer un Set() d'objet Cellules qui me permet de savoir si elles sont accessibles ou pas.

Ensuite dans un combat est de savoir ou l'on se trouve et ou se trouve l'ennemi. Sur ce point précis, openCV et le template matching ont été pris en très grand défaut pour une raison simple. Tout template matching, quelqu'en soit la méthode doit a priori etre fait sur une échelle de gris. Le combat étant en mode créature pour standardiser la détection d'image, on se rend assez vite compte que le mode créa d'un mob et le mode créa d'un perso ( en échelle de gris ) se ressemble énormément. Il n'était donc pas rare que le bot inversent les deux et prennent mon perso pour l'ennemi et vice versa.

Pour contrer ça, dans l'analyse des cases pour savoir si elles sont pratiquables, je réalise en meme temps une analyse de 40x40 pixels autour du centre de la case. Cette analyse sert a comparer les pixels de ce rectangle avec la couleur des pixels connus de l'ennemi et de mon perso. En effet j'ai a priori extrait via un script externe un array de tous les pixels discriminants de mon perso et de l'ennemi via des screenshots dans toutes les directions.

De ce fait en meme temps que l'analyse des cases, le code vérifie si mon personnage ou l'ennemi se trouve sur cette case en comptant les pixels communs avec les pixels connus. A la fin de l'exécution il enregistre les cases qui avaient le plus de pixels communs. Cela a l'avantage colossal comparé a une détection d'image openCV d'ingorer si le personnage est coupé par un élément du décor .

Cette méthode est garantie et jamais le bot ne s'est trompé dans la position de l'ennemi et de mon personnage. On pourrait croire que cela prend du temps mais avec un travail d'optimisation approfondi, notamment via l'utilisation de Heaps, de Set() plutot que des Lists et autre, il faut moins de 5 secondes au programme pour analyser toutes les cases et savoir ou sont les personnages.
Afficher la pièce jointe 453
La meme méthode est utilisée par la suite mais sans analyser la praticabilité de toutes les cases. Ce qui fait que détecter personnage et ennemi prend moins d'une demi seconde.

Maintenant qu'on sait ou sont les protagonistes du combat, il s'agit de faire se déplacer mon personnage pour aller taper l'ennemi.

Pour se faire j'utilise le célibrissime algorithme A star ( A*). Je n'irai pas en détail mais cet algorithme permet de trouver le chemin le plus court possible vers une cible. A tous ceux qui s'y aventurent , prenez garde a bien chronométrer vos différentes étapes pour ne pas avoir un pathfinding qui prennent 3000 ans. Le gif suivant illustre la méthode de l'algorithme dans mon programme. (cf, dans sa première version, ce pathfinding prenait environ 277 secondes ... Comme quoi , avoir un code optimisé c'est assez utile xD )



Ainsi a chaque tour, on détecte le nombre de PM de notre perso et on clique sur la PM-ième case de notre path pour se déplacer.. puis on tape .. et on fait ça jusqu'a la fin .. Et voila , le tour est joué, plus qu'a faire ça en boucle.

6 - Limites et conclusion
.
Vous vous doutez évidemment qu'il y a pas mal de limites a ce fonctionnement. Certaines choses seraient bien plus optimisées si j'avais les connaissances requises pour les faire. Je pourrais par exemple avoir un world path finding ou détecter via l'interprétation de paquet la position de l'ennemi. Bien plus de choses seraient accessibles via l'interprétation de paquets et je compte les ajouter quand j'en aurai le temps.

J'ai appris le python pour créer ce projet ( il y a maintenant 2 mois que je code en python et les 7 d'avant j'apprenais le javascript parce que de base ce projet était sous Actionaz .. ) a partir de connaissances éparses en C, Java .. C'est mon premier projet de "grande ampleur" ( a mon échelle ) et tout commentaire, idée ( ou meme de l'aide pour enfin comprendre ces satanés paquets ... ) est bienvenu.

Cordialement
Coucou j'adore l'idée du projet ! Bien joué à toi, as tu Discord pour discuter avec toi ?
Si oui, est-ce possible de m'ajouter ? Wiik#0915
 
Inscrit
7 Mai 2020
Messages
10
Reactions
7
#12
Beau boulot, je serais curieux de voir un combat contre des monstres
 
Inscrit
27 Septembre 2019
Messages
17
Reactions
3
#13
Hello,
J'avais eu cette même idée, et pour éviter un maximum les erreurs (et moins m'embêter) je comptais utiliser une DD autopilote (pour aller sur la map de départ), et pour les indices j'utilisais selenium pour naviguer sur dofus map et récupérer le nombre de déplacement et la direction. :)
Sinon super projet cheapeau !
 
Inscrit
1 Juin 2020
Messages
43
Reactions
29
#14
J'avais eu cette même idée, et pour éviter un maximum les erreurs (et moins m'embêter) je comptais utiliser une DD autopilote
Ouais pratique ! Le mieux c'est d'aller dans l'invoker et de track les paquets pour la fonction de pathfinding. Il existe d'ailleurs je crois un mec qui a fait une lib de pathfinding globale utilisable par chacun :)

j'utilisais selenium pour naviguer sur dofus map et récupérer le nombre de déplacement et la direction. :)
Sinon super projet cheapeau !
J'ai préféré télécharger tous les indices de ces dit sites directement. Comme ça , pas besoin d'aller y naviguer. Le bot a la liste directement et sy rend des qu'il a lu l'indice :)

Beau boulot, je serais curieux de voir un combat contre des monstres
Bah .. Avec ce que j'ai mis en gif, le bot prend a peu pres 4-5 secondes pour savoir comment se déplacer pour se rapprocher de l'ennemi. Par la suite il "suffit" de lancer "betement" les sorts. ( J'ai rajouté quelques conditions de portée histoire de pas essayer de taper alors qu'on est a 40 PO :) ) Je verrai si j'enregistre viteuf un combat
 
Inscrit
1 Juin 2020
Messages
43
Reactions
29
#16
J'ai pas compris cette étape, concrètement, tu boucles sur tous les pixels de l'image ?
Non. En gros je commence a la case la plus en haut a gauche ( 65,12) je crois sa position. Et j'analyse sa couleur. SI elle est dans la liste des couleurs whitelistées, je la considère pratiquable parle perso, otherwise je la considère comme étant blacklist. Puis je décale de X pixels vers la droite pour etre au centre de la case juste a droite ( je sais plus exactement combien de pixels, mais c'est genre 50 ).Et jfais pareil, pour toutes les lignes de la carte.

En espérant avoir été plus précis.
 
Inscrit
4 Novembre 2020
Messages
5
Reactions
1
#17
ok ok je vois, merci pour l’éclaircissement.

bon courage pour la suite
 
Inscrit
6 Novembre 2020
Messages
1
Reactions
0
#18
Salut, super beau travail ! j'ai une petite question, tu dis:
J'ai préféré télécharger tous les indices de ces dit sites directement. Comme ça , pas besoin d'aller y naviguer. Le bot a la liste directement et sy rend des qu'il a lu l'indice :)
je suis curieux de savoir comment tu as fait :)
 
Inscrit
1 Juin 2020
Messages
43
Reactions
29
#19
J'ai loop des requetes GET sur toutes les coordonnées des maps du jeu sur ces sites.
En gros, (0,0), Gauche, Droite Haut Bas, puis (0,1), Gauche, Droite, Haut, Bas , etc etc
 
Inscrit
6 Decembre 2020
Messages
31
Reactions
6
#20
Tout d'abord, merci valchimiiste pour toutes ces informations !

Ayant, comme toi et d'autres, essayé de faire de faire de même (ça marche chez moi mais pas parfaitement); je me suis retrouvé "embêté" par quelques parties que je détaillerai après. J'ai codé en Python (et sans partie réseau) mon petit algo pour les CaT en 2 semaines (du temps libre et du temps pris sur mes nuits).
J'aimerais juste ici te dire ce qui m'a plu dans ton projet (des choses que je ne connaissais pas, et qui m'ont donné des idées):
- Le fait de pouvoir faire marcher le programme en background (je pensais pas que ce serait possible avec Win et sans VM)
- La partie sur le combat : détection de la map (qui me paraissait une tâche bien fatiguante), déplacement grâce à A* (que j'avais étudié rapidement mais ça ne me semblait pas possible car je n'avais pas de partie détection de map).
- Le fait que toutes tes datas soient en local. (J'utilise Selenium et me connecte à chaque fois à un site d'indice: c'est chiant).
- J'aime l'idée de chercher le jalon sur la map pour avoir la pos de début de CaT. De mon côté, Tesseract le fait très bien!!
Passé la partie de félicitation: :p

Comme dis plus haut, j'ai codé mon propre algorithme: moins performant que le tien.
Pour les personnes ayant envie de savoir, ou de programmer votre propre algo de CaT, je me suis retrouvé face à des problèmes. Certaines choses on déjà des solutions, d'autres seront répondues et les dernières :
- Lorsque la CaT commence dans des endroit compliqué, difficiles d'accès (je pense à la presque-île du temple Sram par exemple). Mon personnage ce TP au zaap en dessous, puis ce bloque contre l'eau entre le zaap et la pos). Je n'ai pas encore trouvé de solution à part créer des "chemins d'accès" à ces map particulières, en hard. Ou utiliser un algorithme pour rendre le personnage plus débrouillard (si bloqué en ligne droite, revenir sur ses pas et essayer de changer de map. Mais j'ai peur du temps qu'il pourrait perdre à chercher la map). En revanche, après avoir trouvé la première map, plus de problème puisque la CaT va demander au personnage de se déplacer en ligne droite là où c'est possible.
- La partie combat: je n'avais aucune idée de comment gérer le combat. Mes algorithmes de combat sont adaptées pour des combats contre des défenseur de ressource, pas contre le coffre.
- La partie détection de map : j'ai la position de la map en haut à gauche de l'écran. Mais Tesseract galère sur certaines maps (et ça me met en rogne, pardonnez l'expression). Avec ton idée de copier la pos dans le presse papier, je me suis dit… Pourquoi pas demander à mon personnage de me donner lui-même sa pos: %pos% dans le chat ? Sinon, j'ai pensé à train avec du ML mais ça me semble beaucoup de temps pour pas grand chose.
Passé la partie présentation des problèmes que l'on peut rencontrer pour son algorithme de CaT.

Maintenant, une partie question pour la communauté. Ne répondez que si vous le voulez. :)
- Que pensez-vous de demander à mon personnage sa pos dans le chat? (%pos%) Je trouverais personnellement le comportement clairement suspicieux si je voyais cela. Je fais déjà de la modification d'image (OpenCV) pour ne pas demander à Tesseract de deviner des choses trop compliquées, mais ça ne fonctionne pas à tous les coups. En sniffant les données, cela pourrait marcher plus facilement?
- J'ai aimé la partie de stockage de donnée en local (cf. valchimiiste). J'ai essayé de tout stocker, mais je n'ai pas (encore) trouvé comment. Je pensais tout stocker dans un nested dictionary et cela dans un Json (pourquoi? je ne sais pas…). Le format du fichier est-il important? L'idée du nested dictionary est-elle bonne? Y a-t-il de meilleures idées? Les avez-vous? Voulez-vous bien les partager? De plus, je n'arrive pas à "Get" correctement les données du site grâce à mon algorithme. ILe site semble se "bloquer" après 20 demandes différentes. Mais bon, j'ai pas encore tout testé, je devrais pouvoir le faire petit à petit (I hope).
- Pour la partie détection du perso et du monstre grâce aux 'pixels discriminants de mon perso' (cf. valchimiiste). Je comprend l'idée, valchimiiste. Mais je me pose la question des outils… Est-ce que c'est une méthode à la 'bourrin'? Si tu as le temps, et l'envi de poster un article qui t'as donné l'idée? Ou une aide? Un indice? Pour l'anecdote, j'ai longtemps cherché à trouvé une méthode me permettant de détecter un objet partiellement caché, et ce jusqu'à utiliser du ML (j'adore ça, le ML). Mais manque de datas (I guess), mes apprentissages ne marchaient pas aussi bien que je le souhaitais.
- Je n'ai pas compris la partie: "
Par la suite un "/clear" et un "/travel X Y" me permettent alors d'arriver sur la map de départ. ( Le /clear sert a détecter le message m'indiquant etre arrivé )
". Je n'ai pas compris ce que sont ces /clear et /travel. Peut-être ai-je loupé quelque chose. N'hésitez pas à me dire que oui, si c'est le cas (mais gentiment, hein?!).
- Je n'ai pas bien compris dans ta phrase :
En couplant l'application d'un masque a openCV et en configurant correctement les cutoffs de détection[...]
, ce que tu veux dire par "cutoffs de détection". J'imagine que c'est en rapport avec la détection par Computer Vision. Une précision?
Voilà pour la partie question. D'autres arriverons plus tard?

J'ai conscience que j'arrive rapidement et pose plein de questions. Mais face à ce forum VIVANT où les gens s'entraident, j'ai été pris par l'engouement et je me suis lancé. Si vous voulez m'aider, répondre à mes questions me ferait énormément plaisir. Si vous ne voulez pas partager, ce n'est pas grave et je le comprend (d'une certaine manière), j'essaierai de faire avec mes propres moyens. ;)
J'espère relancer ce thread qui m'a bien plu!
Je vais continuer de 'roam' (pas le mot Français en tête :/ )sur ce forum à la recherche de plus d'informations. Prochain intérêt: sniffer... le réseau (toujours détesté, peut-être que ça va m'aider à l'apprécier à sa juste valeur aujourd'hui?) pour avoir plus d'informations pour mes programmes.
Désolé pour les fautes (si vous en trouvez ;) ). J'espère que ce dont je parle tout du long de ce gros post est clair.
 
Haut Bas