maitretarot-devel-fr
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Maitretarot-devel-fr] nouveau protocole


From: nico
Subject: Re: [Maitretarot-devel-fr] nouveau protocole
Date: Tue, 17 Dec 2002 22:34:23 +0100

Globalement, le truc le plus simple, c'est : en cours de jeu, le serveur
envoie toutes les données (après que chaque joueur est joué) qu'il a
avec un flag "à toi de jouer". Comme ça, il n'y a qu'un seul type de
message.

On mets un timeout sur la réponse, tu renvoie 2-3 fois, puis après tu
envoie le paquets à tous avec un flags en "erreur". C'est ça le vrai
stateless:)

Il faut envoyer ses cartes restant, des flags (erreur ou pas, son tour
de jouer ou pas,...), les plis (l'équipe du preneur puis l'autre), le
paris, les annonces, tout quoi. 1 seul message avec l'état dedans
(erreur ou pas, etc...)

nicO

On 16 Dec 2002 22:06:26 +0100
philippe brochard <address@hidden> wrote:

> Yves Mettier <address@hidden> writes:
> 
> > On 16 Dec 2002 19:00:30 +0100
> > philippe brochard <address@hidden> wrote:
> > 
> > > 
> > > Bonjour a tous,
> > > 
> > > suite a une discution avec Yves sur IRC, nous avons decider
> > > de changer de protocole pour faire en sorte que la partie
> > > gestion de l'ordre du jeu soit initiee par le serveur et
> > > non pas dans le client (ou la lib client) comme c'est le
> > > cas actuelement.
> > > 
> > > Pour cela, voila la liste des fonctions dont ont besoin
> > > les clients :
> > > 
> > > Vocabulaire :)
> > >   get : le client a besoin d'une information du serveur
> > >   set : le client donne une valeur au serveur.    
> > 
> > Euh, vu que le client deviendra une sorte d'objet manipule par le
> > serveur, c'est plutot le contraire.
> > Exemple: quand le serveur fait appel a get_hand_cards() du client,
> > il ne demande pas au client les cartes. Il fait le contraire: il les
> > fournit.
> > 
> eh, eh, tout depend tu cote ou tu te place :)
> mais, bon va pour le sens inverse.
> 
> > D'autre part, get et set sont des mots generalement associes a des
> > variables. Or d'apres notre discussion, on ne travaille pas avec un
> > systeme de variables mais un systeme de commandes (on avait parle de
> > procedures a cause de l'analogie avec les rpc).
> > Le vocabulaire devient donc du vocabulaire d'action, comme compute,
> > exec, init, etc.
> > 
> ou get : prend   set : envoi/fixe
> set_bid : le client donne son enchere
> get_card : le client prend les cartes qu'il a en mains
> (se sont des actions, non ?)
> 
> > > 
> > > 
> > > Identification :
> > > --------------
> > > 
> > >   * {Nick, } set_identity_client (void)
> > > 
> > >   Cette fonction est appele au debut pour realiser(?) la connexion
> > >   et informer le serveur sur le client qui vient de ce connecter.
> > >   Les parametres de version ne sont pas primordial pour le client
> > >   mais il peuvent etre utiles.
> > > 
> > > 
> > >   * {void} get_resume_client (place, nombre_joueur, nick_client1,
> > >       nick_client2, nick_client3, ..., score1, score2, score3,
> > >       ...)
> > > 
> > >   Cette fonction permet d'informer le client sur les autres
> > >   joueurs. la bornes nick_client3 depend du nombre de joueur, elle
> > >   peut aller jusqu'a nick_client5 dans le cas d'un jeu a 5 joueurs
> > >   ou nombre_joueur = 5.
> > >   Les score1 a 3 (4 et 5) sont les scores totaux des precedentes
> > >   parties.
> > > 
> > > 
> > > Debut du jeu :
> > > ------------
> > > 
> > >   * void get_hand_cards (c1, c2, c3, c4, ..., c18)
> > >   
> > >   Le client recoit les cartes qu'il a en mains (c1, c2...).
> > >   Le parametre c18 peut varier de c15 a c24 suivant un jeu a 5
> > >   joueurs
> > >    ou 3 joueurs.
> > 
> > 24 parametre.
> > Si on est a 4, les 6 derniers seront undef. Si on est a 5, ce seront
> > les 9 derniers a etre a undef.
> > 
> ok, j'ai laisse des ... pour ne pas rentrer dans le detail
> du codage (on pouvais aussi utiliser des tableaux dynamiques,
> ou fixer le nombre de parametre au depart, ou ...)
> 
> > > 
> > > 
> > > Encheres :
> > > --------
> > > 
> > >   * {enchere} set_bid (e1, e2, e3, ...)
> > > 
> > >   Cette fonction est appelee si le client doit faire une
> > >   enchere.
> > >   Le serveur lui fourni les encheres des autres joueurs
> > >   (e1,e2,e3,e4,e5 enchere des clients 1 2 3 4 5 suivant le
> > >   nombre de joueurs) 
> > > 
> > > 
> > >   * void other_bid (place, e1, e2, e3 , ...)
> > > 
> > >   Cette fonction est appelee quand un autre joueur est en
> > >   train de faire sont enchere. Le serveur fourni la place du
> > >   joueur qui est en train de faire sont enchere, ainsi que les
> > >   encheres deja faites. 
> > > 
> > > 
> > > Chien :
> > > -----
> > > 
> > >   * {c1, c2, ..., c6} set_chien (pc1,pc2,...,pc6)
> > > 
> > >   Cette fonction est appellee si le client doit faire un chien
> > >   (petite ou garde).
> > >   Le serveur fourni les cartes du chien original (pc1...pc6).
> > >   Le client renvoit les cartes du chien qu'il a fait (c1...c6).
> > >   Les parametres c6 et pc6 peuvent etres c6,pc6 pour un jeu a 3
> > >   ou 4 et c3,pc3 pour un jeu a 5 joueurs.
> > >   Tant que le chien n'est pas valide, le serveur demande au client
> > >   de faire un chien.
> > > 
> > > 
> > >   * void chien_valide (c1, c2, ..., c6)
> > > 
> > >   Cette fonction est appellee si le chien fait par le client (avec
> > >   set_chien) est valide. Elle permet au client de savoir que le
> > >   serveur a accepte son chien.
> > > 
> > > 
> > >   * void other_set_chien (place, c1, c2, ..., c6)
> > > 
> > >   Cette fonction est appellee quand un autre joueur est en train
> > >   de faire son chien. Le serveur fourni la place du joueur qui est
> > >   en train de faire son chien et le chien original.
> > >   Meme reflexion que precedement sur le parametre c6 suivant le
> > >   nombre de joueur. (Ceci toujours dans le cas d'une petite ou
> > >   d'une garde).
> > > 
> > > 
> > >   * void no_chien (void)
> > > 
> > >   Cette fonction est appellee si les clients n'ont pas a faire de
> > >   chiens(garde sans, garde contre).
> > > 
> > 
> > Manque les annonces ici.
> > Tu peux deja fournir le proto des procedures, voire les implementer,
> > meme si les arguments seront initialement ignores et une valeur
> > undef est renvoyee.
> > J'ai vu que c'est plus bas dans le mail.
> > 
> oui, je les ai misent plus bas parce que je ne me souvient plus
> a quelle moment on les fais. de toute facon, c'est au serveur
> d'apppeler la fonction annonce, le client y repondra quel que
> soit le moment ou ca se passe, c'est le serveur qui impose l'ordre.
> 
> > > 
> > > Jeu des cartes :
> > > --------------
> > > 
> > >   * {card} set_card (lc1, lc2, lc3, ...)
> > > 
> > >   Cette fonction est appellee chaque fois que le client doit jouer
> > >   une
> > >    carte.
> > >   Le serveur fourni les cartes du tour precedent en parametre (lc3
> > >   varie en fonction du nombre de joueur), le client renvoit la
> > >   carte qu'il veut joueur.
> > >   Tant que la carte n'est pas valide, le serveur demande au client
> > >   de rejouer une carte.
> > > 
> > >   
> > >   * void card_valide (card)
> > > 
> > >   Cette fonction est appellee si la carte card jouee par le client
> > >   (avec set_card) est valide.
> > >   Elle permet au client de savoir que la carte card a ete acceptee
> > >   par le serveur.
> > 
> > ici, quel doit etre l'algo a mettre en place si la carte est non
> > valide?
> > 
> soit la carte est non valide et le serveur refait un appel set_card
> pour que le client joue une carte valide.
> soit la carte est valide et le serveur appel la fonction card_valide.
> 
> un algo pourrai etre :
> 
> card_is_valide = FALSE;
> while (!card_is_valide)
> {
>   /* demande la carte au client */
>   card_play = set_card ([parametres]);
> 
>   card_is_valide = test_if_carte_is_valide (card_play);
> }
> 
> /* informe le client que sa carte est valide */
> card_valide (card_play);
> 
> et pendant le while, tant que le client cherche la carte qu'il va
> jouer, les serveur fait un appel a other_set_card(place)  pour
> informer les autres joueur que le client a la place place choisi une
> carte.
> 
> > > 
> > > 
> > >   * void other_set_card (place)
> > > 
> > >   Cette fonction est appellee quand un autre joueur est en train
> > >   de choisir une carte a jouer. Le serveur fourni la place du
> > >   joueur qui est en train de joueur.
> > 
> > et la carte, non?
> > 
> quelle carte ? celle que l'autre client va jouer ? a priorie quand
> on est dans cette fonction on ne sait pas quelle carte va joue le
> client qui est en train de choisir sa carte.
> 
> cette fonction est juste la pour dire que untel choisis une carte
> (et que ca peut prendre du temps).
> 
> > > 
> > > 
> > >   * void end_of_turn (c1, c2, c3, ..., lc1, lc2, lc3, ...)
> > > 
> > >   Cette fonction est appellee a la fin d'un tour. le serveur
> > >   fourni les cartes jouees dans le tour (c1...) ainsi que les
> > >   cartes du tour precedent (lc1...).
> > >   Les bornes c3 et lc3 dependent du nombre de joueur.
> > > 
> > > 
> > >   * {announce} set_announce (a1, a2, a3, ...)
> > > 
> > >   Cette fonction est appellee lorsque le serveur a besoin de
> > >   connaitre les annonces des clients (juste apres le 1er tour, il
> > >   me semble). Il fournit les annonces des autres joueurs et le
> > >   client renvoie son annonce (s'il veut en faire une).
> > > 
> > > 
> > > Fin de partie :
> > > -------------
> > > 
> > >   * {replay} end_of_game (contract, win, score, oudlers, 
> > >                           sc1, sc2, sc3, ..., chien1, chien2,
> > >                           chien3, ...)
> > > 
> > >   Cette fonction est appellee en fin de partie si le jeu c'est
> > >   deroule normalement ou que tout le monde a passe.
> > > 
> > >   Le serveur fourni :
> > >     contract : le contrat du preneur
> > >     win : TRUE si le preneur a gagne, FALSE autrement
> > >     score : le score du preneur pour la partie
> > >     oudlers : le nombre d'oudlers du preneur
> > >     sc1, sc2, sc3 ... : les scores totaux de tous les joueurs
> > >      (score de la partie ajoute aux scores precedents, pour chaque
> > >      joueur). sc3 peut varier en fonction du nombre de joueurs.
> > >     chien1, chien2, chien3, ... : les cartes dans le chien.
> > >     chien3 peut varier en fonction du nombre de joueurs.
> > > 
> > >   Si tout le monde a passe, contract vaut BID_PASSE et les cartes
> > >   du chien sont affectees, les autres valeurs sont non definies.
> > > 
> > >   Le client renvoi replay qui vaut TRUE si le client veut rejouer
> > >   ou FALSE dans le cas contraire.
> > > 
> > > 
> > > Cas particulier :
> > > ---------------
> > > 
> > >   * void normal_close (void)
> > > 
> > >   Cette fonction est appellee si la connexion a ete fermee
> > >   normalement(en fin de partie quand quelqu'un a dis qu'il voulait
> > >   quitter le jeu)
> > > 
> > > 
> > >   * void lost_connexion (void)
> > > 
> > >   Cette fonction est appellee dans le cas ou il y a eu une
> > >   deconnexion. Elle permet d'informer les clients que le jeu ne se
> > >   deroule plus normalement.
> > > 
> > > 
> > > 
> > > Voila, pour l'instant ces fonctions sont faites dans libmt_client.
> > > Et donc avec le protocole actuel c'est la libmt_client qui demande
> > > au client de faire telle ou telle action (donc la libmt_client
> > > implemente le meme protocole que le serveur).
> > > 
> > > Avec le nouveau protocole, ce serai bien de faire en sorte que ce
> > > soit le serveur qui demande au client de faire telle ou telle
> > > action. La libmt_client n'etant la que pour etablir la connection,
> > > gerer le reseau et informer le client de ce que le serveur lui
> > > demande. Dans ce cas, seul le serveur serai au courant du
> > > deroulement du jeu, les clients ne faisant que repondre a ce que
> > > le serveur leur demande(ie: il n'y aurai plus qu'une seule
> > > implementation du protocole : celle du serveur).
> > 
> > Ceci n'etait pas le protocole mais un inventaire des procedures qui
> > sont ou seront dispo chez tout client qui se veut compatible avec
> > maitretarot.
> > 
> > Il faut donc maintenant...
> > 1/ definir le protocole.
> > Pour une fonction A qui prend comme arguments arg1, arg2...argn et
> > qui renvoie r1, r2...rn, avec argi et ri de type int ou string, il
> > faut pouvoir encoder tout cela dans un format independant du nom de
> > la procedure, du nombre et du type des arguments et des valeurs de
> > retour.
> > 
> Oui.
> Est-ce qu'on peut utiliser que des strings, sachant que quand on
> doit avoir un int, c'est au client (ou a la lib) de decoder.
> 
> exemple: get_card (c1,c2, ....)
> 
> avec ce qui circule sur le reseau : c1 = "10"
> et le client decode la carte (sachant qu'il attend un int) en le
> convertissant explicitement :
> 
> carte_1 = string_to_int (c1);
> 
> ceci evite le probleme d'architecture (big/little endian).
> et evite d'avoir a faire un test sur le type du parametre.
> 
> sinon, on peut realiser ca de la maniere suivante :
> 
> [params_sortie] appel_fonction (string param1, string param2, ...)
> {
>   /* definition de la commande */
>   st = forme_la_chaine ("%s%s%...", nom_de_la_fonction_a_apeller,
>   param1, param2);
>  
>   /* envoi de la commande */
>   envoi_sur_le_reseau (st, taille (st));
> 
>   /* lecture des valeurs renvoyees */
>   param_sortie = lecture_sur_le_reseau ();
> 
>   return param_sortie;
> }
> 
> la partie conversion int_to_string et string_to_int se fait en
> dehors de cette fonction.
> on peut presque faire la construction de la chaine a envoyer en
> dehors de cette fonction.
> => un fonction qui code la commande
> => envoie de la commande (une chaine de caracteres)
> => une fonction qui decode les parametres de sortie.
> 
> la commande etant de la forme :
> 
> "nom_fonction param1 param2 ..."
> ou les param sont des strings.
> 
> 
> > 2/ implementer le protocole
> > Le serveur doit generer les commandes au format du protocole,
> > recuperer les valeurs de retour et les interpreter
> > Le client doit interpreter les commandes et appeler les fonctions
> > associees, puis encoder les valeurs de retour suivant le format du
> > protocole
> > 
> ouep, voir juste au dessus.
> 
> > 3/ faire de la verification d'erreur et implementer un
> > sous-protocole de traitement d'erreur (que faire si le client ne
> > renvoie rien, ou renvoie des donnees insuffisantes, trop nombreuses
> > ou au mauvais format...?)
> > 
> si le client renvoi des donnes fausses, on lui repose la question 
> jusqu'a ce qu'il reponde quelque chose de correct (et au bout de 10
> fois on le deconnecte :)
> > 
> > 
> > Quelques remarques...
> > 
> > Nous abandonnons le format xml un moment envisage. C'est trop
> > complexe a mettre en oeuvre par rapport au gain que ca apporte.
> > 
> > Le protocole, a un niveau tres bas, disons couche 1, consistera a
> > envoyer des paquets. Un paquet est consitue de sa longueur (4
> > octets) puis d'une chaine de caracteres representant le contenu du
> > paquet. Puis il faut definir comment on code les arguments string
> > ou int, ainsi que des constantes comme UNDEF. Et definir comment on
> > code une commande.
> > La couche 2 consiste a utiliser ce codage pour envoyer des commandes
> > et des resultats
> > La couche 3 coordonne tout cela, a savoir comment on fait pour
> > dialoguer.
> > 
> > 
> > La couche 1 est deja codee.
> > Ci-dessous, une proposition de codage des differents elements
> > la couche 2 est encore d'ordre reseau puisqu'elle ne tient pas
> > compte du contenu de ce qui est envoye.
> > la couche 3 est d'ordre applicative.
> > Et evidemment, la couche 4 dont je n'ai pas parle, c'est les
> > fonctions, qui sont propres a chaque client.
> > 
> la couche 4 correspond a priorie a ce qu'il y a dans libmt_client,
> il y a une couche de plus pour implementer les fonctions dans
> chaques clients. Donc a part libmt_client, rien ne devrai changer
> dans les clients deja codes.
> 
> > 
> > proposition de codage des differents elements:
> > - tout entier doit etre mis entre parentheses
> > - toute chaine de caracteres doit etre mise entre guillemets.
> > Comment coder un guillemet? On le double, on lui met un antislash
> > devant, ou on trouve autre chose?
> 
> une methode pour coder les chaines de caractere est de reperer le "
> de debut et le " de fin et de conciderer que tout ce qu'il y a a 
> l'interieur et qui est entre " est une chaine.
> 
> exemple :
> 
>   "la_fonction "param 1" "param 2 bla bla" "param_3""
>   ^                                                 ^
>   |                                                 |
>   on repere ces 2 ", les autres " a l'interieur delimite des chaines
> de caracteres.
> 
> sinon (cf plus haut) je suis plutot partant pour mettre tous les
> parametres sous forme de chaine de caractere et c'est au serveur ou au
> client de savoir que tel parametre qu'il attent est un entier, et dans
> ce cas il fait la conversion int_to_string.
> 
> > - une valeur non definie sera 0. Remarque: 0 est donc different de
> > (0).
> 
> ou une chaine vide : ""
> 
> > - tout nom de procedure, vu qu'il est defini et fait partie de
> > l'ensemble des noms de procedures, n'a pas besoin d'un codage
> > special. Simplement, pour les noms des procedures, nous
> > n'utiliserons que des caracteres alphanumeriques (et le _).
> > 
> > Jusqu'ici, on peut encore utiliser un parser fait avec du C.
> > Pour la couche 2, si on va plus loin dans ce langage qu'on est en
> > train de definir, il faudra utiliser le parseur bison (yacc).
> > Mais on peut aussi tenter quelque chose de simple. A voir...
> > 
> je suis plutot pour quelque chose de plus simple, sachant que ce
> qu'on veut faire n'a vraiment rien de complique (pas besoin de
> sortir l'artillerie lourde :)
> 
> > Bon, qui se devoue pour extraire les elements stables de cette
> > discussion et la mettre en format docbook dans un fichier sgml?
> > 
> je transcrit les fonctions en sgml des qu'on ai d'accord sur
> tout les termes :)
> 
> 
> Philippe
> 
> -- 
> (    )
>  ~oo~         Philippe Brochard    <address@hidden>
>   .. Gnu!                           http://hocwp.free.fr
>   / =\   \=
>  -   -    -   -=-= http://www.fsf.org/home.fr.html =-=-
> 
> 
> _______________________________________________
> Maitretarot-devel-fr mailing list
> address@hidden
> http://mail.nongnu.org/mailman/listinfo/maitretarot-devel-fr
> _____________________________________________________________________
> GRAND JEU SMS : Pour gagner un NOKIA 7650, envoyez le mot IF au 61321
> (prix d'un SMS + 0.35 euro). Un SMS vous dira si vous avez gagn_.
> R_glement : http://www.ifrance.com/_reloc/sign.sms



reply via email to

[Prev in Thread] Current Thread [Next in Thread]