I'm trying to develop a networking part in my basic game engine in C++, but I'm faced with a rather strange problem (it is for me).
I got a Singleton Networker class that handles the set-up of a socket (UDP) and will try to register the username the client provided to the server, returning a bool that represents if the username is already taken by a different player or not. The class itself does not handle the packets itself, I aim to use a Packethandler class for that.
The problem is that I don't want a client to be able to create a PacketHandler directly because the entire point of the Networker class is to provide some kind of interface for handling that. The first idea I had is 'make the constructor of Packethandler private and create a Singleton' but then ofcourse the client can still ask the instance. Then I quickly though 'well protected then' but Networker is not extending PacketHandler. Then I thought 'well let's make Networker a friend of PacketHandler'. All the info I found up till now seems to discourage Friend usage however, so I wonder: Is my plan for the simple networking part flawed thus facing me with an issue like this or is my problem the reason friend functionality exists in the first place? What is the take of you guys on this, do you have a much better idea?
Edit: code of my idea.
Packethandler.h
#ifndef FANCY_PACKET_HANDLER
#define FANCY_PACKET_HANDLER
#include <SFML/Network.hpp>
namespace fancy {
namespace network {
class PacketHandler
{
friend class Networker;
private:
sf::IpAddress _hostAddress;
sf::UdpSocket _socket;
PacketHandler(std::string hostAdress);
public:
~PacketHandler();
void sendPacket(const char* packet_data, const unsigned int packet_size);
char* receivePacket();
};
}
}
#endif
Networker.h
#ifndef FANCY_NETWORKER
#define FANCY_NETWORKER
#include <SFML/Network.hpp>
#include <Engine/PacketHandler.h>
namespace fancy {
namespace network {
class Networker
{
public:
static Networker* instance();
bool openUdpSocket(unsigned short port);
bool registerUsername(char* username);
char* receiveOnSocket();
protected:
Networker();
private:
static Networker* _instance;
static PacketHandler* _packetHandler;
const char* _username;
sf::IpAddress _hostAddress;
sf::UdpSocket _socket;
};
}
}
#endif