Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Slash94

31
Réseau / Re: Problème de réception de données côté Client..
« le: Juillet 02, 2017, 01:53:53 pm »
Merci infiniment Laurent, j'ai résolu le problème en supprimant le Selector ! Je viens d'apprendre quelque chose finalement :-]

Voici mon Serveur complet & parfaitement OK maintenant :

#include "../../Headers/Network/Network.h"

Network::Network(std::vector<Client>& vecClient) :
    m_Client(vecClient)
{

}

void Network::Launch(USHORT port)
{
    m_port = port;

    if (m_listener.listen(m_port) == sf::Socket::Done)
    {
        std::cout << "Serveur lance sur le port " << m_port << std::endl;
        m_isRunning = true;
        m_listener.setBlocking(false);
    } else {
        std::cout << "Impossible de lancer le serveur sur le port " << m_port << std::endl;
    }
}

void Network::MainLoop()
{
    PushNewUser();
    SendToClients();
    ReceiveAndSendData();
}

void Network::PushNewUser()
{
    sf::TcpSocket *socket = new sf::TcpSocket();
    socket->setBlocking(false);
    sf::Uint16 idNumber = 1;

    if (m_listener.accept(*socket) == sf::Socket::Done)
    {
        while (m_Client[idNumber].getIdNumber()!=0)
            idNumber++;

            if (idNumber <= 4)
            {
                m_Client[idNumber].setSocket(socket);
                m_Client[idNumber].setState(true);
                m_Client[idNumber].setIdNumber(idNumber);
            } else {
            m_blackList.push_back(socket);
            CheckBlackList();
        }
    }
}

void Network::CheckBlackList()
{
    if (m_blackList.size() > 0)
    {
        for (unsigned int i = 0 ; i < m_blackList.size() ; i++)
        {
            sf::Packet sendPacket;
            sendPacket << DATA::INFO << "FULL";
            m_Client[i].getSocket()->send(sendPacket);
            m_blackList.erase(m_blackList.begin()+i);
        }
    }
}

void Network::SendToClients()
{
    if (_kbhit())
    {
        if (_getch() == 'w')
        {
            for (unsigned int i = 0 ; i < m_Client.size() ; i++)
            {
                if (m_Client[i].getIdNumber() !=0)
                {
                    sf::Packet packTest;
                    packTest << DATA::INFO << sf::Uint16(0) << "Salut ! ";
                    m_Client[i].getSocket()->send(packTest);
                    std::cout << "Message du serveur envoye au(x) client(s)." << std::endl;
                }
            }
        }
    }
}

void Network::ReceiveAndSendData()
{
    for (unsigned int i = 0 ; i < m_Client.size() ; i++)
    {
        if (m_Client[i].getIdNumber()!=0)
        {
            sf::Packet receivePacket;
            if (m_Client[i].getSocket()->receive(receivePacket) == sf::Socket::Done)
            {
                sf::Uint32 checker;
                receivePacket >> checker;

                switch(checker)
                {
                    case DATA::INFO:
                    {
                        std::string information;
                        receivePacket >> information;
                        std::cout << "DATA::INFO du Client N " << m_Client[i].getIdNumber() << " : " << information << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::INFO << information;
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;

                    case DATA::USERNAME:
                    {
                        std::string username;
                        receivePacket >> username;
                        m_Client[i].setUsername(username);
                        std::cout << username << " vient de se connecter." << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::USERNAME << sf::Uint16(0) << m_Client[i].getUsername();
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;

                    case DATA::DIRECTION:
                    {
                        sf::Uint32 direction;
                        receivePacket >> direction;
                        std::cout << "DATA::DIRECTION du Client N " << m_Client[i].getIdNumber() << " : " << direction << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::DIRECTION << sf::Uint16(0) << direction;
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;
                }
            }
        }
    }
}

///GETTERS///
bool Network::isRunning() const { return m_isRunning; }
 

Merci à toi ! UNE FOIS DE PLUS ! :-D

32
Réseau / Re: Problème de réception de données côté Client..
« le: Juillet 01, 2017, 08:02:49 pm »
Ah oui, merde pour le break ! L'erreur pour DIRECTION doit venir de la !
Ben il me semblait qu'il etait primordial d'employer socetselector quand on faisait du multi clients pour éviter de faire appel à des threads .
En fait j'aimerais que mon serveur puisse gérer les échanges entre les clients ET qu'il soit possible de contacter les clients directement par le biais du serveur ..
Comment T'y prendrais-tu ?
Merci :-))

33
Réseau / Re: Problème de réception de données côté Client..
« le: Juillet 01, 2017, 02:54:09 pm »
PS : Pour voir le screen entièrement, faire "clique droit > ouvrir dans un nouvel onglet " car il ne s'affiche pas entièrement :-/

34
Réseau / Re: Problème de réception de données côté Client..
« le: Juillet 01, 2017, 02:51:41 pm »
Salut Laurent :-)

Oui, c'est normal, c'est comme cela que je procède côté client, en effet.

Le serveur lui, sait de quel client ça vient grâce à sa socket, il retrouve son ID automatiquement et peut renseigner les autres joueurs sur le changement de coordonnées qu'un joueur a fait et renvoyant l'information aux autres joueurs, cette fois-ci avec l'ID du joueur concerné, et côté client, on RÉCEPTIONNE avec l'ID du joueur dont il est question, ça fonctionne très bien comme ça..

En fait, mon problème c'est que je n'arrive pas à envoyer une information directement depuis mon Serveur, on dirait qu'il est " bloqué ".

J'ai refait entièrement un petit programme Serveur/Client de test qui fonctionne mais avec le même problème :

Côté Serveur


#include "../../Headers/Network/Network.h"

Network::Network(std::vector<Client>& vecClient) :
    m_Client(vecClient)
{

}

void Network::Launch(USHORT port)
{
    m_port = port;

    if (m_listener.listen(m_port) == sf::Socket::Done)
    {
        std::cout << "Serveur lance sur le port " << m_port << std::endl;
        m_listener.setBlocking(false);
        m_socketSelector.add(m_listener);
        m_isRunning = true;
    } else {
        std::cout << "Impossible de lancer le serveur sur le port " << m_port << std::endl;
    }

}

void Network::MainLoop()
{
    if (m_socketSelector.wait())
    {
        if (m_socketSelector.isReady(m_listener))
        {
            PushNewUser();
        } else {
            SendToClients();
            ReceiveAndSendData();
        }
    }

}

void Network::PushNewUser()
{
        sf::TcpSocket *socket = new sf::TcpSocket();
        socket->setBlocking(false);
        m_listener.accept(*socket);

        std::cout << "Une connexion est detectee." << std::endl;

        sf::Uint16 idNumber = 1;

        while (m_Client[idNumber].getIdNumber()!=0)
            idNumber++;

            if (idNumber <= 4)
            {
                m_Client[idNumber].setSocket(socket);
                m_Client[idNumber].setState(true);
                m_Client[idNumber].setIdNumber(idNumber);
                m_socketSelector.add(*m_Client[idNumber].getSocket());
            } else {
            m_blackList.push_back(socket);
            CheckBlackList();
        }
}

void Network::CheckBlackList()
{
    if (m_blackList.size() > 0)
    {
        for (unsigned int i = 0 ; i < m_blackList.size() ; i++)
        {
            sf::Packet sendPacket;
            sendPacket << DATA::INFO << "FULL";
            m_Client[i].getSocket()->send(sendPacket);
            m_blackList.erase(m_blackList.begin()+i);
        }
    }
}

void Network::SendToClients()
{
    if (_kbhit())
    {
        if (_getch() == 'w')
        {
            sf::Packet packTest;
            packTest << DATA::INFO << sf::Uint16(0) << "Salut ! ";
            for (unsigned int i = 0 ; i < m_Client.size() ; i++)
            {
                if (m_Client[i].getIdNumber() !=0)
                {
                    sf::Packet packTest;
                    packTest << DATA::INFO << sf::Uint16(0) << "Salut ! ";
                    m_Client[i].getSocket()->send(packTest);
                    std::cout << "Message du serveur envoye au(x) client(s)." << std::endl;
                }
            }
        }
    }
}

void Network::ReceiveAndSendData()
{
    for (unsigned int i = 0 ; i < m_Client.size() ; i++)
    {
        if (m_Client[i].getIdNumber()!=0 && m_socketSelector.isReady(*m_Client[i].getSocket()))
        {
            sf::Packet receivePacket;
            if (m_Client[i].getSocket()->receive(receivePacket) == sf::Socket::Done)
            {
                sf::Uint32 Checker;
                receivePacket >> Checker;

                switch(Checker)
                {
                    case DATA::INFO:
                    {
                        std::string information;
                        receivePacket >> information;
                        std::cout << "DATA::INFO du Client N " << m_Client[i].getIdNumber() << " : " << information << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::INFO << information;
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;

                    case DATA::USERNAME:
                    {
                        std::string username;
                        receivePacket >> username;
                        m_Client[i].setUsername(username);
                        std::cout << username << " vient de se connecter." << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::USERNAME << sf::Uint16(0) << m_Client[i].getUsername();
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;

                    case DATA::DIRECTION:
                    {
                        sf::Uint32 direction;
                        receivePacket >> direction;
                        std::cout << "DATA::DIRECTION du Client N " << m_Client[i].getIdNumber() << " : " << direction << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << DATA::DIRECTION << sf::Uint16(0) << direction;
                        m_Client[i].getSocket()->send(sendPacket);
                    }
                    break;
                }
            }
        }
    }
}

///GETTERS///
bool Network::isRunning() const { return m_isRunning; }
 

Côté Client


#include "../../Headers/Network/Network.h"

Network::Network(Client& client) :
    m_Client(client)
{

}

void Network::ConnectToServer(std::string ipAddress, USHORT Port)
{
    if (m_socket.connect(ipAddress, Port) == sf::Socket::Done)
    {
        std::cout << "Connexion reussie au serveur." << std::endl;
        m_isRunning = true;
        m_socket.setBlocking(false);
    } else {
        std::cout << "Connexion impossible..." << std::endl;
        exit(0);
    }
}

void Network::SendData(float timeSend)
{
    if (m_clockSend.getElapsedTime().asMilliseconds() > timeSend)
    {
        if (m_Client.getDirection() != m_structData.Direction)
        {
            m_structData.Direction = m_Client.getDirection();
            if (m_structData.Direction !=0)
            {
                sf::Packet sendPacket;
                sendPacket << DATA::DIRECTION << m_structData.Direction;
                m_socket.send(sendPacket);
                std::cout <<"Direction envoyee au serveur" << std::endl;
                m_structData.Direction = 0;
            }
        }

        if (m_Client.getUsername() != m_structData.Username)
        {
            m_structData.Username = m_Client.getUsername();
            sf::Packet sendPacket;
            sendPacket << DATA::USERNAME << m_structData.Username;
            m_socket.send(sendPacket);
            std::cout <<"Username envoye au serveur" << std::endl;
        }

        m_clockSend.restart();
    }

}

void Network::ReceiveData()
{
    sf::Packet receivePacket;
    if (m_socket.receive(receivePacket) == sf::Socket::Done)
    {
        sf::Uint32 Checker;
        sf::Uint16 idNumber;

        receivePacket >> Checker >> idNumber;

        switch(Checker)
        {
        case DATA::INFO:
            {
                std::string info;
                receivePacket >> info;
                std::cout << "Recu info : " << info << std::endl;
            }
            case DATA::DIRECTION:
            {
                sf::Uint32 direction;
                receivePacket >> direction;
                std::cout << "Le serveur vous renvoi votre direction : " << direction << std::endl;
            }
            break;
        }
    }
}

///GETTERS///
bool Network::isRunning() const { return m_isRunning; }
 

J'ai fait, pour le test, en sorte que si l'on appuie sur la touche W, que ça envoi l'information aux Clients avec une itération, mais l'information n'arrive pas instantanément, il faut obligatoirement que les Clients concernés aient renvoyé un message pour que le serveur envoi le sien, comme si il était bloqué / en attente..

Exemple :


Mon serveur à gauche, mon client à droite.

Lorsque j'appuie sur la touche W sur mon serveur, il ne se passe rien côté serveur, ni client..

PAR CONTRE si le client change sa position ALORS le serveur envoi finalement l'information, mais j'ai aussi un bug car le Client reçoit une DATA::DIRECTION de 2292880 alors que je n'ai jamais demandé au serveur de renvoyer la direction à ce moment-là ( et surtout pas avec cette donnée faussée ).

Ma question ultime est, comment faire pour que lorsque je presse la touche 'W' sur mon serveur, celui-ci envoi instantanément aux clients la DATA::INFO que j'ai envie d'envoyer ?
D'où viendrait aussi le bug inhérent à la direction ?

PS : Voici mon enumération de mon Network.h qui est la même de chaque côté :

    enum DATA:sf::Uint32{INFO, USERNAME, DIRECTION};
 

Merci infiniment ! :-)


35
Réseau / Re: Problème de réception de données côté Client..
« le: Juin 30, 2017, 08:04:33 pm »
Ben non Laurent, j'avais bel et bien écrit

            if (m_socketSelector.isReady(*m_Clients[i].getSocket()))
            {
                        sf::Packet sendPacket;
                        sendPacket << DATA::INFO << 0 << "Le serveur vous parle !";
                        m_Clients[i].getSocket()->send(sendPacket);
             }
 


:-)

36
Réseau / Re: Problème de réception de données côté Client..
« le: Juin 30, 2017, 05:26:22 pm »
Merci pour ta réactivité Laurent !
J'essayerais d'ores et déjà de procéder selon ta méthode quand je rentrerais chez moi, néanmoins je tiens a insister sur le fait que lorsque le client a au préalablement adressé un packet au serveur, admettons DATA::XPOS et qu ensuite je renvoi tout de suite au client par un DATA:INFO << 0 << "Le serveur a bien reçu votre position X !";
La le client recevra bien le packet dans son intégralité alors que si j'envoi directement ce packet , le client ne recevra pas tout ... Bizarre, non ?

37
Réseau / Re: Problème de réception de données côté Client..
« le: Juin 30, 2017, 11:24:12 am »
Salut Laurent, ça fait un petit baille :-)
Toujours fidèle au poste à ce que je vois !

[Petite apparté*] Alors JE SAIS PERTINEMMENT que la meilleure gestion qui soit c'est celle ou c'est LE SERVEUR qui détermine tout (positions en temps réel etc etc ) et non le Client, je le sais très bien mais ce n'est pas la question que je pose dans ce poste, donc ne nous attardons pas sur cette question de " faille " ou " d'optimisation idéale" mais plutôt sur comment résoudre mon problème qui a tendance à m'énerver copieusement ! :-)

Côté Client, on check si un paramètre change en le comparant à une structure déclarée dans ma classe Network, si c'est le cas, hop, on envoie la modification dont il est question au serveur :

void Network::sendData(float timeSend, MainPlayer &mainPlayer, Map& map)
{
    if (m_clockSend.getElapsedTime().asMilliseconds()>timeSend)
    {
        if (mainPlayerData.username != mainPlayer.getUsername())
        {
            mainPlayerData.username = mainPlayer.getUsername();
            sf::Packet sendPacket;
            sendPacket << DATA::USERNAME << mainPlayerData.username;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.mapname != mainPlayer.getMapName())
        {
            mainPlayerData.mapname = mainPlayer.getMapName();
            sf::Packet sendPacket;
            sendPacket << DATA::MAPNAME << mainPlayerData.mapname;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.position.x != mainPlayer.getPosition().x)
        {
            mainPlayerData.position.x = mainPlayer.getPosition().x;
            sf::Packet sendPacket;
            sendPacket << DATA::XPOS << mainPlayerData.position.x;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.position.y != mainPlayer.getPosition().y)
        {
            mainPlayerData.position.y = mainPlayer.getPosition().y;
            sf::Packet sendPacket;
            sendPacket << DATA::YPOS << mainPlayerData.position.y;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.anim.x != mainPlayer.getAnim().x)
        {
            mainPlayerData.anim.x = mainPlayer.getAnim().x;
            sf::Packet sendPacket;
            sendPacket << DATA::XANIM << mainPlayer.getAnim().x;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.anim.y != mainPlayer.getAnim().y)
        {
            mainPlayerData.anim.y = mainPlayer.getAnim().y;
            sf::Packet sendPacket;
            sendPacket << DATA::YANIM << mainPlayer.getAnim().y;
            m_socket.send(sendPacket);
        }

        if (mainPlayerData.life != mainPlayer.getLife())
        {
            mainPlayerData.life = mainPlayer.getLife();
            sf::Packet sendPacket;
            sendPacket << DATA::LIFE << mainPlayerData.life;
            m_socket.send(sendPacket);
        }

        m_clockSend.restart();
    }
}
 

Toujours côté Client, je reçois les informations provenant du serveur de la sorte :
( chaque donnée est identifiable grâce à son préfixe énuméré )

void Network::receiveData(std::vector<OnlinePlayer>&onlinePlayer)
{
    UINT checker;
    sf::Packet receivePacket;

    if (m_socket.receive(receivePacket) == sf::Socket::Done)
    {

    USHORT idNumber;
    receivePacket >> checker >> idNumber;
    std::cout << "checker = " << checker << std::endl;
    std::cout << "idNumber = " << idNumber << std::endl;

    if (!onlinePlayer[idNumber].getState())
        onlinePlayer[idNumber].setState(true);

    switch(checker)
    {
    case DATA::USERNAME:
        {
        std::string username;
        receivePacket >> username;
        onlinePlayer[idNumber].setUsername(username);
        }
        break;
    case DATA::MAPNAME:
        {
        std::string mapname;
        receivePacket >> mapname;
        onlinePlayer[idNumber].setMapname(mapname);
        }
    break;
    case DATA::XPOS:
        {
        float xPos;
        receivePacket >> xPos;
        onlinePlayer[idNumber].setxPos(xPos);
        }
        break;
    case DATA::YPOS:
        {
        float yPos;
        receivePacket >> yPos;
        onlinePlayer[idNumber].setyPos(yPos);
        }
        break;
    case DATA::XANIM:
        {
            int xAnim;
            receivePacket >> xAnim;
            onlinePlayer[idNumber].setxAnim(xAnim);
        }
        break;
    case DATA::YANIM:
        {
            int yAnim;
            receivePacket >> yAnim;
            onlinePlayer[idNumber].setyAnim(yAnim);
        }
        break;
    case DATA::STATE:
        {
        bool state;
        receivePacket >> state;
        onlinePlayer[idNumber].setState(state);
        if (!onlinePlayer[idNumber].getState())
            onlinePlayer[idNumber].init();
        }
        break;
    case DATA::INFO:
        {
            std::string info;
            receivePacket >> info;
            std::cout << "Info : " << info << std::endl;
            if (info == "FULL")
            {
                std::cout << "Serveur plein.." << std::endl;
                exit(0);
            }
        }
        break;
    case DATA::WEATHER:
        {
            bool weather;
            receivePacket >> weather;
            std::cout << "weather : " << weather << std::endl;
            mapData.weather = weather;
            std::cout << "mapData.weather : " << mapData.weather << std::endl;
        }
        break;

    }

    }
}
 

Et enfin, côté serveur, je traite la réception et le renvoi de données de cette manière là :

void Network::receiveAndSendData()
{
    for (UINT i = 0 ; i < m_Clients.size() ; i++)
    {
        if (m_Clients[i].getIdNumber() != 0)
        {

            if (m_socketSelector.isReady(*m_Clients[i].getSocket()))
            {
                sf::Packet receivePacket;

                if (m_Clients[i].getSocket()->receive(receivePacket) == sf::Socket::Done)
                {

                ///Le checker permettra de vérifier l'énumération reçue
                UINT checker;
                receivePacket >> checker;

                switch(checker)
                {
                    case DATA::USERNAME:
                    {
                        std::string username;
                        receivePacket >> username;
                        std::cout << "username recu du client " << m_Clients[i].getIdNumber() << " : " << username << std::endl;
                        m_Clients[i].setUsername(username);

                        sf::Packet sendPacket;
                        sendPacket << DATA::USERNAME << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getUsername();
                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }
                    }
                    break;
                    case DATA::MAPNAME:
                    {
                        std::string mapname;
                        receivePacket >> mapname;
                        std::cout << "mapname recu du client " << m_Clients[i].getIdNumber() << " : " << mapname << std::endl;
                        m_Clients[i].setMapname(mapname);

                        sf::Packet sendPacket;
                        sendPacket << DATA::MAPNAME << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getMapname();
                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }
                    }
                    break;
                    case DATA::STATE:
                    {
                        bool state;
                        receivePacket >> state;
                        m_Clients[i].setState(state);

                        sf::Packet sendPacket;
                        sendPacket << DATA::STATE << m_Clients[i].getIdNumber() << m_Clients[i].getState();

                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() !=0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }

                        if (!m_Clients[i].getState())
                        {
                            std::cout << m_Clients[i].getUsername() << " s'est deconnecte." << std::endl;
                            m_socketSelector.remove(*m_Clients[i].getSocket());
                            m_Clients[i].init();
                        }
                    }
                    break;
                    case DATA::XPOS:
                    {
                        float xPos;
                        receivePacket >> xPos;
                        std::cout << "xPos recu du client " << m_Clients[i].getIdNumber() << " : " << xPos << std::endl;
                        m_Clients[i].setxPos(xPos);

                        sf::Packet sendPacket;
                        sendPacket << DATA::XPOS << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getPosition().x;

                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);

                        }

                    }
                    break;
                    case DATA::YPOS:
                    {
                        float yPos;
                        receivePacket >> yPos;
                        std::cout << "yPos recu du client " << m_Clients[i].getIdNumber() << " : " << yPos << std::endl;
                        m_Clients[i].setyPos(yPos);

                        sf::Packet sendPacket;
                        sendPacket << DATA::YPOS << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getPosition().y;
                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }
                    }
                    break;
                    case DATA::XANIM:
                    {
                        int xAnim;
                        receivePacket >> xAnim;
                        std::cout << "xAnim recu du client " << m_Clients[i].getIdNumber() << " : " << xAnim << std::endl;
                        m_Clients[i].setxAnim(xAnim);

                        sf::Packet sendPacket;
                        sendPacket << DATA::XANIM << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getAnim().x;
                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }
                    }
                    break;
                    case DATA::YANIM:
                    {
                        int yAnim;
                        receivePacket >> yAnim;
                        std::cout << "yAnim recu du client " << m_Clients[i].getIdNumber() << " : " << yAnim << std::endl;
                        m_Clients[i].setyAnim(yAnim);

                        sf::Packet sendPacket;
                        sendPacket << DATA::YANIM << m_Clients[i].getIdNumber()
                                   << m_Clients[i].getAnim().y;
                        for (UINT s = 0 ; s < m_Clients.size() ; s++)
                        {
                            if (i!=s && m_Clients[s].getIdNumber() != 0)
                                m_Clients[s].getSocket()->send(sendPacket);
                        }
                    }
                    break;
                    case DATA::ATTACK:
                    {
                        bool attack;
                        receivePacket >> attack;
                        for (UINT a = 0 ; a < m_Clients.size() ; a++)
                        {
                            if (i!=a && m_Clients[a].getIdNumber() != 0)
                            {
                                if (m_Clients[i].checkPerimeter(m_Clients[a]))
                                {
                                    m_Clients[i].attack(m_Clients[a]);
                                    sf::Packet sendPacket;
                                    sendPacket << DATA::DAMAGE << m_Clients[i].getIdNumber()
                                               << m_Clients[a].getLife();
                                    m_Clients[a].getSocket()->send(sendPacket);

                                    for (UINT s = 0 ; s < m_Clients.size() ; s++)
                                    {
                                        if (a!=s && m_Clients[s].getIdNumber() != 0)
                                        {
                                            sf::Packet sendPacket;
                                            sendPacket << DATA::LIFE << m_Clients[a].getIdNumber()
                                                       << m_Clients[a].getLife();
                                            m_Clients[s].getSocket()->send(sendPacket);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                    }
                }
            }

        }
    }
}
 

Tout ça fonctionne parfaitement bien MAIS lorsque je désire envoyer une information DIRECTEMENT aux clients depuis le serveur, le client ne reçoit que le type énuméré et non le reste...

Exemple de code qui foire :

    for (UINT i = 0 ; i < m_Clients.size() ; i++)
    {
        if (m_Clients[i].getIdNumber() != 0)
        {
            if (m_socketSelector.isReady(*m_Clients[i].getSocket()))
            {
                        sf::Packet sendPacket;
                        sendPacket << DATA::INFO << 0 << "Le serveur vous parle !";
                        m_Clients[i].getSocket()->send(sendPacket);
             }
        }
    }
 

Le client reçoit bien le DATA::INFO ( car il sait qu'il s'agit d'une INFO ) mais ensuite, lorsqu'il s'agit d'extraire la string "Le serveur vous parle !", impossible, la string est vide, comme si il y avait eu une perte.. :-(

38
Réseau / Problème de réception de données côté Client..
« le: Juin 29, 2017, 10:13:42 pm »
Salut à tous !

Alors voilà, je viens vous voir car j'ai un soucis particulièrement agaçant et je n'arrive absolument pas à en identifier la cause, en effet, lorsque j'envoi une information au serveur depuis mon Client, elle arrive parfaitement à destination.

Je procède de la sorte :

if (structData.xPos != m_mainPlayer.getPosition().x)
{
structData.xPos = m_mainPlayer.getPosition().x;
sf::Packet sendPacket;
sendPacket << DATA::XPOS << structData.xPos;
m_socket.send(sendPacket);
}

Le serveur reçoit parfaitement ma variable " structData.xPos " et bien entendu, grâce à l'enum DATA::XPOS préfigurant dans le packet, il identifie clairement à quoi correspond cette donnée.

Je réceptionne le packet comme suit :



    for (UINT i = 0 ; i < Clients.size() ; i++)
    {
        if (Clients[i].getIdNumber() != 0)
        {
            if (m_socketSelector.isReady(*Clients[i].getSocket()))
            {
                sf::Packet receivePacket;

                 if (Clients[i].getSocket()->receive(receivePacket) == sf::Socket::Done)
                {
                    UINT checkData;
                    receivePacket >> checkData;
                       
                    switch(checkData)
                    {
                    case DATA::XPOS:
                    {
                        float xPos;
                        receivePacket >> xPos;
                        Clients[i].setxPos(xPos);
                        std::cout << "xPos vaut : " << xPos << std::endl;
                        sf::Packet sendPacket;
                        sendPacket << INFO << "Le serveur a reçu votre position X ! ";
                        Clients[i].getSocket()->send(sendPacket);
                    }
                    break;
                    }
                }
            }
        }
    }

 

Et ça marche sans aucun problème si je renvoi l'information au client TOUT DE SUITE après grâce à mon packet sendPacket, le client reçoit bien la phrase "Le serveur a reçu votre position X ! ".

MAIS car oui il y a un MAIS, si je veux envoyer DIRECTEMENT une information à mon client sans que celui-ci m'est au préalablement envoyé un paquet comme par exemple :

sf::Packet sendPacket;
sendPacket << DATA::INFO << "Salut!";
Clients[i].getSocket()->send(sendPacket);
 

Mon client ne reçoit pas la phrase :-( il reçoit bien l'énumération qui indique qu'il s'agit de DATA::INFO mais la string sensée recevoir "Salut !" est vide....

Et pareil avec un booléen, un entier ou autre...
Pourquoi cette perte de données soudaine ?

Donc mes questions sont les suivantes :

-Comment je pourrais faire afin d'envoyer une information à un Client sans que celui-ci m'est envoyé d'abord un packet ?

-Pourquoi mon Client reçoit-il correctement l'énumération mais pas son contenu, alors que lorsque je procède à un renvoi direct après une réception, cela fonctionne ?


Merci infiniment car là, je suis complètement largué pour le coup.... ça me semble illogique comme problème...

39
Je reviens une dernière fois ici afin de vous informer que j'ai résolu le problème en surchargeant simplement les opérateurs << & >>, je n'utilise pas uint8_t mais directement l'envoi des valeurs énumérées et les réceptionne côté serveur, ça fonctionne du tonnerre !

Le lien que j'avais trouvé en pause à mon boulot sur mon téléphone qui m'a aidé à résoudre le problème :

https://en.sfml-dev.org/forums/index.php?topic=16295.0

Mes codes fonctionnels :

Côté Serveur

#include <iostream>
#include <vector>

#include <SFML/Network.hpp>

using namespace std;
using namespace sf;

enum DATA {Right, Up, Message};
Packet& operator>>(Packet& p, DATA& receiveData);

int main()
{
    int port = 2000;
    bool done = false;

    TcpListener listener;
    SocketSelector selector;

    if (listener.listen(port) == Socket::Done)
        cout << "Serveur lance sur le port " << port << endl;
    else
        cout << "Impossible de lancer le serveur sur le port " << port << endl;

    listener.setBlocking(false);

    selector.add(listener);

    vector<TcpSocket*>clients;

    while (!done)
    {
        if (selector.wait())
        {
            if (selector.isReady(listener))
            {
                TcpSocket* socket = new TcpSocket;
                listener.accept(*socket);
                clients.push_back(socket);
                selector.add(*socket);

                Packet receivePacket;
                string pseudo;

                if (socket->receive(receivePacket) == Socket::Done)
                {
                    receivePacket >> pseudo;
                    cout << pseudo << " vient de se connecter." << endl;
                }

            } else {

                for (int i = 0 ; i < clients.size() ; i++)
                {
                    if (selector.isReady(*clients[i]))
                    {
                        Packet receivePacket, sendPacket;

                        if (clients[i]->receive(receivePacket) == Socket::Done)
                        {
                            int checker;

                            receivePacket >> checker;

                            switch(checker)
                            {
                            case DATA::Right:
                                int x;
                                receivePacket >> x;
                                cout << "x : " << x << endl;
                                break;
                            case DATA::Up:
                                int y;
                                receivePacket >> y;
                                cout << "y : " << y << endl;
                                break;
                            case DATA::Message:
                                string str;
                                receivePacket >> str;
                                cout << "str : " << str << endl;
                                break;
                            }

                            for (int j = 0 ; j < clients.size() ; j++)
                            {
                                if (i!=j)
                                clients[j]->send(sendPacket);
                            }
                        }

                    }
                }
            }
        }
    }
}
 

Côté Client

#include <iostream>
#include <sstream>
#include <conio.h>

#include <SFML/Network.hpp>

using namespace std;
using namespace sf;

enum DATA {Right, Up, Message};

Packet& operator<<(Packet& packet, DATA& receiveData);

int main()
{
    bool done = false;
    string ip = "localhost";
    int port = 2000;

    TcpSocket socket;

    string pseudo;
    cout << "Votre pseudo : ";
    getline(cin,pseudo);

    if (socket.connect(ip, port) == Socket::Done)
    {
        cout << "connexion reussie ! " << endl;
        Packet sendPacket;
        socket.setBlocking(false);
        sendPacket << pseudo;
        socket.send(sendPacket);
    } else {
        cout << "echec de connexion... " << endl;
        exit(0);
    }

    int x = 0, y = 5;

    Clock clockSend;

    while (!done)
    {
            if (_kbhit())
            {
                Packet sendPacket;
                switch (_getch())
                {
                case 'x':
                    x++;
                    cout << " x : " << x << endl;
                    sendPacket << DATA::Right << x;
                    socket.send(sendPacket);
                break;
                case 'y':
                    y++;
                    cout << " y : " << y << endl;
                    sendPacket << DATA::Up << y;
                    socket.send(sendPacket);
                break;
                case 'm':
                    sendPacket << DATA::Message << "Lol.";
                    socket.send(sendPacket);
                    break;
                }
            }

    }
}
 

Merci une fois de plus à Laurent de m'avoir orienté vers cette superbe méthode d'optimisation !
Car sur mon jeu, à chaque nouvelle mise à jour ( admettons la position X de mon personnage ), je renvoyais TOUTES les informations ( pseudonyme, la map où il est, x, y, son level etc etccc ) ce qui était vraiment pourri de chez pourri comme méthode !

En espérant en avoir aidé à mon tour ! :-]

40
Excellent Laurent !!!
Merci énormément, c'est une excellente technique et très simple qui plus est :-D

41
Salut à tous !

Alors voilà, je développe un petit jeu en ligne qui avance à vitesse grand V, néanmoins, pour les échanges réseaux, je procède de la sorte ( bon, je vulgarise ça un petit peu pour poster ma question ici ) :

sendPacket << username << x << y << state << mapzone << level;
 

Et bien entendu, de l'autre côté, on reçoit tout dans le même ordre, ça fonctionne parfaitement mais en fait, ça ne m'enchante pas de devoir tout renvoyer à chaque fois.. Ca bouffe de la bande passante et par conséquent, plus il y a de joueurs présents en ligne, plus ça lag..

Admettons que le personnage se déplace sur l'axe Y, j'aimerais que UNIQUEMENT la valeur de la variable Y soit envoyée et traitée de l'autre côté..
Comment donc pourrais-je m'y prendre pour que de l'autre côté, le serveur se dise " ÇA, c'est pour la variable Y ! "

J'ai tenté de faire un Packet différent pour chaque donnée envoyée et un packet de réception différent pour chaque réception mais ça arrive dans le désordre le plus total et puis ça me semble inutile, farfelu et complètement à côté de la plaque comme méthode..

Comment m'y prendre ?
Merci à tous, les amis :-]

PS : J'ai tenté de faire un petit code en guise de test avant de vouloir m'occuper de mon projet, mais c'est absolument pas fonctionnel du tout, lol.

Côté Serveur :
( J'ai crée un Packet pour recevoir les int X, Y et un autre Packet pour recevoir les strings mais cette méthode est complètement nulle et non fonctionnelle.. )

#include <iostream>
#include <vector>

#include <SFML/Network.hpp>

using namespace std;
using namespace sf;

int main()
{
    int port = 2000;
    bool done = false;

    TcpListener listener;
    SocketSelector selector;

    if (listener.listen(port) == Socket::Done)
        cout << "Serveur lance sur le port " << port << endl;
    else
        cout << "Impossible de lancer le serveur sur le port " << port << endl;

    listener.setBlocking(false);

    selector.add(listener);

    vector<TcpSocket*>clients;

    while (!done)
    {
        if (selector.wait())
        {
            if (selector.isReady(listener))
            {
                TcpSocket* socket = new TcpSocket;
                listener.accept(*socket);
                clients.push_back(socket);
                selector.add(*socket);

                Packet receivePacket;
                string pseudo;

                if (socket->receive(receivePacket) == Socket::Done)
                {
                    receivePacket >> pseudo;
                    cout << pseudo << " vient de se connecter." << endl;
                }

            } else {

                for (int i = 0 ; i < clients.size() ; i++)
                {
                    if (selector.isReady(*clients[i]))
                    {
                        Packet receivePacket, receivePacket2, sendPacket;
                        string str;

                        if (clients[i]->receive(receivePacket) == Socket::Done)
                        {
                            int x, y;
                            if (receivePacket >> x >> y)
                            {
                                cout << "recu de " << clients[i]->getRemoteAddress().getPublicAddress()
                                << " : x : " << x << " , y : " << y << endl;
                                sendPacket << x << y;
                            }

                            for (int j = 0 ; j < clients.size() ; j++)
                            {
                                if (i!=j)
                                    clients[j]->send(sendPacket);
                            }
                        }

                        if (clients[i]->receive(receivePacket2) == Socket::Done)
                        {
                            string str;
                            if (receivePacket2 >> str)
                            {
                                cout << "recu de " << clients[i]->getRemoteAddress().getPublicAddress()
                                << " : str = " << str << endl;
                                sendPacket << str;
                            }

                            for (int j = 0 ; j < clients.size() ; j++)
                            {
                                if (i!=j)
                                    clients[j]->send(sendPacket);
                            }
                        }
                    }
                }
            }
        }
    }
}
 

Mon Client de test :
(Quand on appui sur X ou Y ça incrémente les variables en question et quand on appuie sur S c'est censé envoyer la chaîne de caractère ).

#include <iostream>
#include <sstream>
#include <conio.h>

#include <SFML/Network.hpp>

using namespace std;
using namespace sf;

int main()
{
    bool done = false;
    string ip = "192.168.0.25";
    int port = 2000;

    TcpSocket socket;

    string pseudo;
    cout << "Votre pseudo : ";
    getline(cin,pseudo);

    if (socket.connect(ip, port) == Socket::Done)
    {
        cout << "connexion reussie ! " << endl;
        Packet sendPacket;
        socket.setBlocking(false);
        sendPacket << pseudo;
        socket.send(sendPacket);
    } else {
        cout << "echec de connexion... " << endl;
        exit(0);
    }

    int x = 0, y = 5;

    Clock clockSend;

    while (!done)
    {
        Packet sendPacket, sendPacket2;

        if (clockSend.getElapsedTime().asMilliseconds()>50)
        {
            if (_kbhit())
            {
                switch (_getch())
                {
                case 'x':
                    x++;
                    sendPacket << x << y;
                    socket.send(sendPacket);
                    break;
                case 'y':
                    y++;
                    sendPacket << x << y;
                    socket.send(sendPacket);
                    break;
                case 's':
                    sendPacket2 << "Lol!";
                    socket.send(sendPacket2);
                    break;
                }
            }
            clockSend.restart();
        }

        system("cls");
        cout << " x : " << x << " , y : " << y << endl;
    }
}
 

42
Certes, mais j'aime la simplicité !
Néanmoins, si tu veux m'expliquer brièvement comment j'aurais pu m'y prendre, je suis preneur et très intéressé pour le principe de mon perfectionnement en prog :-]

43
Salut à toi G.

Merci infiniment ! J'ai téléchargé une police monospaced ( je ne connaissais même pas ce principe de police d'écriture ! ) et ça fonctionne PARFAITEMENT !

T'es au top, merci encore :-]  ;)

44
Graphique / Problème de taille de caractère lors de l'affichage..
« le: Avril 22, 2017, 02:15:07 pm »
Salut à tous !

Alors voilà, j'essaie de faire un système de bulle de dialogue qui s'adapte à la longueur de mon texte..

Lorsqu'il s'agit de la lettre a, c'est parfait, l'alignement des lettres et l'écartement de la bulle de dialogue restent parfaits !

Néanmoins, lorsque j'emploi la lettre i, la bulle de dialogue grandit beaucoup plus qu'il ne le faudrait et à l'inverse, la lettre w a tendance à très vite dépasser la bulle hors de ses zones...

Voici une illustration afin de poser le problème ici concrètement :



Je suis totalement conscient que chaque lettre est entourée d'un rectangle invisible qui définit ses bordures mais j'aimerais garder un espacement identique pour chaque lettre de l'alphabet de manière à ce que ça ne foire pas mon calcul de taille de bulle... Comment pourrais-je m'y prendre ? Quelle(s) portion(s) de code appartenant à sf::Text pourrait m'aider ?

PS : J'ai cru comprendre que sf::Glyph pourrait m'aider mais aucune idée de son utilisation pour résoudre mon problème..

Merci à tous & Salut à Laurent au passage ;-)

45
Général / Besoin de conseils pour protéger mes fichiers maps.
« le: Mars 29, 2017, 09:42:27 pm »
Salut à tous :-]

Alors voilà, mon projet avance à grands pas et j'aimerais que vous me donniez des solutions afin de protéger ( au mieux, du moins ) mes fichiers maps de manière à ce qu'ils ne soient pas facilement modifiables.

Si j'ai un fichier .map avec, admettons, l'architecture suivante :

00 42 00 48 00 48 48 48 00
00 14 00 17 00 00 00 52 52

Ou chaque nombre représenterait un tile différent.

Le joueur pourrait très aisément modifier la map à sa guise.

Donc dans un premier temps, que me conseillerez-vous pour la rendre illisible ? Je dis par là, la crypter.
Un cryptage xor ? Sinon j'ai entendu parler d'un module "regex", ça pourrait être intéressant à utiliser ?

Ensuite, je ferais en sorte que lorsque le client se connecte au jeu et qu'il change de map, que le nombre de caractères soit vérifié par rapport à une base de données dans laquelle je stockerais les différentes tailles de chaque fichier map comme suit par exemple:

Map1 : 64
Map2 : 47
Map3 : 58

etc.. ( en Octets, du coup ! )

Si ce nombre est modifié d'un seul iota, le programme retéléchargera la map sur un serveur FTP incognito pour remettre la map d'origine dans le répertoire /maps, bonne idée ou pas ?

Comment sécuriser au mieux mes maps ? Même si c'est pas infaillible et ultra-complexe mais déjà, rendre la tâche plus difficile aux petits malins du dimanche.

Merci à vous tous !
( Salut à toi Laurent, au passage :-) )

anything