jeudi 29 mars 2012

Bot Ogame (ancienne version mais ébauche)

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

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.

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
ce qui nous donne :
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);
Pour tester notre classe il nous faut écrire : Connection c = new connection(google.fr,80); mais attention, ceci ouvre une connection qu'il serait bon de refermer ...

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 :).

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
Donc FonctionLog est un délégate qui permettra d'encapsuler une fonction de signature "void xxx(string)" Dans ma classe j'inclus donc ma définition de délégate... Comment les utilise t'on ? Maintenant passons à la pratique, pour les utiliser voici le code : Dans votre classe :
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...  

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)
Exemple : je désire naviguer sur internet, "je vais sur google.fr" correspond à créer un "tunnel" entre google.fr et moipour pouvoir s'envoyer des informations Include C# : System.Net.Sockets;

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)
Exemple : En tant que protocole sûr, celui ci permet l'envoir d'information comme par exemple lors de la navigation internet...

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
Exemple : Le streaming est l'exemple parfait : si une trame (par exemple une image) se pert, il ne sert à rien de la retransmettre, cela bloquerait le processus de lecture. En plus de sa légèreté, UDP permet un gain de performance.

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...
Exemple : Imaginez vous une rue pleine de maison, chaque maison ayant une adresse. Alors si je désire faire des travaux dans une maison, il me parrait inconcevable de prendre la maison et de l'enmener à un atelier. Par contre, avec l'adresse, je peux me rendre directement dans la maison. C'est plus simple. Autre exemple : Je charge un fichier gros XML (5Mo) dans un programme, au lieu de passer le string entier pour écrire une ligne en fin de fichier (et donc le copier d'un emplacement mémoire à un autre), je passe juste le pointeur, et c'est la fonction qui écrit qui va le chercher. C# : (pas de pointeurs sans code unsafe, cool non ?)

Original article available at http://www.alphablog.org

L'intégration continue avec Hudson

HudsonUne petite présentation succincte sur l'intégration continue Hudson dans un projet .Net. Ces avantages et inconvénients. Il m'a fallut 1/2 journée pour tout mettre en place. Il me reste encore à bien paramétrer les règles FXCop et ça sera parfait. Pour info, le PowerPoint s'accompagne aussi de quelques explications :) Lien vers la présentation

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 : 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

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 mode listen est le mode du Serveur qui consiste à attendre une demande de connection d'un Client. Celle ci est souvent bloquante bien que certaines alternatives avec CallBack ou Non bloquante existe. Le socket est la base d'internet comme du réseau local... Voici un Client - Serveur de chat simple sur Developpez.com :http://stephaneey.developpez.com/tutoriel/dotnet/sockets/

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 avec
GET 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

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