Bon, pour ceux qui se délectaient d'avoir un bot Ogame, je leur donne une ébauche, donc à retravailler. 90% du boulot est fait mais j'ai perdu les sources récentes donc vous ferrez surrement avec ca : Sources A refaire, l'interface, Quelques fonctions haut niveau mais le protocole et les paquets "machés" son en principe dedans. Les sources sont fournies sans garanties et a compiler avec VS.Net 8.0 (et compilable avec le 7.1) ! Si quelqu'un veut se dévouer pour reprendre le boulot avec moi (une team C# par exemple), dites le moi et on fera un bot intéligent avec plaisir ^^
Original article available at http://www.alphablog.org
jeudi 29 mars 2012
Les Sockets ou comment communiquer sur internet ...
Je vais essayer de vous montrer comment utiliser les sokets dans un projet. Je ne vais pas le faire dans un "projet vide" directement mais plutôt mais dans une classe que nous pourrons réutiliser.
Original article available at http://www.alphablog.org
Mise en place d'un projet vierge
(Regardez sur le site l'article correspondant) Ceci fait, on passe à la suite...Ajout d'une classe vierge
Par le biais du menu "Fichier" faites "ajouter nouvel élément" puis classe. Nomez la et vous êtes prés.Ce qu'a besoin une connection
Bon, réfléchissons sur ce qu'a besoin une connection ... Voyons voir ... Ha oui, un Socket. Allez donc voir sa définition dans un article du site. Voyez donc que certains paramètres sont complexes. Nous allons donc développer un exemple pour plus de facilité.Exemple
Un petit exemple sympa : un client web ... Non, non, ça ne sera pas un firefox like car on va juste le faire en mode texte, juste pour tester les sockets.La classe vide
Revenons à notre classe de faite. En voici le code (une fois la classe renommée)//J'ai supprimé les commentaires pour plus de lisibilité.
using System;
//Le using utile pours les sockets using System.Net.Sockets;
using System.Net;
namespace ClientWeb
{
public class Connection
{
public Connection()
{
}
}
}
Dans notre exemple il nous faudra en private : - un Socket
- un bool pour savoir si tout c'est bien passé
- une string pour connaitre la dernière erreur
using System;
using System.Net.Sockets;
using System.Net;
namespace ClientWeb
{
public class Connection
{
Socket mainSocket;
bool Error;
string LastError;
public Connection()
{
}
}
}
un nouveau constructeur
La fonction "public Connection()" est le constructeur par défaut, je dois avouer que celui ci ne sert à rien sous cette forme car notre classe sera utilisée pour la connection à un serveur, sur un port déterminé. Transformons alors ce constructeur :public Connection(string serveur, int port)
{
Error = false;
mainSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
try
{
System.Net.IPHostEntry IPHE = System.Net.Dns.GetHostByName(serveur);
if(IPHE.AddressList.Length < 1)
{
Error = true;
LastError = "Hote existant mais impossible de trouver une adresse";
return;
}
System.Net.IPEndPoint IPEP = new System.Net.IPEndPoint(IPHE.AddressList[0],port);
mainSocket.Connect(IPEP);
}
catch
{
Error = true;
LastError = "Impossible de trouver l'hote";
return;
}
}
Explications : - mainSocket est initialisé de telle manière qu'il accepte le TCP.
- IPHE est l'élément qui contiendra l'analyse de l'adresse du serveur
- System.Net.Dns.GetHostByName() permet de déterminer les adresses d'un host par son nom
- Le try catch est pour prévenir l'erreur de getHostByName due à un hote introuvable
- IPEP est l'endroit de destination de notre connection avec une adresse et un port
- Et enfin la connection principale : mainSocket.Connect(IPEP);
Fermeture de connection
On ajoute alors dans notre classe :public void CloseConnection()
{
if(mainSocket != null)
if(mainSocket.Connected)
mainSocket.Close();
}
Si mainSocket est initialisé et que mainSocket est connecté, on le ferme. Envoie réception de donnée
Passons à l'envoie et la réception de donnée. Il nous faut bien communiquer avec ce socket ouvert non ? L'envoie est un jeu d'enfant alors que la réception reste un peu plus dure... Sachez que mainSocket.Send() et mainSocket.Receive() n'acceptent que des bytes ... La réception ressemble à ceci :public void Envoie(string str)
{
if(mainSocket == null) return;
if(!(mainSocket.Connected)) return;
//GetBytes transforme une string en tableau de bytes.
mainSocket.Send(System.Text.Encoding.Default.GetBytes(str));
}
Mais il vous faut ajouter ceci dans les "usings" : using System.Text;Quant à notre problème de lecture, voici la solution :
public string Recoie()
{
if(mainSocket == null) return "";
if(!(mainSocket.Connected)) return "";
int MAXBUFFER = 200;
int Octet_Lu = 1;
byte[] first_buffer = new byte[MAXBUFFER];
string LastReadString = "";
while(Octet_Lu != 0)
{
Octet_Lu = mainSocket.Receive(first_buffer,0,MAXBUFFER,System.Net.Sockets.SocketFlags.None);
if( Octet_Lu != 0)
LastReadString += System.Text.ASCIIEncoding.Default.GetString(first_buffer,0,Octet_Lu);
}
return LastReadString;
}
Notre algorithme fait ceci : Tant que je ne lit pas " à vide" je continu à lire MAXBUFFER octets et je les écrits. Dans un autre cas, nous aurions pu changer d'algorithme si nous avions connu la longueur du paquet ou bien sa fin, etc ... Utilisation finale
Notre classe connection est finie ... Voici son utilisation :Connection C = new Connection("Ogame.fr",80);
C.Envoie("GET / HTTP 1.1\r\n\r\n");
string reponse = C.Recoie();
C.CloseConnection();
Et, ho miracle, si vous affichez reponse, vous voyez le code HTML de la page de ogame.fr ... Ceci conclue mon premier tutorial de niveau intermédiaire sur les sockets. Pour vous faire rager un peu, je vous invite a regarder la classe TcpClient et HTTPrequest (si je me rapelle bien) et vous verrez que leur utilisation est peu être un peu plus simple. Pour ma part, j'utiliserais la classe Socket pour toutes mes connections. Original article available at http://www.alphablog.org
Les délégates ou comment passer une fonction en paramètre...
On connais tous les pointeurs de fonction en C par exemple ainsi que leur lot de problème (enfin pour moi) et pour ceux qui ne les connaissent pas les pointeurs, un petit récapitulatif peut être trouvé sur le site :).
On dois préparer le terrain en plusieur fois :
Original article available at http://www.alphablog.org
A quoi servent les délégates ?
Je dois vous avouer que je n'ai compris leur utilité que 2 semaines avant d'écrire ce post ! Je suis donc un Noob au niveau des délégates. Alors pour résumer, les délégates sont des variables capablent de stocker des fonctions avec une signature particulière. Plus particulièrement : Je crée une classe de threading, on le sait tous, le but des threads est de travailler en parrallèle pour le processus. Mais il faut bien qu'il fasse un rapport, non ? Les délégates interviènnent ici : Dans l'instanciation de la classe (ThreadClass tc = new ThreadClass(...)) on lui passe un délégate d'une fonction Log en paramètre pour que les threads puissent faire un compte rendu.Comment les déclare t'on ?
On dois préparer le terrain en plusieur fois :
public delegate void FonctionLog(string msg);Cette ligne signifie plusieurs choses :
- public : pour rendre le délégate public (j'y reviendrai tout à l'heure)
- void : notre fonction de log ne retournera rien
- FonctionLog : Le nom du delegate (pas d'une quelconque fonction)
- (...) : ses paramètres
public delegate void FonctionLog(string msg);
FonctionLog Fonc;
public ThreadClass(FonctionLog fl, ...)
{
Fonc = fl;
} Dans votre programme principal : public void LogThis(string ToLog) { //... }
public FonctionQuiUtiliseLesThreads()
{
ThreadClass tc = new ThreadClass(new ThreadClass.FonctionLog(LogThis));
} La seule difficulté ici réside dans le code new ThreadClass.FonctionLog(LogThis)qui est la méthode d'utilisation des délégates.
Quelques précisions
new ThreadClass(...) attends absolument une FonctionLog, il faut donc que, lors d'une utilisation interClasse, le délégate soit public. Dans une utilisation dans la même classe (quel intéret ?), le délégate peut être privé.Original article available at http://www.alphablog.org
Struct, Class, pour quelle organisation opter ?
Struct et Class sont deux type utilisable en C#. Le problème étant de savoir quand les utiliser... Selon moi, les classes sont des super-structures, nous allons voir comment utiliser les deux...
Original article available at http://www.alphablog.org
Type : CLASS
On peut ajouter une classe dans un projet par le biais du menu 'fichier' : "Fichier" --> "Ajouter un nouvel element" --> "Classe" puis entrez votre nom de classe. Vous vous en doutez, "Ajouter un element existant" permet de réutiliser une classe déja faite. L'IDE, aprés confirmation par l'utilisateur, crée un fichier .cs qui contient un code trés spartiate :using System;
namespace WindowsApplication2
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
public class Class1
{
public Class1()
{
//
// TODO : ajoutez ici la logique du constructeur
//
}
}
}
A nous de le rendre plus efficace... La classe alors crée est une classe totalement Objet, on y ajoute des champs private, static, et/ou public (pas propre) et on i ajoute aussi des procédures/fonction. Les champs :
Scope Type Nom ;Exemples :
public string Login; static int NBThread; private bool IsEnabled;
Les fonctions/procédures :
Scope Type Nom { }
Exemples : public string getLogin { return Login; }
Type : STRUCT
Les structures ne sont pas définies par l'IDE, elles sont définies par l'utilisateur comme :public struct StructTest
{
//On définit ensuite les champs et les fonctions/procédures de la
//même façon que pour les classes
}
Conclusion
Les classes englobent les structures, d'un point de vue conception, les classes sont des parties intégrante du programme final, elle permétrons d'organiser au mieux la logique de votre programme. Les structures quant à elles sont des moyen de faciliter la programmation des classes. Elles permettent, à mon point de vue, une meilleure "vision objet" de votre programme. Quelques exemple avec mes projets actuels : Pour mon projet de bot Ogame, j'ai organisé mon travail autour de la classe Form1 (autour de la classe graphique). Voici le shéma :- Form1.cs
- TraitementHautNiveau.cs
- TraitementParsing.cs (Classe Static)
- TraitementInternet.cs
- PaquetHTTP (Struct)
- ReponseHTTP (Struct)
- Connection (Struct)
- ListeAdresse (Struct)
- ListeGalaxie (Struct)
- ListePlanete (Struct)
- Vaisseau (Struct)
- ListeVaisseau (Struct)
- Threading.cs
Original article available at http://www.alphablog.org
Quelques définitions
Sockets
But : un socket est comme un "tunnel" ou transite des informations.Caractéristiques :
- Mode de création : en serveur, le socket accepte les connections et les traites. En client, il se conecte à un serveur
- Type de trame : TCP (sûre mais plus couteuse), UDP (sans contrôle d'arrivée), etc...
- Famille d'adresse : Internet, Unix (je sais pas trop à quoi ca sert)
TCP
But : Type de trame de comunication Caractéristiques :- Controle de séquence, remise en ordre à l'arrivé
- Controle de flux, pas de saturation
- Fragmente et s'adapte pour le protocole IP
- Orienté connection (Ouverture, fermeture de connection)
UDP
But : Type de trame de comunication Caractéristiques :- NON Orienté connection (Pas d'ouverture, fermeture de connection)
- Risque de perte de Trame
- Plus "léger" que TCP
Pointeurs
But : C'est un indicateur d'emplacement (cf Exemples), une adresse Caractéristiques :- Un simple Int : le pointeur est léger, maniable, copiable, etc...
- Permet le maniement des données de façon plus rapide est moins couteuse.
- Attention, prendre l'habitude de travailler avec...
Original article available at http://www.alphablog.org
L'intégration continue avec Hudson
Original article available at http://www.alphablog.org
.Net, Microsoft et les Règles ...
Bon, voila, je me dois de pousser une geulante de temps à autre ... Non mais sans rire ça me révolte, J'ai passé une heure à débugger mon protocole réseau de mon MMORPG pour me rendre compte que c'est une énormité de microsoft. Vla l'histoire, mon but était de convertir une donnée en type de base (int, char, byte, etc ...) en un tableau de byte, jusqu'au moment ou je me trouve face à la conversion de byte en tableau de byte donc, généricité oblige :
Original article available at http://www.alphablog.org
System.BitConverter.GetBytes((byte)6);Et la surprise, il me sort un tableau de deux bytes ! J'hallucine, Un tableau de bytes crée à partir d'un byte retourne deux bytes Oo ... Faut peut être arréter de fumer là... Le mot de la fin est que sur les pages de la MSDN, il n'y a bien sur des tas d'exemples avec les types simples mais pas avec les bytes, pas bête l'artiste ! Rappelez vous :
Seul le char est universel !
Original article available at http://www.alphablog.org
Les sockets et le protocole HTTP
Bon, nous allons commencer par la base :D
Original article available at http://www.alphablog.org
Les sockets
Un socket est un flux de communication entre deux objets que nous nommerons "Client" et "Serveur" dans le cadre du projet. Le Client va demander un droit de créer un canal de communication avec le Serveur, puis, si celui ci accèpte, le Client et le Serveur pourront communiquer. En C++, C#, Java, etc... les fonctions sont quasi-identiques. Cela consiste :- Créer un objet Socket
- Le paramétrer (TCP, Internet, etc... et le Host, le port)
- Lancer la demande pour le client ou se mettre en "Listen" pour le serveur
- Les fermer et les détruires
Le protocole HTTP
Le protocole HTTP, si vous passez outre la partie réseau s'avère assez simpliste. Voici une version du RFC de l'ancien salemioche.net : http://www.iprelax.fr/http/1945tm.php En quoi consiste la petite partie du protocole qui nous intéresse pour notre projet ? Voici ce que doit faire notre programme : Une fois connecté, lui envoyer une demande de page en envoyant tout simplement une string avecGET NomDeLaPage HTTP/1.1 host: alphablog.org (Double retour chariot pour finir)et la réponse est du style
HTTP/1.1 200 OK Date: Thu, 20 Dec 2001 17:11:50 GMT Server: Apache/1.3.19 (Unix) PHP/4.0.6 Last-Modified: Thu, 20 Dec 2001 16:36:22 GMT ETag: "2cb9e7-61c-3c221386" Accept-Ranges: bytes Content-Length: 1564 Connection: close Content-Type: text/html X-Pad: avoid browser bug <html><head> ...(Suite et fin)Enfin nous récupérons le code renvoyé par le Serveur, nous le parsons et nous en extrayons les cookies, les sessions, les liens html etc... Je vous laisse le plaisir de découvrir les joies d'extraire tout ces petits champs et si le malheur s'abat sur vous, la chance de découvrir les "serveurs caches". Autre difficulté, trouver dans le RFC les "nomenclatures" de fin de paquet par exemple, de séparation entre paquet système et paquet utile (entre le "HTTP/1.1 200 OK..." et le "<html>...") et aussi la méthode d'envoie des paramètres POST et GET qui ne sont pas si compliqués.
Application a Ogame
But de la manoeuvre : faire croire a Ogame qu'on joue... Pour cela, rien de plus simple, on va : - Se connecter à lui - Récupérer des pages et envoyer des demandes pour : --- Simuler une identification et récupérer les Session générés par php --- Générer les paquets d'affichage des pages, les récupérer et les parser. - Fermer proprement la session et enfin le socket.Outils utiles (indispensables)
Les plugins de firefox qui affichent/modifient les paquets ou un bon sniffer avec décryptage de paquet HTTP (gzip entre autre). Un peu de patiente. Si vous avez des questions, postez à la suite une question consise et complète et je tacherais d'y répondre.Original article available at http://www.alphablog.org
Mini tutorial sur les sockets appliqués au Bot Ogame
Créer un bot Ogame, pour un noob comme moi, m'a pris pas mal de temps alors je vous poste un guideLine plus qu'un tutoriel sur l'ébauche et le travail de recherche à propos de mon Bot Ogame. Je vous laisse le soins de poster aprés dans le forum directement pour poser une question ou laisser votre avis ici. Si ce tutorial ne vous convient pas, dites le moi et je chercherais à le faire évoluer. Voici l'adresse : Cliquez ICI ^^ Un bot est maintenant disponible ICI !!!
Original article available at http://www.alphablog.org
Original article available at http://www.alphablog.org
Premières vidéo du ciel du MMORPG
Une de mes premères vidéos en ce qui concerne le ciel. Les dégradés marchent, le mouvement des nuages aussi. Les étoiles (pas trés visible) sont implémentées aussis. Bientot j'ajouterai le soleil/la lune. J'optimiserai les Pixel shader et VertexShader pour le dome des nuages/étoiles.
Délégates démistifiés !
J'ai tenté un petit speech sur les délégates en C# J'ai essayé d'être le plus clair possible
MaJ des Tutoriaux intermédiaires C#
Voila mon premier tuto intermédiaires C# sur l'utilisation des Sockets
Inscription à :
Commentaires (Atom)