![]() |
||
![]() |
||
![]() |
|
On retrouve alors le choix qui a été fait des le cahier des charges, de faire un serveur multi-thread couplé avec des sockets bloquants. Cette solution est de loin celle qui représente le meilleur rapport entre rapidité et portabilité. Fonctionnement de WinsockWinsock se présente sous forme d'une dll, il a donc fallu apprendre a insérer une dll dans un projet Visual Studio. En effet, ceci ne se présente pas sous la même forme que sous Delphi ou il suffit d'inclure le .h, il faut utiliser inclure au projet un .lib et le .h correspondant. De plus la librairie Winsock doit être initialisé, ceci se fait par l'appel de la fonction WSAStartup() tandis que la fermeture se faite par WSACleanup() (il est à noter que lors de la fermeture des connections et de la librairie il faut vérifier s'il y a ou nom des messages en attente). Une fois ces opérations réglées on peut accéder à toutes les fonctions externes de la librairies : celles qui sont déclarées dans Winsock.h.Le serveur commence par initialiser un socket en mode Listen. Ce socket sert à recevoir les connections entrantes. Pour initialiser un socket on passe par une classe sockaddr_in qui sert a décrire le socket. La classe sockaddr_in est en fait une classe enfant de sockaddr car il existe en fait une classe héritée pour chaque type de protocole de connexion (dans notres cas c'est pour le protocole TCP/IP). On a alors :
sockaddr_in sinInterface;
sinInterface.sin_family = AF_INET;
sinInterface.sin_addr.s_addr = nInterfaceAddr;
sinInterface.sin_port = Port;
nInterfaceAddr est l'IP de l'interface sur
laquelle on désire écouter les connections, celle ci a été
précédemment obtenue grâce à la fonction de conversion de Winsock
: inet_addr() à partir d'une adresse de la forme x.x.x.x.
Ensuite on affecte ensuite cette description au socket grâce à la
fonction bind(). Enfin on met le socket en écoute avec
listen().
Le serveur continue alors d'écouter jusqu'à ce qu'on le ferme. Pour chaque connection entrante il va recevoir les coordonnées du client et lancer un nouvelle thread qui va s'occuper de gérer le client qui s'est connecté. Lorsqu'il y a du mouvement sur le socket en écoute, celui reçoit les coordonnées du client grâce à la fonction accept(). Le lancement de la nouvelle thread se fait grâce à CreateThread() auquel on passe le socket contenant les informations du client avec qui on communique. Il est important de noter que toutes ces fonctions ont une syntaxe très proche de la version sous Unix des socket, ainsi que la création de thread qui est à peu de choses près pareil. De plus les fonctions utilisant Winsock ont toutes été regroupées dans un même fichier afin de faciliter le portage du code sous une autre plateforme. La thread principale qui gère les connections ne peut communiquer qu'avec un seul utilisateur en même temps. C'est à la fois une bonne et un mauvaise chose. Une bonne chose car tout ce qui est envoyé et reçus dans ce thread vient ou provient de la même personne. Par contre dès que l'on à besoin d'envoyer un message à quelqu'un d'autre il faut passer par des variables globales. Il faut alors faire attention à la gestion de la mémoire car il faut interdire à deux threads de travailler sur un même objet en même temps. Ceci sera l'objet de notre travaille dans la réalisation des fonctions du protocole et sera donc traité à la deuxième soutenance. Néanmoins la méthode pour s'échanger des informations a déjà été mise au point, on se servira d'une file de message appartenant à la classe user (pour plus de détails sur celle ci se référer à la section qui lui est dédiée). Pour ce qui est de l'envoie et la réception des données on utilise les fonctions recv() et send(). Lorsqu'on envoie un message, on boucle jusqu'à ce qu'on soit sur que tout les octets soient envoyés. Lors de la réception, cette méthode qui permet d'être sûr d'avoir envoyé tout le message ne peut pas être faite car on ne connaît pas à l'avance la longueur du message que l'on reçoit. C'est lors des procédure d'envoie et de réception que le cryptage des messages est effectués (voir la partie sécurité). Gestion des erreursLa plus grosse partie du serveur consiste à bien gérer les erreurs. Il faut tester la valeur de retour de la plus pars des fonctions pour voir si tout s'est bien déroulé. Ceci est crucial dans un serveur car un plantage pourrait avoir un effet désastreux. A chaque fois qu'il se produit une erreur il faut la conserver dans un fichier de log, et faire en sorte que le serveur continue ses tâches comme si de rien était. Pour ce qui est de la gestion des logs, celle ci n'est pas encore implémentée, pour l'instant le serveur se limite à afficher à l'écran les erreurs, elle sera implémentée plus tard, avec les statistiques du serveur.Mais tout n'est pas si simple car la plupart des fonctions Winsock ne renvoient pas directement les erreurs, mais celle si sont accessibles à travers la fonction WSAGetLastError(). Malheureusement cette fonction retourne des nombres comme erreurs et ceux ci sont peu explicites et non pratique à utiliser dans des logs. Il a donc été réalisé une fonction permettant de transformer ce numéro en message d'erreur afin d'avoir un affichage plus correct et une utilisation plus propre. Le protocoleBut d'un protocoleLe protocole est le langage qui permet à deux applications réseau de communiquer. Nous avons donc écrit un protocole de communication YooGoo. Si une application respecte le protocole, elle est en mesure de communiquer soit avec le client, soit avec le serveur de YooGoo. De plus, le protocole nous permet de coder le serveur et le client indépendamment l'un de l'autre. Il suffit qu'il respecte tous les deux le protocole pour qu'ils soient compatibles. Lors de la conception du protocole, nous avons fait bien attention à ce que celui-ci soit "logique". Il ne faut pas qu'il y ait de fonctions incompatibles, ni de fonction double. On doit aussi penser comment faire passer certaines informations entre les clients, etc. Dans un protocole tel que le FTP et HTTP, il n'y a pas besoin de faire passer de l'information entre les clients. Chaque connexion au serveur est totalement indépendante.Conception du protocoleTout d'abord, YooGoo est crypté. Toute la première phase de la connexion se compose de la génération et de l'échange des clés de cryptage. Dans la suite, le cryptage est totalement transparent. Lorsque nous appelons la fonction permettant l'envoie de donnée, celle-ci crypte les données avant de les envoyer. Comme YooGoo ressemble pour la plupart de ses fonctionnalités à l'IRC, nous nous sommes beaucoup inspiré du protocole de l'IRC (cf. RFC 1412??? disponible sur www.YooGoo.com).Pour chaque fonction un code d'erreur est renvoyé au client. La valeur 00 signifie que tout s'est bien passé. Tous les codes < 100 signifient que ce ne sont pas des erreurs fatales. Les erreurs comprises entre 400 et 499 signifient que l'erreur est fatale et que la fonction s'est terminée anormalement. Ces codes d'erreur sont important car ils seront aussi utilisés en interne dans le serveur. Néanmoins, nous avons décidé de ne pas renvoyer d'erreur de la part du client. Effectivement, nous pensons qu'il n'est pas utile au serveur de savoir si la donnée est bien reconnue (il ne peut rien y faire s'il y a une erreur...). De plus, les messages envoyés par le serveur sont souvent des messages d'informations, il y a donc que très peu d'erreur possible. Je rappelle que TCP/IP possède un code de correction d'erreur et qu'une donnée arrive forcement à destination sans erreurs. Pour une description détaille de toutes les fonctions du protocole, je vous invite à vous reporter en annexe A. Gestion du serveurLa classe userLes droitsLe principe des droits est très simple, chaque utilisateur donne un niveau de droit à chacune des personnes qu'il désire. Un droit différent de 1 donne le permet de figurer sur la contact list. Le droit 0 banni l'utilisateur concerné qui figure sur la contact list en tant que banni. Le droit de 1 est attribué à toutes les personnes de la communauté YooGoo ne figurant pas sur la contact list. Enfin les droits supérieurs à 1 donne une importance différente aux personnes de la contact list, qui pourront accéder à certains champs de votre profil grâce à leur niveau de droit.Donc chaque champ du profil contiendra un niveau de droit. Les champs de recherche comme le pseudo auront un niveau fixe de 1, afin d'être vu par toute la communauté hormis les bannis. IntroductionLa classe User à pour but de gérer tout ce qui touche à l'utilisateur. C'est-à-dire qu'elle contient toutes les fonctions ayant rapport au profil, à la contact list, à la file des messages. Elle est composée de fonctions publiques qui seront appelées par le programme, et de fonctions privées qui seront cachées du reste du programme mais appelées en interne à la classe. Ainsi chaque utilisateur en ligne sera un objet de cette classe. Par ailleurs la classe User possède un compteur permettant de savoir le nombre d'utilisateurs chargés en mémoire, ce qui nous permettra d'effectuer des statistiques. Ce compteur est réalisé grâce à une variable static à la classe, elle est donc indépendante de chacun des objets. Cette variable est incrémentée dans le(s) constructeur(s) de la classe. Et pour nous permettre de récupérer cette valeur, il faut appeler la fonction user::getnbuser dans le programme. Cette fonction est également static à la classe.Type UserChaque objet de la classe sera chargé en mémoire. Il faut donc alléger au maximum la structure de l'objet user. Or l'élément prenant le plus de place est bien évidemment le profil. Il n'a donc fallu garder que les éléments indispensables à un fonctionnement rapide du programme. Le type User se décompose en trois structures, la structure profil, la structure info et une structure dédiée à la file de messages. La structure profil contient les critères de recherches (nick, sexe, ville, date de naissance) mais également le mot de passe et deux 'pointeurs' vers les fichiers Profil et Contact désignant un numéro de ligne. La structure info contient elle des informations temporaires utiles pour la procédure de la thread, telles que l'adresse IP, le port, la clé DES, (le statut). Enfin la structure file de messages est composée d'un tableau de char et d'un pointeur vers un autre message.ProfilIl existe donc deux profils. Un profil lite, le plus petit possible, destiné à la mémoire principale et un profil complet destiné à la mémoire secondaire, regroupant toutes les infos disponibles sur un utilisateur. Les informations sont celles qu'on trouve régulièrement sur les chats (ICQ, Caramail, IRC ...). Le profil complet regroupe les champs du profil lite, plus des champs complémentaires tels que le Password, le nom, le prénom, l'adresse, le code postal, la langue, le pays, le numéro de téléphone, l'adresse mail, un " pointeur " vers le numéro de ligne dans le fichier contact, une chaîne contenant le chemin vers une image, et les intérêts. De plus chaque champ possède un niveau de droit qui sera le premier caractère de chaque champ (ex : 4Dupond, seuls les personnes ayant un niveau supérieur à 3 sur la contact list de monsieur Dupond pourront voir ce champ).Fichier profil.yooAfin de pouvoir conserver tous les profils après une extinction du serveur ou une panne éventuelle, il faut que tous les profils soient stockés dans un fichier : le fichier profil.yoo. Ce fichier est d'autre part indispensable car tous les profils complets des utilisateurs ne pourront pas être stockés dans la mémoire vive. De plus afin d'avoir une vue sur l'ensemble des profils, il a été décidé d'en faire un fichier ascii et non binaire. Ce choix nous permettra de visionner les profils et éventuellement de corriger, supprimer, ajouter des profils à notre guise, à l'aide d'un éditeur de texte classique. Par ailleurs le fichier sera formaté, c'est-à-dire que chaque champ du profil aura une colonne de taille fixe pour tous les utilisateurs, ce qui permettra d'avoir une meilleure vision de notre fichier. Enfin chaque profil occupera une ligne dans le fichier où chaque champ sera délimité par un caractère spécial qu'il sera possible de changer à tout moment. Pour l'instant le caractère délimiteur est le "Ce fichier devra être compatible avec notre procédure d'ajout, ou plutôt nous allons adapter notre procédure d'ajout à notre vision du fichier. Le format du fichier devra donc faciliter la construction de la procédure d'ajout. Pour cela chaque ligne aura le même nombre de caractères. Il sera ainsi plus aisé de se déplacer directement à une ligne, il suffira d'utiliser la fonction fseek, qui prend en paramètre un pointeur sur FILE, le numéro du caractère voulu, et l'origine (début, fin, ou position actuel du pointeur), en multipliant le numéro de la ligne désirée par le nombre de caractères par ligne. Les fonctions publiques associées au fichier profil.yoo sont au nombre de 3. La première est celle d'ajout, elle prend en paramètre une chaîne de caractères contenant le profil complet. Cette chaîne est dans un premier temps analysée, c'est-à-dire qu'on vérifie si son formatage est correct, si les champs numériques ne contiennent pas de lettres, et si la date de naissance est cohérente. Le formatage de cette chaîne est possible grâce une nouvelle fois à un caractère délimiteur. Cette chaîne peut par exemple peut passer le test sans problème :
"2!19821203!City!FirstName!Name!PassWord!address!zipcode!
10!10!numtel1!numtel2!email1!email2!photo.jpg!interests!".
Une fois analysée, la chaîne est stockée dans le fichier. Pour
cela, il faut ouvrir le fichier à l'aide de la fonction
fopen() qui retourne un pointeur sur FILE. En ouvrant un
fichier il faut choisir un mode dans notre cas le mode append est
le plus approprié. Ensuite la chaîne est écrite caractère par
caractère juste qu'à la fin du champs, qui sera complété par des
espaces jusqu'au prochain champ. Le nombre d'espace dépend bien
sûr de la taille du champ. Une fois l'écriture terminée il faut
refermer le fichier à l'aide de la fonction fclose().
La seconde fonction est celle de modification de champ. Elle prend en paramètre le nouveau champ (chaîne de caractères) ainsi que la désignation du champ établie par une série de constantes (ex : MOD_NICK pour modifier le pseudo). Elle fonctionne sur le même principe que la fonction de sauvegarde pour ce qui est de la manipulation du fichier (fopen(), fclose() ...), sauf que le mode n'est plus append mais emphread /write, car il faut trouver le champ désiré (donc lire) et le modifier (donc écrire). La dernière fonction permet de récupérer le profil d'une personne si nous en avons l'autorisation. Cette fonction est appelée avec un pointeur sur char qui contiendra le profil de retour, et l'utilisateur voulu (sous le type user). Ce qui implique qu'il sera impossible de visionner le profil d'une personne déconnectée. Dans un premier temps, il faut aller rechercher les droits de l'utilisateur demandeur dans la contact list. Si l'utilisateur est banni on retourne un message d'avertissement, s'il n'existe pas on lui donne un droit de 1. Ensuite on se positionne sur la ligne contenant le profil grâce à la variable numline faisant partie du profil lite. La ligne est parcourue à l'aide de la fonction fseek() qui déplace le pointeur du fichier sur le premier caractère de chaque champ. Ainsi il est plus aisé de récupérer les champs qui sont autorisés pour l'utilisateur. Les champs récupérés sont ajoutés à la chaîne de retour. Contact ListLa Contact List a pour but de faciliter la vie du chatteur. En effet grâce à cette dernière il peut voir automatiquement les membres de la communauté YooGoo avec lesquels il parle fréquemment. Dans sa conception la Contact List n'est rien d'autre qu'une simple liste associant un niveau de droit, donc un numéro, à une personne. Ainsi la liste des bannis est intégrée à la contact list. De plus avec YooGoo c'est le serveur qui hébergera la contact list. Ceci permettra même après un formatage du disque du côté client de pouvoir récupérer sa contact list, dès la reconnexion au serveur. C'est d'ailleurs la solution que vient d'adopter ICQ dans sa dernière version (ICQ2001b). Le serveur se contente juste de garder les noms, et le client YooGoo s'occupera de la personnaliser : trie, couleur ... Ce choix sera bien sûr plus délicat à traiter, et ralentira bien évidemment le serveur à cause des accès au fichier et aux tests fréquents, mais sa praticité prime sur le reste. Ainsi la contact list sera modifiée par le client à travers des appels de fonction du serveur.Fichier contact.yooLe même problème que pour les profils se pose à la contact list. Il faut pouvoir stocker toutes les contact lists dans un fichier. Un problème majeur qui n'apparaît pas avec les profils est que une liste de contact n'a pas la même longueur selon l'utilisateur. Elle peut être vide, ou regrouper tous les utilisateurs de la communauté. Pour remédier à se problème la structure du fichier à été repensée. Chaque ligne correspond à un utilisateur, et ne contient que 5 contacts. La structure est la suivante :ProchaineLigne|Propriétaire|Contact1|Contact2|Contact3|Contact4|Contact5|Ainsi lorsqu'on ajoute un contact il est ajouté à la ligne, et s'il n'y a plus de place, on ajoute une nouvelle ligne au fichier en modifiant l'en-tête de la ligne précédente. Un utilisateur possède donc (nombre d'utilisateur / 5) + 1 ligne(s) dans le fichier. De même que pour le profil, 4 fonctions publiques agissent sur la modification du fichier contact.yoo.
File des messagesButLa file des messages a pour but de stocker tous les messages de l'utilisateur concerné. Tous ces messages peuvent être des messages texte destinés à être envoyé à d'autre utilisateur de la communauté YooGoo ou tout simplement des appels de fonctions. Par exemple lors d'un ajout d'utilisateur dans la Contact List, on empile un message qui contiendra le message request qui appel une fonction au niveau du client.FonctionnementLa file est composée d'une chaîne d'une longueur de 1024 caractères contenant le message et d'un pointeur vers une autre structure message. Cette file est donc une file classique comme celles vues en cours. Dans sa construction la file possède une tête, et une queue déclarées en privée. Ces variables ne peuvent donc pas être modifiées accidentellement par du code extérieur à la classe. La file des messages est gérée par 3 fonctions publiques :
La classe canalIntroductionLa classe canal ressemble de part sa structure à la classe User. Les principes de fonctionnement sont proches mais pas rigoureusement les mêmes. La Contact List de la classe User peut ainsi se rapprocher de la liste des utilisateurs de la classe canal. Cependant le principe de fonctionnement n'est pas le même c'est pourquoi nous devons l'expliquer.PrincipeLes canaux ou salons permettront aux utilisateurs de pouvoirs parler tous en même temps dans des sections à thèmes. Il existera des canaux permanents qui ne pourront donc pas être effacé du serveur. De plus les utilisateurs auront la possibilité d'en créer. Pour créer un canal il suffit d'appeler la fonction joinable. Si le canal existe l'utilisateur tente de se connecter au canal demandé sinon un canal est créé. Ce canal comportera seulement un nom et un mot de passe. Ce sera le créateur qui devra personnaliser son canal avec les fonctions de modification. Il aura alors le choix entre un canal public et un canal privé. Les canaux privés ne sont que des canaux publics dont l'accès nécessite un mot de passe. Chaque canal sera chargé en mémoire. Tout comme avec le type user, le type canal devra être assez léger pour ne pas occuper trop de place en mémoire. De plus chaque canal devra posséder la liste des utilisateurs connectés, des utilisateurs bannis, des modérateurs, et des chanroots. Ils seront stockés sous forme de liste chaînée. Les modérateurs sont des utilisateurs à pouvoir. C'est-à-dire qu'ils peuvent bannir des personnes, les kicker, tout cela en fonction des droits qui leurs sont attribués. Les modérateurs d'un même canal ont tous les mêmes droits. Ce sont les chanroots qui distribuent les droits. Ils sont modifiables à tout moment. Le chanroot est un modérateur qui possède tous les droits. De plus un chanroot peut ajouter, mais aussi supprimer un chanroot.Afin de conserver les canaux permanents, ils seront stockés dans un fichier à l'extinction du serveur; on y stocke les infos du canal (mot de passe, nom, ...), les utilisateurs particuliers (chanroots, bannis, modérateurs). D'un point de vu de la gestion " interne " au serveur, une seule thread gérera tous les canaux. De plus contrairement à la classe user, la file des messages sera commune à la classe et non pas à chaque canal. Type classeNotre type classe sera composé de 6 champs qui seront gardés en mémoire.
File des messagesLa file des messages de la classe Canal est la même que celle de la classe User à une exception près. La file des messages des canaux est unique, c'est-à-dire que tous les messages enfilés pas les canaux se retrouvent dans une seule file qui ne dépend pas de l'objet canal. Pour pouvoir réaliser une telle file il suffit de passer la tête de la file en variable statique à la classe. La tête étant la même pour tous les canaux ils enfilent ainsi tous au même endroit.La déclaration de la variable est la suivante :
static Tcanal *tete;
Et lorsqu'on définit une variable statique dans une classe il faut
l'initialiser ainsi :
canal::Tcanal * canal::tete = NULL;
Principe des listesPour pouvoir fonctionner correctement la classe canal a besoin de listes. Elles sont au nombre de quatre, toutes basées sur la même structure Tlist. Cette liste est doublement chaînée et permettra de faire une recherche par dichotomie dans la liste des connectés. Il y a une liste pour les chanroots, une pour les modérateurs, une autre pour les bannis, et une dernière pour les utilisateurs connectés. Le but de faire 4 listes est de simplifier l'écriture dans un fichier des canaux permanents, il suffira d'écrire les trois premières listes.Elles possèdent une tête et une queue. Lors de la création, tête et queue pointe sur NULL. Puis on distingue différents cas pour l'insertion et la suppression : pour la tête et la queue. En effet selon qu'on insert en tête ou en queue la mise à jour des pointeurs se fait différemment. Constructeur et destructeurPour pouvoir créer et détruire proprement un canal il faut adapter le constructeur et le destructeur à nos besoins.
Gestion des utilisateursPour gérer les utilisateurs on aura besoin principalement de deux fonctions qui porteront sur la liste des utilisateurs.
Gestion des modérateursVoici les fonctions qui permettent de créer des modérateurs, mais également les fonctions qu'ils devraient pouvoir utiliser pour garder le canal le plus "propre" possible :
Gestion des chanrootsVoici les fonctions qui permettent de créer des chanroots, mais également les fonctions qui permettront de définir les modérateurs :
La base de donnéePour représenter l'ensemble des utilisateurs, nous avons opté pour la représentation par arbre binaire et plus précisément arbre AVL (Adelson-Velskii et Landis).L'avantage de cette représentation est que la durée de n' importe quelle opération, que ce soit ajout, insertion, suppression ou recherche, et au plus Implémentation des types abstraitsAfin de faciliter le développement de YooGoo, nous avons implémenté en C les types les plus usités (liste, pile, file et AVL) dans notre application. Cela évite finalement que chacun d'entre nous développe ses propres outils chacun de son côté et que l'on découvre à la compilation que l'on aurait pu faire une certaine économie de temps et d'énergie.Liste, pile et filePour la liste (et donc pour la pile et la file), nous avons :
AVL
Définition de l'objet DatabasePour " simplifier les choses ", nous avons choisi de représenter l'objet [base de donnée] (tout du moins, celui représenté en mémoire) directement par sa propre classe d'objet et ses propres méthodes qui lui seront appliquées.La classe Base De Donnée (DB) comprend essentiellement une liste chaînée et un AVL pour chaque critère selon lesquels on peut rechercher un utilisateur. Actuellement, on recense 4 critères principaux (Nickname, genre, date de naissance et ville). Ceci signifie que les opérations d'insertion et de suppression seront de l'ordre de L'objet DB comporte deux opérations classiques : le constructeur qui initialise la liste et les arbres à NULL et le destructeur qui se charge de libérer la mémoire proprement. Il comporte également une fonction d'insertion (celle qui stock et insert dans les AVL) et une fonction de recherche qui retourne une liste chaînée d'objets utilisateurs en fonction d'un objet utilisateur passé en paramètre (critères plus ou moins vides selon ce que l'on recherche : c'est la fonction qui gère). Bien entendu, dans le but d'être propre, les utilisateurs ne sont représentés qu'une seule fois en mémoire et les arbres s'entrecroisent sur les pointeurs "data" stockés dans la liste chaînée. Pour cette première soutenance, un exemple en Shell sera montré, avec insertion et affichage de l' arbre ainsi que la fonctionnalité recherche. Mais YooGoo c'est aussiUn site webBut du Site webLe site web doit présenter le projet. On doit y trouver toutes les informations du projet. Pour cela, il nous faut une page de news évoluée. Les différentes versions du projet ainsi que les sources doivent aussi être accessibles. N'oublions pas non plus la documentation du projet qui doit pouvoir être consultée. Pour les membres du projet, le site web est un pilier principal puisqu'il contient tout le travail de l'équipe accessible de n'importe où. Le couple PHP/SQL nous parait une bonne solution pour mettre en place un tel site.HTML/PHP/SQLPHP est un langage qui permet de générer du code HTML. Seul le serveur interprète le code. Pour le client, il n'y a aucune différence, il reçoit du code HTML. Une page comportant du code PHP doit comporter l'extension .php (.php3) pour que le serveur web l'interprète. Pour insérer du code PHP dans une page, on utilise la balise
ex: echo
Les variables en PHP commencent toutes avec un '$'. Il est
possible d'initialiser certaines variables en appelant la page
avec la syntaxe suivante.
mapage.php?var1=42;var2=53
Il est ainsi possible de transmettre des informations à d'autres
pages. PHP possède un add-on qui permet de se connecter à une base
SQL. SQL est un protocole permettant d'envoyer des requêtes à une
base de donnée (les plus utilisées : MySQl, Oracle et MS SQL).
L'instruction pour récupérer des données est:
SELECT
Par exemple si on veut récupérer le Nom et la profession de toutes
les personnes de 18 ans depuis la base user, on envoiera
l'instruction:
SELECT Name,Job FROM user WHERE age=18
En créant les bonnes bases, on peut rendre le couple PHP/SQL très
puissant. Les principaux scripts du site web sont :
id title text date .....
On récupère ensuite l'ensemble des éléments et on les affiche avec
une boucle while toute simple. Alors qui aurait fallu recopier le
code à chaque fois si on avait utilise du HTML normal (vive PHP).
PHPMyAdminPour gérer la base SQL, la plupart des hébergeur possèdent un outil qui s'appelle PHPMyAdmin.PHPMyAdmin est un outil sécurise qui permet d'avoir une vue graphique d'une base SQL. Il permet d'avoir accès facilement au commande de base de SQL ajout, suppression et recherche. Il permet aussi à l'utilisateur d'envoyer ses propres requêtes. PHPNukePour le site web, nous ne voulions pas avoir trop de travail graphique à faire. Ce n'est effectivement pas le but du projet. Bien que PHP nous aide dans cette tache, il nous semblait difficile de faire un site web sans beaucoup toucher aux logiciels graphiques. Et puis, nous avons trouvé PHPNuke. PHPNuke est un ensemble de scripts PHP qui permettent de crée un site web PHP sans quasiment toucher une ligne de code. PHPNuke nous a surtout été utile pour les fonctions pour créer l'interface graphique.Nous avons utilise PHPNuke 5.0 pour la création de YooGoo.com. Les plus utiles des fonctions sont celles qui permettent de créer des cadres. Ca parait bête mais pour cela, il faut faire un tableau 3x3 où les cellules du bord contiennent les images des bordures. Et surtout, il faut avoir un ensemble d'images dont les dimensions sont calculées pour qu'elles correspondent avec les dimensions du tableau. Bref, ces fonctions nous ont épargné tout ce calcul laborieux. PHPNuke possède aussi une interface pour l'administration du site web. Néanmoins, nous n'utilisons pas cette interface. Tout d'abord parce que nous avons beaucoup modifié PHPNuke pour nos besoins et que les scripts d'administrations ne sont plus compatibles. Ensuite, nous préférons utilise PHPMyAdmin qui demande une meilleure compréhension du code mais offre plus de possibilités. MIG et XitiNous avons aussi utilisé MIG, un script permettant de créé des galeries de Photos. MIG nous permet de mettre en ligne rapidement les photos numériques de Danao. Le script que nous avons utilisé était quasiment parfait pour nos besoins, nous avons donc fait que très peu de changement dessus.Par curiosités, nous voulions savoir qui visite yoogoo.com. Nous utilisons pour cela le très célèbre Xiti. Xiti s'utilise en ajoutant simplement un petit morceau de JavaScript dans son code HTML. Xiti permet de savoir de nombreuses informations sur les internautes qui visitent le site. Il est vrai que Xiti emmène un petit cote ludique au pauvre webmaster. YooGoo a connu une croissance supérieure a 1000% entre Novembre et Décembre. Nous affichons maintenant 55 visiteurs mensuels. Notre part de marché à l'étranger à beaucoup augmenté puisse que un tiers de nos visiteurs sont étranger (en particulier les USA, la Chine et l'Australie...). C'est vraiment super Xiti. Choix de l'hébergeurL'utilisation de PHP réduit énormément le choix des hébergeur. Au début nous utilisions Free.fr. Mais, nous avons été déçus par la lenteur de la connexion WWW et FTP. De plus, Free, n'accepte que PHP3 alors, que la plupart des exemples de codes se trouvent en PHP4. La grosse de différence entre PHP3 et PHP4 est que l'extension des fichiers doit être .php3 dans le premier cas et .php dans le second. Il faut donc à chaque fois modifier les extensions de tous les fichiers ainsi que toutes les références à ces fichiers. Nous avons donc essayé multimania. Multimania offre une gestion PHP4 mais le débit n'est pas beaucoup plus important que free et nous eu la surprise de voir une publicité sur notre site. Nous pensons donc utilise le serveur UNIX de Zapata qui est prêt pour héberger un site PHP4.Une machineLe nom de domaine YooGoo.comLors de la création du projet nous avions décidé de réalisé un projet aux apparences sérieuses et professionnel. C'est dans cet esprit que nous avons monté un serveur Unix réalisant la plupart des services indispensables à une petite entreprise.Nous avons commencé par acheter YooGoo.com chez Gandi (www.gandi.net) pour 99fr. Gandi propose l'enregistrement du nom de domaine ainsi qu'un DNS (Domain Name Server). Malheureusement une telle configuration ne nous satisfaisait pas car le nom de notre site web restait yoogoo.multimania.com et non www.yoogoo.com. De plus il nous était impossible de profiter pleinement du domaine yoogoo.com. Nous avons alors décidé de monter notre propre DNS. Le DNS qui a été installé est Named dans sa derniere version (v9.2.0a2). Ainsi nous sommes libres d'organisé notre sous domaine comme bon nous semble. L'état actuel est :
IN NS Zapserv.yoogoo.com.
IN MX 10 mail.yoogoo.com.
;
Zapserv IN A 195.132.224.69
www IN CNAME Zapserv.yoogoo.com.
zapata IN CNAME Zapserv.yoogoo.com.
danao IN CNAME danao.no-ip.com.
hargos IN CNAME hargos.no-ip.com.
ftp IN CNAME Zapserv.yoogoo.com.
mail IN CNAME danao.no-ip.com.
(extrait de /etc/namebd/yoogoo.com fichier de configuration du
domaine yoogoo.com)
C'est-à-dire Zapserv (le serveur principal) qui fait office de DNS a comme alias ftp, Zapata et www. Le mail @yoogoo.com est redirigé sur la machine de Franck (danao.no-ip.com) ainsi que mail.yoogoo.com. Ainsi que hargos.yoogoo.com est redirigé vers hargos.no-ip.com. La machine et ses servicesLa machine qui nous sert actuellement de serveur est un PC Compaq, Pentium 120Mhz, avec 16MB de Ram, et un disque dur de 800MB, il est relié à Internet par une connexion par câble (Noos) avec un débit de 512k descendant et 128k ascendant. Cette machine est sous NetBSD 1.5 et sert de passerelle et pare-feu au réseau local de Marco (l'administrateur de la machine). Pour cela elle utilise IPNAT, IPFilter et l'IP forwarding (aussi appelé IP Masquerading). Au vue de la configuration de la machine il est clair que la charge de cette machine devra être réduite au minimum, et que le futur serveur de chat YooGoo ne tournera pas sur cette machine. (REM : Cette machine est un vrai serveur, elle est allumée 24h/24, 7j/7).Comme on peut le constater il existe un serveur de mail pour les adresses du type login@yoogoo.com , celui ci est sur la machine de Franck. Mais il faut l'avoué cette fonction nous sert plus pour le prestige (et le coté professionnel) que pour autre chose car nous n'utilisons pas ces adresses (du moins pour l'instant). Néanmoins il existe déjà une interface graphique pour enregistrer un compte accessible au mail.yoogoo.com :81. Il existe aussi un ftp privée sur la machine Zapserv qui nous sert pour échanger les fichiers, pour mettre les dernières versions de notre travail, et pour rendre les rapports. On essaye de le maintenir le plus a jour possible, ainsi chaque membre du groupe peut accéder a l'ensemble du travail quand il le désir. C'est un élément important car pendant les vacances il nous est parfois difficile de communiquer (et les gros fichier par mail ne sont pas acceptés, merci EPITA). Pour ce qui est de la technique du ftpd, il est lancé a partir de inetd, ainsi il n'est lancé que lorsqu'il y a des connections. De plus il est chrooted afin de protéger l'accès au fichier système. Par ailleurs, il est aussi possible d'accéder au serveur par ssh si on a besoin de faire des opérations un peut plus complexes. Cela peut permettre aussi aux membres du groupe qui n'ont pas d'Unix chez eux d'en avoir un où ils peuvent s'amuser (sans risquer de close compte). La machine n'ayant pas d'écran, le ssh est aussi le seul moyen de l'administrer (très pratique quand on est en vacances aussi). Enfin vient le serveur web. Comme on peut le voir à partir de la table du DNS, www.yoogoo.com est redirigé sur Zapserv. Le serveur web est apache, recompilé avec le support du php4. Puisque notre site web se base sur PHPNuke qui utilise mySQL, un serveur mySQL a été recompilé et installé pour permettre un bon fonctionnement du site web. De plus pour une administration plus aisée de mySQL, PhpMyAdmin a été installé. Un alias pour www.yooogoo.com/phpmyadmin/ a été crée, et l'accès du répertoire est protégé grâce à un mot de passe, qui fonctionne par autorisation au près de apache grâce a un .htaccess. Le serveur Unix fait donc tourner Apache/php4/mySQL/PhpMyAdmin. ConclusionL'opinion de chacunFranckTout d'abord, j'ai du m'adapter au langage de programmation orienté objet C++ et apprendre à utiliser l'environnement Visual C++. De plus j'ai utilisé pour la première fois des classes et tout ce qui va avec, les constructeurs, les destructeurs, les fonctions statiques à la classe. La conception de la classe user principalement m'a permis de me familiariser avec la gestion des chaînes de caractères mais également avec la gestion des fichiers en ascii. De son côté la classe canal m'a permis d'approfondir mes connaissances dans les pointeurs en C et C++, et de pouvoir les manipuler.Les recherches effectuées sur le net m'ont fait connaître l'initialisation de Winsock, les fonctions de base telles que l'émission et la réception de données ainsi que les différents modes de fonctionnement. De plus cette année le travail en groupe est mieux organisé ce qui rend le développement du projet plus efficace. Ainsi chacun comprend le principe global du serveur mais également est capable de lire et comprendre le code des autres membres du groupe. FolkenLes expériences que m'ont apportées le travail sur le projet YooGoo sont essentiellement de deux natures différentes. La première est essentiellement humaine : j' ai enfin découvert le travail d'équipe avec des personnes sérieuses et motivées. Au sein du groupe de projet, l'ambiance est surtout au travail (peut-être trop, même), on peut constater que l'on a affaire à des passionnés intimement liés par le désir de création, mus par la soif de connaissance et de techniques (savoir et savoir-faire, pour être plus abstrait) dans le domaine informatique. La tâche est passionnante et l'environnement assez motivant. De mon côté, je n' ai aucun sentiment de regret: ma tâche est accomplie dans les délais, sinon un peu plus que prévus.La deuxième, d'ordre plus technique, est les connaissances sur la création de base de données utilisant les AVL et diverses méthodes. J' ai également appris à mieux répartir mon temps de travail et mieux organiser mes méthodes de production. Cette expérience m'a également appris que même si certains algorithmes peuvent être déjà écris, il reste beaucoup de chemin à parcourir afin d' obtenir un résultat final satisfaisant. Au final, ces derniers sont d' ailleurs fort satisfaisants. HargosTechniquement tout d'abord, j'ai appris le travail de webmaster. Pour cela, j'ai appris les langages HTML et PHP dont je ne m'était jamais servi jusqu'à présent. J'ai appris à utiliser des requêtes SQL. J'ai appris à référencer un site web. Le projet m'a permis de mettre aux C++ dans un projet de plus grande envergure que les TPs. Cette année nous avons abordé le projet avec beaucoup plus de professionnalisme que l'année dernière. Avec le protocole, j'ai appris à concevoir et à rédiger une documentation technique. Pour la planification du projet, nous nous sommes beaucoup mieux débrouillé que l'année dernière et nous avons beaucoup mieux repartis les tâches. La conception de YooGoo m'as aussi permit d'apprendre beaucoup de choses sur les réseaux et leur fonctionnement. Le projet est conforme au planning et l'entente dans le groupe est bonne. J'espère que ça va durer.ZapataLe travail sur la cryptographie a été très intéressant, malheureusement certaines opérations semblaient sortis de nulle part. De plus le travail sur la classe de nombre infinis m'as permis d'apprendre le C++, et de voir plus en détails la puissance des objets, tandis que les opération sur les bits dans le DES m'on fait travaillé au plus bas niveau.Nouveau en programmation réseau, j'ai découvert les bases de Winsock, qui m'ont permis de réaliser un serveur stable et sans erreur. Il me reste à découvrir les fonctions avancées de Winsock. De plus j'ai eu une petite introduction de ce qu'est un thread, comment ça marche, comment on s'en sert et à quoi ça sert. Ce fut un travail somme toute très technique mais sûrement très utile pour l'avenir. De plus l'administration du serveur de YooGoo m'as permis d'agrandir énormément mes compétences en Unix, qui au début de l'année était bien pauvres. Cette année s'annonce très passionnante car les sujets abordés sont variés. Jusqu'ici il m'a semblé être dans la peau d'un administrateur réseau et j'ai maintenant une idée plus précise de ce travail. Cette expérience me permettra peut-être de faire un choix mieux pesé dans mon orientation future. Le mot de la finLe projet de l'année dernière porte ses fruits. La division du travail n'a pas, jusqu'à présent, posé de problèmes. Nous avons réussit à concevoir une architecture dont nous sommes sûrs (ce que nous n'avions pas fait l'année dernière). Cela nous a permis de travailler chacun sur une partie. Pour la prochaine soutenance, nous devrons réunir les codes. Nous allons pouvoir tester la cohérence de notre code. Si chacun a suivit les normes qui lui étaient imposés, il ne devrait pas y avoir de problèmes.AnnexesProtocole
/*************************************************************************
* Fichier: Proto.h *
* Description: Protocole de YooGoo, decrit les fonctions *
* reconnus par les parseurs. Du cote client, comme du coté *
* serveur. *
* Date: Janvier 2002 *
**************************************************************************
////////////////////////////////////////////
/******************************************/
/* Les Commandes recue par le serveur */
/******************************************/
////////////////////////////////////////////
/*************************************************************************
* Commande recue: *
* chId User [Pass] *
* Permet de changer de Pseudo. Si le pseudo est deja enregisté, on doit *
* spécifier un mot de passe. Dans le cas ou le mot de passe n'est pas *
* specifié, la fonction doit etre appellée avec "". 'connect' previent *
* les utilisateur ayant une conversation privée et etant connectés *
* sur le meme canal du changement d'identité par un message 'chId' *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_NickUnregistered *
* Err_NeedMoreParams *
* Err_Password *
* Err_NickInUse *
* Err_NickNotAccepted *
**************************************************************************
int chId(CString user, pass);
/*************************************************************************
* Commande recue: *
* reg User Pass *
* Permet de proteger un compte utilisateur par un mot de passe. Il n'y *
* a pas besoin d'etre connecté sous ce nom pour l'enregister. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_UserRegistered *
* Err_NickInUse *
* Err_NickNotAccepted *
**************************************************************************
int reg(CString user, pass);
/*************************************************************************
* Commande recue: *
* chNick nouveau_pseudo *
* Permet de changer le champ 'Nick' de son profile. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_NickInUse *
* Err_NickNotAccepted *
* Err_NickRegistered *
**************************************************************************
int chNick(CString user, new_nick);
/*************************************************************************
* Commande recue: *
* chStatus {OnLine|Away|DND|Invisible} *
* Permet de changer son status. chStatus met a jour l'index des status *
* Attention: chStatus ne s'occuppe pas de la procedure de deconnection *
* si 'OffLine' lui est envoyé *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_InvalidStatus *
*************************************************************************/
#define OFFLINE 1
#define ONLINE 2
#define AWAY 3
#define DND 4
#define INVISIBLE 5
int chStatus(CString User; int status);
/*************************************************************************
* Commande recue: *
* chMail [nouveau_mail] *
* Permet de changer le champ 'Mail' de son profile. *
* Celui-ci peut-etre vide *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_InvalideMail *
*************************************************************************/
int chMail(CString user, new_mail);
/*************************************************************************
* Commande recue: *
* chName [nouveau_nom] *
* Permet de changer le champ 'Nom' de son profile. *
* Celui-ci peut-etre vide *
* Valeur Renvoyées: *
* Inf_Ok *
*************************************************************************/
int chName(CString user, new_Name);
/*************************************************************************
* Commande recue: *
* chFName [nouveau_prénom] *
* Permet de changer le champ 'Prénom' de son profile. *
* Celui-ci peut-etre vide *
* Valeur Renvoyées: *
* Inf_Ok *
*************************************************************************/
int chFName(CString user, new_FName);
/*************************************************************************
* Commande recue: *
* chSex {Male|Female} *
* Permet de changer le champ 'Sexe' de son profile. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_InvalidSex *
*************************************************************************/
#define MALE 1
#define FEMALE 2
int chSex(CString user; int new_sex);
/*************************************************************************
* Commande recue: *
* chState [nouveau_pays] *
* Permet de changer le champ 'Pays' de son profile. *
* Celui-ci peut-etre vide *
* Valeur Renvoyées: *
* Inf_Ok *
*************************************************************************/
int chState(CString user, new_state);
/*************************************************************************
* Commande recue: *
* chTown [nouvelle_ville] *
* Permet de changer le champ 'Ville' de son profile. Celui-ci peut-etre *
* vide. *
* Valeur Renvoyées: *
* Inf_Ok *
*************************************************************************/
int chTown(CString user, new_Town);
/*************************************************************************
* Commande recue: *
* chLikeUser user {0|1|2|...|8|9} *
* Permet de changer la confiance d'un utilisateur. *
* *
* 0 = liste noire *
* 1 = aucun renseignements *
* 2 = utilisateur normal *
* 3 = *
* .... *
* 9 = tous les pouvoirs *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_NickUnregistered *
* Err_NeedMoreParams *
* Err_InvalideLevel *
*************************************************************************/
int chLikeUser(CString user, user2; int like);
/*************************************************************************
* Commande recue: *
* chPass nouveau_pass *
* Permet de changer le champ 'Password' de son profile. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
*************************************************************************/
int chPass(CString user, new_Pass);
/*************************************************************************
* Commande recue: *
* chAutoReply ["message"] *
* Permet d'envoyer un message automatique au personne essayant de parler *
* a l'utilisateur. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
*************************************************************************/
int chAutoReply(CString user, message);
/*************************************************************************
* Commande recue: *
* join canal [password] *
* Permet de se connecter a un canal. Les autres utilisateur sont avertis *
* et la liste des connectés du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChannelCreated *
* Err_NeedMoreParams *
* Err_Password *
* Err_BannedFromChannel *
*************************************************************************/
int join(CString user, chanel, password);
/*************************************************************************
* Commande recue: *
* part canal *
* Permet de se deconnecter d'un un canal. Les autres utilisateurs sont *
* avertis et la liste des connectés du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChannelKilled *
* Inf_NotConnectedChan *
* Err_NeedMoreParams *
*************************************************************************/
int part(CString user, chanel);
/*************************************************************************
* Commande recue: *
* query pseudo ["message"] *
* Permet d'ouvrir une discution privée avec un autre utilisateur. Une *
* demande connection est envoyé au receiver. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ConnectionRefused *
* Err_NeedMoreParams *
*************************************************************************/
int query(CString user, user, message);
/*************************************************************************
* Commande recue: *
* query_direct pseudo ["message"] *
* Permet d'ouvrir une discution privée en peer-to-peer avec un autre *
* utilisateur. Une demande connection est envoyé au receiver. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ConnectionRefused *
* Err_NeedMoreParams *
*************************************************************************/
int query_direct(CString user, user, message);
/*************************************************************************
* Commande recue: *
* msg {pseudo|canal} "message" *
* Envoie un message vers un canal ou un pseudo. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_NotConnectedChan *
*************************************************************************/
int msg(CString user, receiver, message);
/*************************************************************************
* Commande recue: *
* op canal pseudo *
* Donne les privileges d'Op a un User. Les autres utilisateurs sont *
* avertis et la liste des Op du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChanNotRegistered *
* Inf_UserNotRegistered *
* Inf_Chan&UserNotRegistered *
* Inf_AlreadyOp *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int op(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* deop canal pseudo *
* Enleve les privileges d'Op a un User. Les autres utilisateurs sont *
* avertis et la liste des Op du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_UserNotOp *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int deop(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* ban canal pseudo *
* Banni un Utilisateur du canal. Les autres utilisateurs sont avertis et *
* la liste des Bannis du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChanNotRegistered *
* Inf_UserNotRegistered *
* Inf_Chan&UserNotRegistered *
* Inf_AlreadyBan *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int ban(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* deban canal pseudo *
* Debanni un Utilisateur du canal. Les autres utilisateurs sont avertis *
* et la liste des Bannis du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_UserNotBan *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int deban(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* ChanRoot canal pseudo *
* Donne les privileges de ChanRoot a un User. Les autres utilisateurs *
* sont avertis et la liste des ChanRoot du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChanNotRegistered *
* Inf_UserNotRegistered *
* Inf_Chan&UserNotRegistered *
* Inf_AlreadyChanRoot *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int chanroot(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* deChanRoot canal pseudo *
* Enleve les privileges de ChanRoot a un User. Les autres utilisateurs *
* sont avertis et la liste des ChanRoot du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_UserNotChanRoot *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int dechanroot(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* kick canal pseudo *
* Kick un Utilisateur du canal. Les autres utilisateurs sont avertis et *
* la liste des Users du canal est mise a jour *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_UserNotConnected *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int kick(CString user, chanel, receiver);
/*************************************************************************
* Commande recue: *
* chMod canal {Topic|Name| *
* Kick|Op|DeOp|Ban|DeBan} {on|off} *
* Permet de changer les privileges des Ops sur le canal. Ne peut etre *
* utilisé que par un chanRoot. *
* *
* Valeur Renvoyées: *
* Inf_Ok *
* Inf_ChanelUnregistered *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
* Err_InvalidPrivileges *
* Err_InvalidStatus *
*************************************************************************/
#define TOPIC 1
#define NAME 2
#define KICK 3
#define OP 4
#define DEOP 5
#define BAN 6
#define DEBAN 7
#define OFF 0
#define ON 1
int chMod(CString user, chanel; int status, stat);
/*************************************************************************
* Commande recue: *
* chTopic canal "Sujet" *
* Permet de changer le sujet du canal *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int chTopic(CString user, chanel, Topic);
/*************************************************************************
* Commande recue: *
* chName canal Name *
* Permet de changer le Nom du canal *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
*************************************************************************/
int chName(CString user, chanel, Name);
/*************************************************************************
* Commande recue: *
* chKeep canal {on|off} *
* Permet de garder ou nom le canal en mémoire si il n'y a pas de *
* connectés *
* Valeur Renvoyées: *
* Inf_Ok *
* Err_NeedMoreParams *
* Err_Privileges *
* Err_ChanNotExist *
* Err_InvalidStatus *
*************************************************************************/
#define OFF 0
#define ON 1
int chKeep(CString user, chanel; int stat);
/*************************************************************************
* Commande recue: *
* about *
* Renvoie les noms des createurs de YooGoo *
* Out contient la valeur renvoyée *
* Valeurs Renvoyées: *
* Rpl_About *
*************************************************************************/
int about(CString Out);
/*************************************************************************
* Commande recue: *
* help *
* Renvoie un texte d'aide. *
* Out contient le texte renvoyé *
* Valeurs Renvoyées: *
* Rpl_About *
*************************************************************************/
int help(CString Out);
/*************************************************************************
* Commande recue: *
* version *
* Renvoie des informations sur la serveur *
* Out contient la valeur renvoyée *
* Valeurs Renvoyées: *
* Rpl_Version *
*************************************************************************/
int version(CString Out);
/*************************************************************************
* Commande recue: *
* What Cannal *
* Renvoie des informations sur le canal *
* Out contient la valeur renvoyée. *
* Valeurs Renvoyées: *
* Rpl_What *
* Err_NeedMoreParams *
*************************************************************************/
int what(CString chanel; CStringList Out);
/*************************************************************************
* Commande recue: *
* Who Pseudo *
* Renvoie des informations sur le pseudo *
* Out contient la valeur renvoyée *
* Valeurs Renvoyées: *
* Rpl_Who *
* Err_NeedMoreParams *
*************************************************************************/
int who(CString User; CStringList Out);
/*************************************************************************
* Commande recue: *
* Search [Nick=Pseudo] [Age=Age] *
* [Birth=Date_Naissance] [Town=Ville] *
* [Sex={Male|Female}] *
* [Status={OnLine|OffLine}] *
* Recherche les utilisateurs correspondant aux critères. *
* Out contient la valeur renvoyée *
* *
* Valeurs Renvoyées: *
* Rpl_UserNotFound *
* Rpl_UserFound *
* Err_NeedMoreParams *
* Err_InvalidArguments *
*************************************************************************/
int search(CString Nick,Birth,Town,State; int Sex, Status; CStringList Out);
/*************************************************************************
* Commande recue: *
* List *
* (Si on est motive, on pourra gerer la recherche parmis les nom des *
* canaux). Renvoie la liste des canaux du serveur Out contient la *
* valeur renvoyée *
* Valeurs Renvoyées: *
* Rpl_List *
*************************************************************************/
int list(CStringList Out);
/*************************************************************************
* Commande recue: *
* Quit *
* Se deconnecte du serveur proprement *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// Cette fonction est a voir avec la gestion du thread, etc...
int disconnect(CString User);
/*************************************************************************
* Commande recue: *
* Iam Nick Command *
* Execute la commande en tant que Nick. Cette commande est reservée a *
* Root *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
int iam(CString User, CString command);
/*************************************************************************
* Commande recue: *
* Rpl_AcceptQuery Pseudo *
* Accepte la demande de conversation privée d'un utilisateur *
* *
* Valeurs Renvoyées: *
* Inf_Ok *
* Err_NoQueryAsk *
*************************************************************************/
int acceptquery(CString User, User2);
/*************************************************************************
* Commande recue: *
* Rpl_AcceptDirectQuery Pseudo *
* Accepte la demande de conversation privée d'un utilisateur *
* *
* Valeurs Renvoyées: *
* Inf_Ok *
* Err_NoQueryAsk *
*************************************************************************/
int acceptdirectquery(CString User, User2);
/*************************************************************************
* Commande recue: *
* Rpl_DenieQuery Pseudo *
* Accepte la demande de conversation privée d'un utilisateur *
* * *
* Valeurs Renvoyées: *
* Inf_Ok *
* Err_NoQueryAsk *
*************************************************************************/
int deniequery(CString User, User2);
/*************************************************************************
* Commande recue: *
* Rpl_DenieDirectQuery Pseudo *
* Accepte la demande de conversation privée d'un utilisateur *
* *
* Valeurs Renvoyées: *
* Inf_Ok *
* Err_NoQueryAsk *
*************************************************************************/
int deniedirectquery(CString User, User2);
////////////////////////////////////////////
/******************************************/
/* Les Commandes envoyées par le serveur */
/******************************************/
////////////////////////////////////////////
/*************************************************************************
* Commande envoyee: *
* msg pseudo message [canal] *
* Donne le message d'un utilisateur sur le canal. Si le canal est omis, *
* le message est privé *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Join canal pseudo *
* Indique qu'un utilisateur s'est connecte *
* sur le canal *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Part canal pseudo *
* Indique qu'un utilisateur s'est deconnecte du canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* chTopic canal message *
* Donne le nouveau sujet du canal *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Op canal pseudo *
* Indique qu'un utilisateur a ete nommé Op sur le canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* DeOp canal pseudo *
* Indique qu'un utilisateur a perdu son status d'Op sur le canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* ChanRoot canal pseudo *
* Indique qu'un utilisateur a ete nommé Chanroot sur le canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* DeChanRoot canal pseudo *
* Indique qu'un utilisateur a perdu son status de ChanRoot sur le canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Ban canal pseudo *
* Indique qu'un utilisateur a ete banni du canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* DeBan canal pseudo *
* Indique qu'un utilisateur a ete debanni du canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Kick canal pseudo1 pseudo2 *
* Indique qu'un utilisateur s'est fait kické du canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Birthday pseudo *
* Indique que c'est l'anniversaire d'un utilisateur. Ce message n'est *
* envoye qu'une fois par connection *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* AskQuery pseudo ["message"] *
* Permet d'ouvrir une discution privée avec un autre utilisateur. Une *
* demandeconnection est envoyé au receiver. *
* *
* Valeur Renvoyées: *
* Rpl_AcceptQuery Pseudo *
* Rpl_DenieQuery Pseudo *
* Err_NeedMoreParams *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* AskQuery_direct pseudo ["message"] *
* Permet d'ouvrir une discution privée en peer-to-peer avec un autre *
* utilisateur. Une demande connection est envoyé au receiver. *
* *
* Valeur Renvoyées: *
* Rpl_AcceptDirectQuery Pseudo *
* Rpl_DenieDirectQuery Pseudo *
* Err_NeedMoreParams *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Les retours sont des messages qui renvoie l'information demandée par *
* l'utilisateur *
*************************************************************************/
/*************************************************************************
* Commande envoyee: *
* Rpl_UserNotFound *
* Indique que votre recherche n'as obtenu aucun resultat *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_UserFound Nick1[, Nick2[, ...]] *
* Indique que votre recherche a obtenue des resultats *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_List Canal1[, Canal2[, ...]] *
* Indique que le message est la liste des cannaux *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_Version String_Version *
* Indique que le message contient les infos sur le serveur *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_Who Nick, Nom, Prenom, BirthDay.... *
* Indique que le message contient les info sur un utilisateur *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_What Nom, Sujet, nbr_connecte... *
* Indique que le message contient les info sur un canal *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Commande envoyee: *
* Rpl_about string_about *
* Indique que le message contient les infos sur le protocole YooGoo *
* *
* Valeurs Renvoyées: *
* <aucune> *
*************************************************************************/
// pas de fonction appellée sur le serveur
/*************************************************************************
* Les erreurs 0** indique que la fonction s'est bien deroulée mais que *
* la fonction a une information a renvoyer *
*************************************************************************/
/* La commande s'est déroulée normallement */
#define Inf_Ok 000
/* Indique que le canal que l'utilisateur vient de joindre vient d'etre *
* créé grace a lui. Cela signifie qu'il est le premier utilisateur et *
* qu'il acquiert les droits de chanroot */
#define Inf_ChannelCreated 001
/* Indique que vous etiez le dernier utilisateur et que le canal a ete *
* killed */
#define Inf_ChannelKilled 002
/* Indique que vous avez choisit un pseudo qui n'est pas enregistré */
#define Inf_NickUnregistered 003
/* Indique que vous avez choisit un canal qui n'est pas enregistré */
#define Inf_ChanNotRegistered 004
/* Indique que vous avez choisit un nick et un canal qui ne sont pas *
* enregistrés */
#define Inf_Nick&ChanNotRegistered 005
/* Indique vous essayer de kicker un utilisateur qui n'est pas connecté *
* au canal */
#define Inf_UserNotConnected 006
/* Indique vous essayer de deOp un utilisateur qui n'est pas Op sur le *
* canal */
#define Inf_UserNotOp 007
/* Indique vous essayer de deBannir un utilisateur qui n'est pas banni du*
* canal */
#define Inf_UserNotBan 008
/* Indique vous essayer de deChanRoot un utilisateur qui n'est pas *
* ChanRoot sur le canal */
#define Inf_UserNotChanRoot 009
/* Indique vous essayer d'Op un utilisateur qui est dej Op sur le canal */
#define Inf_AlreadyOp 010
/* Indique vous essayer de Bannir un utilisateur qui est deja banni du *
* canal */
#define Inf_AlreadyBan 011
/* Indique vous essayer de ChanRoot un utilisateur qui est deja *
* ChanRoot sur le canal */
#define Inf_AlreadyChanRoot 012
/* Indique votre demande discution privée a été rejetée */
#define Inf_ConnectionRefused 013
/*************************************************************************
* Les erreurs 4** sont des erreur fatales. Si elles sont renvoyées, cela*
* signifie que la commande a echouée *
*************************************************************************/
/* La commande envoyée n'existe pas. Cette erreur est renvoye par le *
* parseur */
#define Err_CommandNotFound 400
/* La commande envoyée n'as pas pu etre parsée car elle ne contient pas *
assez d'arguments. Cette erreur est renvoye par le parseur */
#define Err_NeedMoreParams 401
/* Le canal demandé n'existe pas */
#define Err_ChanNotExist 402
/* l'utilisateur n'etes pas connecté sur le canal demandé */
#define Err_NotConnectedChan 403
/* Vous etes bannis de ce canal */
#define Err_BannedFromChannel 404
/* Vous n'avez pas les privilège requis pour executer cette action */
#define Err_Privileges 405
/* Vous essayez de DeBannir un utilisateur qui n'est pas banni */
#define Err_NotBanned 406
/* Vous essayez de DeOp un utilisateur qui n'est pas Op */
#define Err_NotOp 407
/* Vous essayez de DeChanRoot un utilisateur qui n'est pas ChanRoot */
#define Err_NotChanRoot 408
/* Vous essayez d'utiliser un nick qui est deja enregistré */
#define Err_NickRegistered 409
/* Le pseudo que vous essayer d'utiliser est deja attribué */
#define Err_NickInUse 410
/* Le pseudo que vous essayer d'utiliser n'est pas valide */
#define Err_NickNotAccepted 411
/* Les arguments de votre fonction search ne sont pas valides. Cette *
erreur est renvoye par le parseur */
#define Err_InvalidArguments 412
/* Le mail que vous essayer d'utiliser n'est pas valide. Cette erreur est*
* renvoye par le parseur */
#define Err_InvalideMail 413
/* Le sexe que vous avez envoyé en argument n'est pas valide. Cette *
* erreur est renvoye par le parseur */
#define Err_InvalidSex 414
/* Le status que vous avez envoyé en argument n'est pas valide. Cette *
* erreur est renvoye par le parseur */
#define Err_InvalidStatus 415
/* Le niveau que vous avez envoyé en argument n'est pas valide. Cette *
* erreur est renvoye par le parseur */
#define Err_InvalideLevel 416
/* Le mot de passe que vous avez envoyé n'est pas valide */
#define Err_Password 417
/* Vous essayer de repondre a une demande d'amitie qui n'existe pas */
#define Err_NoQueryAsk 418
| ![]() |
|
|