Partage
  • Partager sur Facebook
  • Partager sur Twitter

MMORPG->Serveur->Logique

Suije sur le bon chemin?

Anonyme
    8 janvier 2006 à 9:49:23

    Bonjour a tous,
    Je suis actuèlement sur un projet de mmorpg c++
    Je dévelope le programme avec Qt, et je suis actuèlement sur les sockets.
    Je voudrais savoir si ce que je pensse faire est la bone solution. En fait, je pense code ceci :
    Client :
    Ouverture d'une socket vers le serveur
    Tant que 1
      Si TimeOut
        Message d'
    Ereur
        Quiter la boucle
      Si StopBoucle = true//Passe a true quand on clic sur "Deconnecter"
        Quitter la boucle
      Interoge le serveur //Ecrit une instruction style <personage>position</personage>
      Recupère la réponse //Lit une chaine style <personage x="25" y="7" map="12"/>
      Interprète la réponse pour modifier l'afichage //Modifi par exmeple IdMap, PosX, PosY de l'objet Personage
    Continue


    Pour le serveur, c'est identique, sauf que l'on a un trhead par socket/client, que l'on lit, puis ensuite on répond. Le serveur aficheras en plus la liste de connecter, et les log.
    Sinon je compte utiliser une BDD sql, pour récupèrer les "réponses" et enregistrer les "ordres" du client, du style : <mov x="1" y="1">, ce qui signifi X+=1 et Y+=1 pour la base de donnée Sql.


    Je vous demande donc :
    Esque je fait bien ce qu'il faut avec cette boucle?
    Esque c'est ce n'est aps grave si j'ai 2-3 Requette Sql par boucle du cotée de mon serveur? Sachan que j'ai 1 boucle par client?

    • Partager sur Facebook
    • Partager sur Twitter
      8 janvier 2006 à 10:49:15

      Tu vas mourir avec un tel code.
      Tu fais peut-être un jeu online mais faut pas oublier les bases du jeu non plus : Faut synchroniser l'affichage hein, faut que tu times ta boucle comme on apprend à faire quand on "apprend à faire des jeux".

      if (!needrefresh())
              idle();
      else
              redraw();

      /* ... */

      void
      idle(void)
      {
              if (queryuser() > 0)
                      handleuser();

              if (queryserv() != 0)
                      handlelag();

              update();
      }


      Voilà pour ta boucle ; sinon, faut économiser la BP de ton serv donc le proto, tu peux oublier l'ASCII, ce sera du binaire normalisé.

      Pour le serveur, le modèle par thread est raisonnable, sinon tu peux faire par process, ce qui est plus simple pour un début en forkant(). En gros tu as une boucle qui accept() des connexions et quand elle en a une, elle fork en un autre process qui ne traitera que cette connexion.

      Sinon, oublie la BDD, tu fais un jeu, pas un site web. Tu peux utiliser SQL pour backuper ton jeu lors des reboot et à intervalle régulier maizs pas pour les requêtes de tous les jours si on peut dire...

      ps : Je ne pense pas que tu aies le niveau pour ça ; pourquoi ne pas faire des choses simples... Enfin bon, fais comme tu veux.
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        8 janvier 2006 à 11:02:23

        Désoler, toute ces fonctions sont du c+
        J'utilise Qt, donc je travaille avec des objets dériver de QThread et de QSocket
        Qt gère lui même l'afichage en paralelle des socket.
        Par exeple, l'afichage du jeux, est gérer par un QWidget.
        Pour le transfaère de donée, j'utilise un objet qui trensmet du binaire utf8, et peut envoilelr et recevoir des types simple masi aussi des objets!

        SI je n'utilise pas sql, je garde tout en mémoire? Ou dans un fichier txt? Et ensuite, il me faudras un timer qui sauvegarde dans la bdd? Il faudras aussi la recharger a chaque redémarage du serveur alors ...

        Enfin, pour le cleint, je devrais re-aficher ce qui se passe a chaque mouvement des monstres sur le serveur, ou chaque mouvement du jour. Il faudrais donc que j'ai par exemple un timer de 10ms qui déclanche le code(a la place du while1) et vérifi qu'il n'y a rien a afficher, et provoquer un signale "affichage" a chaque fois qu'il y a du nouveau?[Bonjour els branchements Qt Interclasse :p)
        • Partager sur Facebook
        • Partager sur Twitter
          8 janvier 2006 à 11:18:19

          Citation : JC_Master

          Désoler, toute ces fonctions sont du c+
          J'utilise Qt, donc je travaille avec des objets dériver de QThread et de QSocket
          Qt gère lui même l'afichage en paralelle des socket.
          Par exeple, l'afichage du jeux, est gérer par un QWidget.


          Je ne connais pas Qt mais je le sens mal : Pour un jeu, tu devrais timer toi-même l'affichage, laisser ça à des classes prévues pour du GUI est suicidaire, tu auras besoin d'un temps de latence minimale. [mon avis]

          Citation

          Pour le transfaère de donée, j'utilise un objet qui trensmet du binaire utf8, et peut envoilelr et recevoir des types simple masi aussi des objets!


          Si c'est utf-8, ce n'est pas du binaire mais du texte, mais oublie vite ça et fais-toi ton propre proto : Moins de surcouche = plus d'efficacité et le proto est un point clé de ton application massivement réseau.

          Citation

          SI je n'utilise pas sql, je garde tout en mémoire?


          Oui.

          Citation

          Ou dans un fichier txt? Et ensuite, il me faudras un timer qui sauvegarde dans la bdd? Il faudras aussi la recharger a chaque redémarage du serveur alors ...


          Oui pour le "timer" (mais en fait tu pourrais très bien le faire à la main ou par un cron qui envoie un signal custom à ton serveur pour qu'il dump le contenu). Oui pour le démarrage.

          Citation

          Enfin, pour le cleint, je devrais re-aficher ce qui se passe a chaque mouvement des monstres sur le serveur, ou chaque mouvement du jour.<citation>
          Faux, tu calcules et tu réaffiches périodiquement, faut que ce soit fluide ; il y a _toujours_ des images qui se perdent dans la foule mais c'est pas important du tout, le joueur n'est pas capable de tout percevoir et en plus, pour un RPG, l'importance de la précision d'affichage est largement négligeable : Même s'il y a un lag, tant que les informations restent fidèle au contexte et que le lag ne dure pas trop longtemps.

          <citation>Il faudrais donc que j'ai par exemple un timer de 10ms qui déclanche le code(a la place du while1) et vérifi qu'il n'y a rien a afficher, et provoquer un signale "affichage" a chaque fois qu'il y a du nouveau?[Bonjour els branchements Qt Interclasse :p)


          Ton timer risque de ne pas tenir le coup : De toute façon c'est un jeu et sauf si a priori le joueur exécute d'autres progs en parallèle, tu peux t'accaparer tout le proco. Boucle infinie + une fonction de temps "haute performance".
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            8 janvier 2006 à 11:35:08

            Je veut que mon jeux soit multiplateforme, tent du point de vue client que serveur, c'est pour sa que j'utilise Qt.
            Je n'ai pas fait de teste de "vitesse" pour voire les performance, mais je ^pensse que pour débuter je peut utiliser Qt, quite a re-ecrie plus tard la gestion des socket. C'est un projet de petit jeux, pour débuter, je pensse même eviter openGl pour le moment, et me contenter de 3d Isométrique.

            Esque tu pourais m'écrire un petit pseudo code du serveur/client? Que je comprène bien tout ce que tu ma espliquer.

            Edit : "un temps de latence minimale" -> What is a time of "latence" ? ^^
            • Partager sur Facebook
            • Partager sur Twitter
              8 janvier 2006 à 11:57:48

              Euh, j'utilise latence de manière un peu batarde ~= temps de réactivité.

              Pour ton pseudo code bah le client en gros c'est ce que j'ai donné plus haut et le serveur :

              while (nclients < maxclients) {
                      newclient = waitforclient();
                      forkclient(newclient);
                      ++nclients;
              }

              forkclient(clientid)
              {
                      addclient(clientid);
                      dofork();
              }


              En fait le point plus complexe c'est la synchronisation du serveur : Tes processes serveur peuvent tous accéder à un certain nombre de données et il y a plusieurs façons d'organiser ses processus du côté serveur ; je ne peux pas me prononcer sur "laquelle est la meilleure" ici parce que je n'ai pas d'expérience dans le réseau donc...
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                8 janvier 2006 à 12:17:46

                En fait j'aurais préfèrer un speudo code, plutot qu'un code c ^^
                Donc, pour le serveur, je pensse créer des variables et des metodes, qui se chargent deffectuer des actions sur d'autre variables. Je pense encapsuler le serveur dnas un singeltone(Dsl pour l'aurtographe, je veut dire une classe donc le constructeur est privé) et créer un thread qui apelle la fonction execute, apartenant a cette fameuse classe.
                Pour les instruction client, je voudrais eviter toute tentative de piratage, je pensse donc mêtre toute les instructions de mouvement du jour dans une queu. Seulemetn je ne sias pas trop ou placer le code charger d'executer les unstructions 1à1...
                • Partager sur Facebook
                • Partager sur Twitter
                  8 janvier 2006 à 12:25:00

                  Si tu veux faire les exécutions une à une et pour un petit serveur, je te conseille fortement de ne pas te compliquer la vie et d'utiliser un seul processus et de tout faire linéairement avec un poll() ou un select().

                  Pour le pseudo code, bah ce n'est pas du vrai C, j'oublie plein de déclarations pour plus de simplicité. C'est mon pseudo code ça. :p Ou alors je fais du LISP-like en pseudo code, selon les besoins.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    8 janvier 2006 à 12:30:46

                    Non, pitier, aps de lisp Like o_O
                    Je ne veut pas mourirs....
                    Hrum, bref, tu sais faire du like-french? ^^

                    Sinon, je ne conais ni poll, ni select. Mais si je doit faire els execution une a une, je vais faire plenter le client, exeplication:
                    Le client demande Ataquer * 25 fois
                    Le client demande Afficher
                    Le client demande Ataquer * 25 fois
                    Il s'agit ici d'un client modifier par un pirate. Il va donc fraper 25 fois, et ensuite rafraichir la map, ect...
                    Le but, c'est de répondre imédiatement a toute els demandes d'afichage, mais que les demande d'ataque/mouvement soit executer petit a petit, au compte goute.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      8 janvier 2006 à 12:51:05

                      Je ne peux pas dire quelle méthode est la meilleure *pour un jeu online* puisque je n'en ai jamais fait ; le reste, c'est ton choix, c'est toi, le programmeur.

                      Pour le pseudo code, je n'ai jamais fait du vieux pseudo code français. Je fais des schemas et des codes C-like, lisp-like ou batard avec juste des séries d'instructions mais toujours en anglais, question d'habitude...
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        8 janvier 2006 à 14:02:05

                        Ton abitude ne m'aide pas XD
                        Moi je fait pas du vrai pseudo code, je fait simplement des recapitulatife d'instruction... C'est un peut comme si tu comentai chaque passage, et que tu récupèrer tous les comentaires les un a la suite des autres ^^

                        SInon, pour ma solution, imaginon que se soit la bone(Wé, bon on peut réver hein?), comment puije l'implémenter?[Celle du comtpe goute des actions, mais pas de l'afichage?)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 janvier 2006 à 14:12:11

                          Imaginons que tu le fasses avec des processes ou des threads : Si ton client t'envoie une commande "action", tu fous ça dans la file d'attente partagée ; sinon, si c'est une commande "état", tu te contentes de lire l'état du monde (aussi partagé) et de le renvoyer au client.

                          Je ne vois pas vraiment le problème hein...
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            8 janvier 2006 à 15:42:22

                            le problème, c'est ou je fou le code qui lis la liste d'atente? Un thread en paralele, qui socupera de toute les actions des personages et des monstres, grace a deux timer?(Avec time.h, au lieu de QTimer?)
                            • Partager sur Facebook
                            • Partager sur Twitter
                              8 janvier 2006 à 16:01:47

                              Par exemple, tu peux faire ça. Et les fonctions haute perf, faut que tu les trouves mais c'est pas la libc standard qui va te les donner.

                              Mais sinon moi je ferais plutot comme ça : Tu as un lock et une file d'attente partagée : Lorsque ton process/thread reçoit une action, il postule pour l'exécuter et se met en attente dans la liste et continue de répondre au client. S'il n'y a personne dans la liste : Il exécute l'action et quand il a finit, il regarde s'il y en a qui patientent et si c'est le cas, il réveille le premier de la liste d'attente.

                              Ta boucle process/server ressemble à ça :
                              - Tant que le joueur est connecté
                              - Attente d'une commande du joueur OU d'une libération de place dans la queue.
                              - Si joueur envoie une commande : Tu lui réponds ce que tu peux et tu mets dans la file le reste.
                              - Si place se libère : Tu exécutes la commande puis libère la place pour celui d'après.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Anonyme
                                8 janvier 2006 à 16:32:30

                                Citation

                                - Attente d'une commande du joueur OU d'une libération de place dans la queue.


                                Quesque sa veut dire? La c'est moi qui suprime les elements...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  8 janvier 2006 à 16:40:28

                                  Bah, tu fais une pause en attendant qu'il y ait réception d'un message du joueur ou libération d'une place dans la queue ; je ne vois pas le problème, après tu implémentes ça comme tu veux mais il y a des implémentations plus ou moins évidentes, c'est de la programmation dite "système", c'est tout.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Anonyme
                                    8 janvier 2006 à 17:03:12

                                    Atend, j'ai une queu contenant un std::string, qui est un ordre.
                                    Simulon un dialogue :
                                    //-
                                    Reception "position"
                                    Reponse "xyz"
                                    //-
                                    Reception "Teleport"
                                    Stockage de "Teleport" dans Queu
                                    //???
                                    //-
                                    Reception de "Move"
                                    Stockage de "Move" dans Queu
                                    //???

                                    Voila, quesque je fait dans ???
                                    Comment je me débroille pour répondre a chaque "action" toute les 100 milisecondes par exemple?
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      8 janvier 2006 à 17:16:56


                                      Citation : moi

                                      S'il n'y a personne dans la liste : Il exécute l'action et quand il a finit, il regarde s'il y en a qui patientent et si c'est le cas, il réveille le premier de la liste d'attente.


                                      Si c'est occupé tu attends, c'est tout.

                                      Pis faut adapter à ton cas aussi, c'est pas moi qui veux faire un jeu, c'est à toi de trouver ta solution que te convienne, je ne fais que donner des idées...
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Anonyme
                                        8 janvier 2006 à 18:02:08

                                        Je ne comprend justement rein a ta phrase...
                                        Bion, esque sa peut aller :

                                        Simulon un dialogue :
                                        //-
                                        Reception "position"
                                        Reponse "xyz"
                                        //-
                                        Reception "Teleport"
                                        Stockage de "Teleport" dans Queu
                                        //Si Elemen dans la file
                                        Si LastTime - ThisTime < 100ms
                                        Executer et répondre et suprimer l'élément
                                        //-
                                        Reception de "Move"
                                        Stockage de "Move" dans Queu
                                        //Si Elemen dans la file
                                        Si LastTime - ThisTime < 100ms
                                        Executer et répondre et suprimer l'élément
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        MMORPG->Serveur->Logique

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                        • Editeur
                                        • Markdown