Network is now working as udp or tcp. Next step is making the hybrid.
This commit is contained in:
@@ -1,20 +1,32 @@
|
|||||||
#ifndef NetworkServer_h__
|
#ifndef NetworkServer_h__
|
||||||
#define NetworkServer_h__
|
#define NetworkServer_h__
|
||||||
|
#include <boost/asio.hpp>
|
||||||
#include "Network/Packet.h"
|
#include "Network/Packet.h"
|
||||||
|
#include "Network/PlayerDefinition.h"
|
||||||
#define BUFFERSIZE 32000
|
#define BUFFERSIZE 32000
|
||||||
typedef unsigned int PlayerID;
|
typedef unsigned int PlayerID;
|
||||||
typedef unsigned int PacketID;
|
typedef unsigned int PacketID;
|
||||||
|
|
||||||
class NetworkServer
|
class NetworkServer
|
||||||
{
|
{
|
||||||
//public:
|
public:
|
||||||
// virtual void Connect(std::string playerName, std::string address, int port) = 0;
|
virtual void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers) = 0;
|
||||||
// virtual void Disconnect() = 0;
|
virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
// virtual Packet Receive() = 0;
|
virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
// virtual void Send(Packet & packet) = 0;
|
virtual void Send(Packet & packet) = 0;
|
||||||
//protected:
|
protected:
|
||||||
// char m_ReadBuffer[BUFFERSIZE] = { 0 };
|
char m_ReadBuffer[BUFFERSIZE] = { 0 };
|
||||||
|
//void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code & error);
|
||||||
|
//void parseConnect(Packet & packet);
|
||||||
|
//void readFromClients();
|
||||||
|
|
||||||
|
//public:
|
||||||
|
// virtual void Connect(std::string playerName, std::string address, int port) = 0;
|
||||||
|
// virtual void Disconnect() = 0;
|
||||||
|
// virtual Packet Receive() = 0;
|
||||||
|
// virtual void Send(Packet & packet) = 0;
|
||||||
|
//protected:
|
||||||
|
// char m_ReadBuffer[BUFFERSIZE] = { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -57,7 +57,7 @@ public:
|
|||||||
void ChangePacketID(unsigned int& packetID);
|
void ChangePacketID(unsigned int& packetID);
|
||||||
int Size() { return m_Offset; };
|
int Size() { return m_Offset; };
|
||||||
char* Data() { return m_Data; };
|
char* Data() { return m_Data; };
|
||||||
MessageType GetMessageType() { return m_MessageType; };
|
MessageType GetMessageType();
|
||||||
unsigned int DataReadSize() { return m_ReturnDataOffset; }
|
unsigned int DataReadSize() { return m_ReturnDataOffset; }
|
||||||
unsigned int MaxSize() { return m_MaxPacketSize; }
|
unsigned int MaxSize() { return m_MaxPacketSize; }
|
||||||
unsigned int HeaderSize() { return m_HeaderSize; }
|
unsigned int HeaderSize() { return m_HeaderSize; }
|
||||||
@@ -68,7 +68,6 @@ private:
|
|||||||
int m_Offset = 0;
|
int m_Offset = 0;
|
||||||
unsigned int m_MaxPacketSize = 512;
|
unsigned int m_MaxPacketSize = 512;
|
||||||
unsigned int m_HeaderSize = 0;
|
unsigned int m_HeaderSize = 0;
|
||||||
MessageType m_MessageType = MessageType::Invalid;
|
|
||||||
void resizeData();
|
void resizeData();
|
||||||
void resizeData(int size);
|
void resizeData(int size);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <glm/common.hpp>
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Network/TCPServer.h"
|
||||||
|
#include "Network/UDPServer.h"
|
||||||
#include "Network/MessageType.h"
|
#include "Network/MessageType.h"
|
||||||
#include "Network/PlayerDefinition.h"
|
#include "Network/PlayerDefinition.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
@@ -17,6 +19,7 @@
|
|||||||
#include "Core/EPlayerSpawned.h"
|
#include "Core/EPlayerSpawned.h"
|
||||||
#include "Core/EEntityDeleted.h"
|
#include "Core/EEntityDeleted.h"
|
||||||
#include "Core/EComponentDeleted.h"
|
#include "Core/EComponentDeleted.h"
|
||||||
|
|
||||||
class Server : public Network
|
class Server : public Network
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -49,7 +52,7 @@ protected:
|
|||||||
// Game logic
|
// Game logic
|
||||||
World* m_World;
|
World* m_World;
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
// Packet loss logic
|
// Packet loss logic
|
||||||
PacketID m_PacketID = 0;
|
PacketID m_PacketID = 0;
|
||||||
PacketID m_PreviousPacketID = 0;
|
PacketID m_PreviousPacketID = 0;
|
||||||
@@ -70,13 +73,15 @@ protected:
|
|||||||
void parsePlayerTransform(Packet& packet);
|
void parsePlayerTransform(Packet& packet);
|
||||||
void parseOnInputCommand(Packet& packet);
|
void parseOnInputCommand(Packet& packet);
|
||||||
void parseClientPing();
|
void parseClientPing();
|
||||||
void parsePing();
|
void parsePing();
|
||||||
|
void parseConnect(Packet & packet, PlayerDefinition & pd);
|
||||||
|
void parseTCPConnect(Packet & packet);
|
||||||
void parseDisconnect();
|
void parseDisconnect();
|
||||||
// Pure virtual functions
|
//// Pure virtual functions
|
||||||
virtual void readFromClients() = 0;
|
//virtual void readFromClients() = 0;
|
||||||
virtual void send(Packet& packet, PlayerDefinition & playerDefinition) = 0;
|
//virtual void send(Packet& packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
virtual void send(Packet& packet) = 0;
|
//virtual void send(Packet& packet) = 0;
|
||||||
virtual void parseConnect(Packet& packet) = 0;
|
|
||||||
// Debug event
|
// Debug event
|
||||||
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
@@ -86,6 +91,9 @@ protected:
|
|||||||
bool OnEntityDeleted(const Events::EntityDeleted& e);
|
bool OnEntityDeleted(const Events::EntityDeleted& e);
|
||||||
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
|
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
|
||||||
bool OnComponentDeleted(const Events::ComponentDeleted& e);
|
bool OnComponentDeleted(const Events::ComponentDeleted& e);
|
||||||
|
private:
|
||||||
|
TCPServer m_TCPServer;
|
||||||
|
//UDPServer m_UDPServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,26 +1,30 @@
|
|||||||
#ifndef TCPServer_h__
|
#ifndef TCPServer_h__
|
||||||
#define TCPServer_h__
|
#define TCPServer_h__
|
||||||
|
|
||||||
#include "Server.h"
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include "NetworkServer.h"
|
||||||
|
|
||||||
class TCPServer : public Server
|
class TCPServer : public NetworkServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TCPServer();
|
TCPServer();
|
||||||
~TCPServer();
|
~TCPServer();
|
||||||
|
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
||||||
|
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet);
|
||||||
private:
|
private:
|
||||||
// TCP logic
|
// TCP logic
|
||||||
boost::asio::io_service m_IOService;
|
boost::asio::io_service m_IOService;
|
||||||
std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
|
std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
|
||||||
boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket;
|
boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket;
|
||||||
|
|
||||||
void acceptNewConnections();
|
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code & error);
|
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
void readFromClients();
|
const boost::system::error_code& error);
|
||||||
int receive(char * data, boost::asio::ip::tcp::socket& socket);
|
int readBuffer(char* data, PlayerDefinition& playerDefinition);
|
||||||
void parseConnect(Packet & packet);
|
|
||||||
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
|
||||||
void send(Packet & packet);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,25 +1,31 @@
|
|||||||
#ifndef UDPServer_h__
|
#ifndef UDPServer_h__
|
||||||
#define UDPServer_h__
|
#define UDPServer_h__
|
||||||
|
|
||||||
#include "Server.h"
|
#include "NetworkServer.h"
|
||||||
#include <boost/asio/ip/udp.hpp>
|
#include <boost/asio/ip/udp.hpp>
|
||||||
|
//
|
||||||
|
//virtual void AcceptNewConnections() = 0;
|
||||||
|
//virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
|
//virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
|
//virtual void Send(Packet & packet) = 0;
|
||||||
|
|
||||||
class UDPServer : public Server
|
class UDPServer : public NetworkServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UDPServer();
|
UDPServer();
|
||||||
~UDPServer();
|
~UDPServer();
|
||||||
|
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
||||||
|
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
//void parseConnect(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet);
|
||||||
|
bool IsSocketAvailable();
|
||||||
private:
|
private:
|
||||||
// UDP logic
|
// UDP logic
|
||||||
boost::asio::io_service m_IOService;
|
boost::asio::io_service m_IOService;
|
||||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
||||||
|
int readBuffer(char* data);
|
||||||
void readFromClients();
|
|
||||||
int receive(char * data);
|
|
||||||
void parseConnect(Packet & packet);
|
|
||||||
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
|
||||||
void send(Packet & packet);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+3
-10
@@ -28,15 +28,8 @@
|
|||||||
#include "Network/Network.h"
|
#include "Network/Network.h"
|
||||||
// Client
|
// Client
|
||||||
#include "Network/Client.h"
|
#include "Network/Client.h"
|
||||||
// Hybrid
|
// Server
|
||||||
#include "Network/HybridServer.h"
|
#include "Network/Server.h"
|
||||||
#include "Network/HybridClient.h"
|
|
||||||
// TCP
|
|
||||||
#include "Network/TCPClient.h"
|
|
||||||
#include "Network/TCPServer.h"
|
|
||||||
// UDP
|
|
||||||
#include "Network/UDPServer.h"
|
|
||||||
#include "Network/UDPClient.h"
|
|
||||||
|
|
||||||
// Sound
|
// Sound
|
||||||
#include "Sound/SoundSystem.h"
|
#include "Sound/SoundSystem.h"
|
||||||
@@ -69,8 +62,8 @@ private:
|
|||||||
|
|
||||||
// Network methods
|
// Network methods
|
||||||
void networkFunction();
|
void networkFunction();
|
||||||
Network* m_ClientOrServer;
|
|
||||||
std::unique_ptr<Client> m_Client;
|
std::unique_ptr<Client> m_Client;
|
||||||
|
std::unique_ptr<Server> m_Server;
|
||||||
bool m_IsClientOrServer = false;
|
bool m_IsClientOrServer = false;
|
||||||
bool m_IsServer = false;
|
bool m_IsServer = false;
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ void Packet::Init(MessageType type, unsigned int & packetID)
|
|||||||
// allocate memory for size of packet(only used in tcp)
|
// allocate memory for size of packet(only used in tcp)
|
||||||
Packet::WritePrimitive<int>(0);
|
Packet::WritePrimitive<int>(0);
|
||||||
// Add message type
|
// Add message type
|
||||||
m_MessageType = type;
|
|
||||||
int messageType = static_cast<int>(type);
|
int messageType = static_cast<int>(type);
|
||||||
Packet::WritePrimitive<int>(messageType);
|
Packet::WritePrimitive<int>(messageType);
|
||||||
Packet::WritePrimitive<int>(packetID);
|
Packet::WritePrimitive<int>(packetID);
|
||||||
@@ -120,6 +119,13 @@ void Packet::ChangePacketID(unsigned int & packetID)
|
|||||||
memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int));
|
memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageType Packet::GetMessageType()
|
||||||
|
{
|
||||||
|
MessageType messagType;
|
||||||
|
memcpy(&messagType, m_Data + sizeof(int), sizeof(int));
|
||||||
|
return messagType;
|
||||||
|
}
|
||||||
|
|
||||||
void Packet::resizeData()
|
void Packet::resizeData()
|
||||||
{
|
{
|
||||||
resizeData(m_MaxPacketSize * 2);
|
resizeData(m_MaxPacketSize * 2);
|
||||||
|
|||||||
@@ -23,7 +23,35 @@ void Server::Start(World* world, EventBroker* eventBroker)
|
|||||||
|
|
||||||
void Server::Update()
|
void Server::Update()
|
||||||
{
|
{
|
||||||
readFromClients();
|
m_TCPServer.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers);
|
||||||
|
PlayerDefinition pd;
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
while (kv.second.TCPSocket->available()) {
|
||||||
|
// Packet will get real data in receive
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
m_TCPServer.Receive(packet, kv.second);
|
||||||
|
m_Address = kv.second.TCPSocket->remote_endpoint().address();
|
||||||
|
m_Port = kv.second.TCPSocket->remote_endpoint().port();
|
||||||
|
if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
parseTCPConnect(packet);
|
||||||
|
} else {
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//while (m_UDPServer.IsSocketAvailable()) {
|
||||||
|
// // Packet will get real data in receive
|
||||||
|
// Packet packet(MessageType::Invalid);
|
||||||
|
// m_UDPServer.Receive(packet, pd);
|
||||||
|
// m_Address = pd.Endpoint.address();
|
||||||
|
// m_Port = pd.Endpoint.port();
|
||||||
|
// if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
// parseConnect(packet, pd);
|
||||||
|
// } else {
|
||||||
|
// parseMessageType(packet);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
std::clock_t currentTime = std::clock();
|
std::clock_t currentTime = std::clock();
|
||||||
// Send snapshot
|
// Send snapshot
|
||||||
@@ -60,7 +88,7 @@ void Server::parseMessageType(Packet& packet)
|
|||||||
//identifyPacketLoss();
|
//identifyPacketLoss();
|
||||||
switch (static_cast<MessageType>(messageType)) {
|
switch (static_cast<MessageType>(messageType)) {
|
||||||
case MessageType::Connect:
|
case MessageType::Connect:
|
||||||
parseConnect(packet);
|
//parseConnect(packet);
|
||||||
break;
|
break;
|
||||||
case MessageType::Ping:
|
case MessageType::Ping:
|
||||||
parsePing();
|
parsePing();
|
||||||
@@ -90,7 +118,7 @@ void Server::broadcast(Packet& packet)
|
|||||||
{
|
{
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
packet.ChangePacketID(kv.second.PacketID);
|
packet.ChangePacketID(kv.second.PacketID);
|
||||||
send(packet, kv.second);
|
m_TCPServer.Send(packet, kv.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +212,56 @@ void Server::checkForTimeOuts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::parseConnect(Packet & packet, PlayerDefinition & pd)
|
||||||
|
{
|
||||||
|
//LOG_INFO("Parsing connections");
|
||||||
|
//// Check if player is already connected
|
||||||
|
//if (GetPlayerIDFromEndpoint() != -1) {
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//// Create a new player
|
||||||
|
//pd.EntityID = 0; // Overlook this
|
||||||
|
//pd.Address = pd.Endpoint.address();
|
||||||
|
//pd.Port = pd.Endpoint.port();
|
||||||
|
//pd.Name = packet.ReadString();
|
||||||
|
//pd.PacketID = 0;
|
||||||
|
//pd.StopTime = std::clock();
|
||||||
|
//m_ConnectedPlayers[m_NextPlayerID++] = pd;
|
||||||
|
//LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
||||||
|
|
||||||
|
//// Send a message to the player that connected
|
||||||
|
//Packet connnectPacket(MessageType::Connect, pd.PacketID);
|
||||||
|
//m_UDPServer.Send(connnectPacket);
|
||||||
|
|
||||||
|
//// Send notification that a player has connected
|
||||||
|
//Packet notificationPacket(MessageType::PlayerConnected);
|
||||||
|
//broadcast(notificationPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseTCPConnect(Packet & packet)
|
||||||
|
{
|
||||||
|
LOG_INFO("Parsing connections");
|
||||||
|
// Check if player is already connected
|
||||||
|
PlayerID playerID = GetPlayerIDFromEndpoint();
|
||||||
|
if (playerID = -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Create a new player
|
||||||
|
m_ConnectedPlayers.at(playerID).EntityID = 0; // Overlook this
|
||||||
|
m_ConnectedPlayers.at(playerID).Name = packet.ReadString();
|
||||||
|
m_ConnectedPlayers.at(playerID).PacketID = 0;
|
||||||
|
m_ConnectedPlayers.at(playerID).StopTime = std::clock();
|
||||||
|
LOG_INFO("Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str());
|
||||||
|
|
||||||
|
// Send a message to the player that connected
|
||||||
|
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||||
|
m_TCPServer.Send(connnectPacket);
|
||||||
|
|
||||||
|
// Send notification that a player has connected
|
||||||
|
Packet notificationPacket(MessageType::PlayerConnected);
|
||||||
|
//broadcast(notificationPacket);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::parseDisconnect()
|
void Server::parseDisconnect()
|
||||||
{
|
{
|
||||||
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
||||||
@@ -232,7 +310,7 @@ void Server::kick(PlayerID player)
|
|||||||
{
|
{
|
||||||
disconnect(player);
|
disconnect(player);
|
||||||
Packet packet = Packet(MessageType::Kick);
|
Packet packet = Packet(MessageType::Kick);
|
||||||
send(packet);
|
m_TCPServer.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::OnInputCommand(const Events::InputCommand & e)
|
bool Server::OnInputCommand(const Events::InputCommand & e)
|
||||||
@@ -261,7 +339,7 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
|
|||||||
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
||||||
// We don't send PlayerID here because it will always be set to -1
|
// We don't send PlayerID here because it will always be set to -1
|
||||||
packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name);
|
packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name);
|
||||||
send(packet, m_ConnectedPlayers[e.PlayerID]);
|
m_TCPServer.Send(packet, m_ConnectedPlayers[e.PlayerID]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +375,7 @@ void Server::parseClientPing()
|
|||||||
// Return ping
|
// Return ping
|
||||||
Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID);
|
Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID);
|
||||||
packet.WriteString("Ping received");
|
packet.WriteString("Ping received");
|
||||||
send(packet);
|
m_TCPServer.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parsePing()
|
void Server::parsePing()
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ TCPClient::~TCPClient()
|
|||||||
void TCPClient::Connect(std::string playerName, std::string address, int port)
|
void TCPClient::Connect(std::string playerName, std::string address, int port)
|
||||||
{
|
{
|
||||||
if (m_Socket) {
|
if (m_Socket) {
|
||||||
|
if (m_IsConnected) {
|
||||||
|
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||||
|
packet.WriteString(playerName);
|
||||||
|
Send(packet);
|
||||||
|
LOG_INFO("Connect message sent again!");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_IsConnected) {
|
if (!m_IsConnected) {
|
||||||
@@ -29,6 +35,7 @@ void TCPClient::Connect(std::string playerName, std::string address, int port)
|
|||||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||||
packet.WriteString(playerName);
|
packet.WriteString(playerName);
|
||||||
Send(packet);
|
Send(packet);
|
||||||
|
LOG_INFO("Connect message sent!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,42 +7,38 @@ TCPServer::TCPServer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
TCPServer::~TCPServer()
|
TCPServer::~TCPServer()
|
||||||
{ }
|
|
||||||
|
|
||||||
void TCPServer::readFromClients()
|
|
||||||
{
|
{
|
||||||
acceptNewConnections();
|
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
|
||||||
while (kv.second.TCPSocket->available()) {
|
|
||||||
try {
|
|
||||||
bytesRead = receive(readBuffer, *kv.second.TCPSocket);
|
|
||||||
lastReceivedSocket = kv.second.TCPSocket;
|
|
||||||
// Get logic for mother class
|
|
||||||
boost::asio::ip::tcp::endpoint remoteEndpoint = kv.second.TCPSocket->remote_endpoint();
|
|
||||||
m_Address = remoteEndpoint.address();
|
|
||||||
m_Port = remoteEndpoint.port();
|
|
||||||
// Recreate packets
|
|
||||||
Packet packet(readBuffer, bytesRead);
|
|
||||||
parseMessageType(packet);
|
|
||||||
} catch (const std::exception& err) {
|
|
||||||
//LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::acceptNewConnections()
|
void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
|
||||||
{
|
{
|
||||||
|
//PlayerDefinition pd;
|
||||||
|
//connectedPlayers[nextPlayerID++] = pd;
|
||||||
boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService));
|
boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService));
|
||||||
m_IOService.poll();
|
m_IOService.poll();
|
||||||
acceptor->async_accept(*newSocket,
|
acceptor->async_accept(*newSocket,
|
||||||
boost::bind(&TCPServer::handle_accept, this, newSocket,
|
boost::bind(&TCPServer::handle_accept, this, newSocket, boost::ref(nextPlayerID), boost::ref(connectedPlayers),
|
||||||
boost::asio::placeholders::error));
|
boost::asio::placeholders::error));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket, const boost::system::error_code& error)
|
PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
|
boost::asio::ip::address address, unsigned short port)
|
||||||
{
|
{
|
||||||
if (!error && GetPlayerIDFromEndpoint() == -1) {
|
for (auto& kv : connectedPlayers) {
|
||||||
|
if (kv.second.Address == address &&
|
||||||
|
kv.second.Port == port) {
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket,
|
||||||
|
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
|
const boost::system::error_code& error)
|
||||||
|
{
|
||||||
|
if (!error && GetPlayerIDFromEndpoint(connectedPlayers, socket->remote_endpoint().address(),
|
||||||
|
socket->remote_endpoint().port()) == -1) {
|
||||||
// Add tcp socket to connections
|
// Add tcp socket to connections
|
||||||
boost::asio::ip::tcp::no_delay option(true);
|
boost::asio::ip::tcp::no_delay option(true);
|
||||||
socket->set_option(option);
|
socket->set_option(option);
|
||||||
@@ -51,55 +47,24 @@ void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket, const boost
|
|||||||
pd.TCPSocket = socket;
|
pd.TCPSocket = socket;
|
||||||
pd.Address = socket.get()->remote_endpoint().address();
|
pd.Address = socket.get()->remote_endpoint().address();
|
||||||
pd.Port = socket.get()->remote_endpoint().port();
|
pd.Port = socket.get()->remote_endpoint().port();
|
||||||
m_ConnectedPlayers[m_NextPlayerID++] = pd;
|
connectedPlayers[nextPlayerID++] = pd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::parseConnect(Packet & packet)
|
void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
{
|
|
||||||
LOG_INFO("Parsing connections");
|
|
||||||
// Check if player is already connected
|
|
||||||
PlayerID playerID = GetPlayerIDFromEndpoint();
|
|
||||||
if (playerID = -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new player
|
|
||||||
m_ConnectedPlayers.at(playerID).EntityID = 0; // Overlook this
|
|
||||||
m_ConnectedPlayers.at(playerID).Name = packet.ReadString();
|
|
||||||
m_ConnectedPlayers.at(playerID).PacketID = 0;
|
|
||||||
m_ConnectedPlayers.at(playerID).StopTime = std::clock();
|
|
||||||
LOG_INFO("Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str());
|
|
||||||
|
|
||||||
// Send a message to the player that connected
|
|
||||||
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
|
||||||
send(connnectPacket);
|
|
||||||
|
|
||||||
// Send notification that a player has connected
|
|
||||||
Packet notificationPacket(MessageType::PlayerConnected);
|
|
||||||
broadcast(notificationPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TCPServer::send(Packet & packet, PlayerDefinition & playerDefinition)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
packet.UpdateSize();
|
packet.UpdateSize();
|
||||||
int bytesSent = playerDefinition.TCPSocket->send(
|
int bytesSent = playerDefinition.TCPSocket->send(
|
||||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
0);
|
0);
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
m_NetworkData.AmountOfMessagesSent++;
|
|
||||||
}
|
|
||||||
} catch (const boost::system::system_error& e) {
|
} catch (const boost::system::system_error& e) {
|
||||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::send(Packet & packet)
|
void TCPServer::Send(Packet & packet)
|
||||||
{
|
{
|
||||||
packet.UpdateSize();
|
packet.UpdateSize();
|
||||||
lastReceivedSocket->send(
|
lastReceivedSocket->send(
|
||||||
@@ -107,33 +72,33 @@ void TCPServer::send(Packet & packet)
|
|||||||
packet.Data(),
|
packet.Data(),
|
||||||
packet.Size()),
|
packet.Size()),
|
||||||
0);
|
0);
|
||||||
if (isReadingData) {
|
}
|
||||||
// Network Debug data
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
{
|
||||||
|
int bytesRead = readBuffer(m_ReadBuffer, playerDefinition);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket)
|
int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition)
|
||||||
{
|
{
|
||||||
|
if (!playerDefinition.TCPSocket) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
// Read size of packet
|
// Read size of packet
|
||||||
int bytesReceived = socket.read_some(boost
|
int bytesReceived = playerDefinition.TCPSocket->read_some(boost
|
||||||
::asio::buffer((void*)data, sizeof(int)),
|
::asio::buffer((void*)data, sizeof(int)),
|
||||||
error);
|
error);
|
||||||
int sizeOfPacket = 0;
|
int sizeOfPacket = 0;
|
||||||
memcpy(&sizeOfPacket, data, sizeof(int));
|
memcpy(&sizeOfPacket, data, sizeof(int));
|
||||||
|
|
||||||
// Read the rest of the message
|
// Read the rest of the message
|
||||||
bytesReceived += socket.read_some(boost
|
bytesReceived += playerDefinition.TCPSocket->read_some(boost
|
||||||
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
||||||
error);
|
error);
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataReceived += bytesReceived;
|
|
||||||
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
|
||||||
m_NetworkData.AmountOfMessagesReceived++;
|
|
||||||
}
|
|
||||||
if (error) {
|
if (error) {
|
||||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,71 +6,23 @@ UDPServer::UDPServer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
UDPServer::~UDPServer()
|
UDPServer::~UDPServer()
|
||||||
{ }
|
|
||||||
|
|
||||||
void UDPServer::readFromClients()
|
|
||||||
{
|
{
|
||||||
while (m_Socket->available()) {
|
|
||||||
try {
|
|
||||||
bytesRead = receive(readBuffer);
|
|
||||||
m_Address = m_ReceiverEndpoint.address();
|
|
||||||
m_Port = m_ReceiverEndpoint.port();
|
|
||||||
Packet packet(readBuffer, bytesRead);
|
|
||||||
parseMessageType(packet);
|
|
||||||
} catch (const std::exception& err) {
|
|
||||||
//LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPServer::parseConnect(Packet& packet)
|
void UDPServer::Send(Packet& packet, PlayerDefinition & playerDefinition)
|
||||||
{
|
|
||||||
LOG_INFO("Parsing connections");
|
|
||||||
// Check if player is already connected
|
|
||||||
if (GetPlayerIDFromEndpoint() != -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Create a new player
|
|
||||||
PlayerDefinition pd;
|
|
||||||
pd.EntityID = 0; // Overlook this
|
|
||||||
pd.Endpoint = m_ReceiverEndpoint;
|
|
||||||
pd.Address = m_ReceiverEndpoint.address();
|
|
||||||
pd.Port = m_ReceiverEndpoint.port();
|
|
||||||
pd.Name = packet.ReadString();
|
|
||||||
pd.PacketID = 0;
|
|
||||||
pd.StopTime = std::clock();
|
|
||||||
m_ConnectedPlayers[m_NextPlayerID++] = pd;
|
|
||||||
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
|
||||||
|
|
||||||
// Send a message to the player that connected
|
|
||||||
Packet connnectPacket(MessageType::Connect, pd.PacketID);
|
|
||||||
send(connnectPacket);
|
|
||||||
|
|
||||||
// Send notification that a player has connected
|
|
||||||
Packet notificationPacket(MessageType::PlayerConnected);
|
|
||||||
broadcast(notificationPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDPServer::send(Packet& packet, PlayerDefinition & playerDefinition)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
int bytesSent = m_Socket->send_to(
|
int bytesSent = m_Socket->send_to(
|
||||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
playerDefinition.Endpoint,
|
playerDefinition.Endpoint,
|
||||||
0);
|
0);
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
m_NetworkData.AmountOfMessagesSent++;
|
|
||||||
}
|
|
||||||
} catch (const boost::system::system_error& e) {
|
} catch (const boost::system::system_error& e) {
|
||||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send back to endpoint of received packet
|
// Send back to endpoint of received packet
|
||||||
void UDPServer::send(Packet & packet)
|
void UDPServer::Send(Packet & packet)
|
||||||
{
|
{
|
||||||
m_Socket->send_to(
|
m_Socket->send_to(
|
||||||
boost::asio::buffer(
|
boost::asio::buffer(
|
||||||
@@ -78,27 +30,32 @@ void UDPServer::send(Packet & packet)
|
|||||||
packet.Size()),
|
packet.Size()),
|
||||||
m_ReceiverEndpoint,
|
m_ReceiverEndpoint,
|
||||||
0);
|
0);
|
||||||
if (isReadingData) {
|
|
||||||
// Network Debug data
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int UDPServer::receive(char * data)
|
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
int bytesRead = readBuffer(m_ReadBuffer);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
|
}
|
||||||
|
playerDefinition.Endpoint = m_ReceiverEndpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPServer::IsSocketAvailable()
|
||||||
|
{
|
||||||
|
return m_Socket->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
int UDPServer::readBuffer(char* data)
|
||||||
{
|
{
|
||||||
unsigned int length = m_Socket->receive_from(
|
unsigned int length = m_Socket->receive_from(
|
||||||
boost::asio::buffer((void*)data
|
boost::asio::buffer((void*)data
|
||||||
, BUFFERSIZE)
|
, BUFFERSIZE)
|
||||||
, m_ReceiverEndpoint, 0);
|
, m_ReceiverEndpoint, 0);
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataReceived += length;
|
|
||||||
m_NetworkData.DataReceivedThisInterval += length;
|
|
||||||
m_NetworkData.AmountOfMessagesReceived++;
|
|
||||||
}
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
|
||||||
|
{
|
||||||
|
}
|
||||||
+3
-3
@@ -156,7 +156,7 @@ void Game::Tick()
|
|||||||
// Update network
|
// Update network
|
||||||
if (m_IsClientOrServer) {
|
if (m_IsClientOrServer) {
|
||||||
if (m_IsServer)
|
if (m_IsServer)
|
||||||
m_ClientOrServer->Update();
|
m_Server->Update();
|
||||||
else if (!m_IsServer) {
|
else if (!m_IsServer) {
|
||||||
m_Client->Update();
|
m_Client->Update();
|
||||||
}
|
}
|
||||||
@@ -197,9 +197,9 @@ void Game::networkFunction()
|
|||||||
if (m_IsServer) {
|
if (m_IsServer) {
|
||||||
m_IsClientOrServer = true;
|
m_IsClientOrServer = true;
|
||||||
// m_ClientOrServer = new UDPServer();
|
// m_ClientOrServer = new UDPServer();
|
||||||
m_ClientOrServer = new TCPServer();
|
m_Server = std::unique_ptr<Server>(new Server());
|
||||||
//m_ClientOrServer = new HybridServer();
|
//m_ClientOrServer = new HybridServer();
|
||||||
m_ClientOrServer->Start(m_World, m_EventBroker);
|
m_Server->Start(m_World, m_EventBroker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user