Moved UDP logic from Hybrid server/client to UDP server/client. fixed bug in Server::CheckForTimeOuts.
This commit is contained in:
@@ -1,25 +1,13 @@
|
|||||||
#ifndef HybridClient_h__
|
#ifndef HybridClient_h__
|
||||||
#define HybridClient_h__
|
#define HybridClient_h__
|
||||||
|
|
||||||
#include "Client.h"
|
class HybridClient
|
||||||
|
|
||||||
|
|
||||||
class HybridClient : public Client
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HybridClient(ConfigFile* config);
|
HybridClient();
|
||||||
~HybridClient();
|
~HybridClient();
|
||||||
void Start(World* world, EventBroker* eventBroker);
|
|
||||||
private:
|
private:
|
||||||
// Assio UDP logic
|
|
||||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
|
||||||
boost::asio::io_service m_IOService;
|
|
||||||
boost::asio::ip::udp::socket m_Socket;
|
|
||||||
|
|
||||||
void connect();
|
|
||||||
void readFromServer();
|
|
||||||
int receive(char * data);
|
|
||||||
void send(Packet & packet);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,25 +1,12 @@
|
|||||||
#ifndef HybridServer_h__
|
#ifndef HybridServer_h__
|
||||||
#define HybridServer_h__
|
#define HybridServer_h__
|
||||||
|
|
||||||
#include "Server.h"
|
class HybridServer
|
||||||
#include <boost/asio/ip/udp.hpp>
|
|
||||||
|
|
||||||
class HybridServer : public Server
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HybridServer();
|
HybridServer();
|
||||||
~HybridServer();
|
~HybridServer();
|
||||||
private:
|
private:
|
||||||
// UDP logic
|
|
||||||
boost::asio::io_service m_IOService;
|
|
||||||
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
|
||||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
|
||||||
|
|
||||||
void readFromClients();
|
|
||||||
void parseConnect(Packet & packet);
|
|
||||||
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
|
||||||
void send(Packet & packet);
|
|
||||||
int receive(char * data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,12 +8,11 @@ class TCPClient : public Client
|
|||||||
public:
|
public:
|
||||||
TCPClient(ConfigFile* config);
|
TCPClient(ConfigFile* config);
|
||||||
~TCPClient();
|
~TCPClient();
|
||||||
void Start(World* world, EventBroker* eventBroker);
|
|
||||||
private:
|
private:
|
||||||
// Assio TCP logic
|
// Assio TCP logic
|
||||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||||
boost::asio::io_service m_IOService;
|
boost::asio::io_service m_IOService;
|
||||||
boost::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
std::unique_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
|
|
||||||
void connect();
|
void connect();
|
||||||
void readFromServer();
|
void readFromServer();
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ private:
|
|||||||
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 readFromClients();
|
|
||||||
void acceptNewConnections();
|
void acceptNewConnections();
|
||||||
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code & error);
|
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code & error);
|
||||||
|
void readFromClients();
|
||||||
|
int receive(char * data, boost::asio::ip::tcp::socket& socket);
|
||||||
void parseConnect(Packet & packet);
|
void parseConnect(Packet & packet);
|
||||||
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
void send(Packet & packet);
|
void send(Packet & packet);
|
||||||
int receive(char * data, boost::asio::ip::tcp::socket& socket);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef UDPClient_h__
|
||||||
|
#define UDPClient_h__
|
||||||
|
|
||||||
|
#include "Client.h"
|
||||||
|
|
||||||
|
|
||||||
|
class UDPClient : public Client
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UDPClient(ConfigFile* config);
|
||||||
|
~UDPClient();
|
||||||
|
private:
|
||||||
|
// Assio UDP logic
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
boost::asio::ip::udp::socket m_Socket;
|
||||||
|
|
||||||
|
void connect();
|
||||||
|
void readFromServer();
|
||||||
|
int receive(char * data);
|
||||||
|
void send(Packet & packet);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef UDPServer_h__
|
||||||
|
#define UDPServer_h__
|
||||||
|
|
||||||
|
#include "Server.h"
|
||||||
|
#include <boost/asio/ip/udp.hpp>
|
||||||
|
|
||||||
|
class UDPServer : public Server
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UDPServer();
|
||||||
|
~UDPServer();
|
||||||
|
private:
|
||||||
|
// UDP logic
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
||||||
|
|
||||||
|
void readFromClients();
|
||||||
|
int receive(char * data);
|
||||||
|
void parseConnect(Packet & packet);
|
||||||
|
void send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void send(Packet & packet);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -26,10 +26,15 @@
|
|||||||
// Network
|
// Network
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include "Network/Network.h"
|
#include "Network/Network.h"
|
||||||
|
// Hybrid
|
||||||
#include "Network/HybridServer.h"
|
#include "Network/HybridServer.h"
|
||||||
#include "Network/HybridClient.h"
|
#include "Network/HybridClient.h"
|
||||||
|
// TCP
|
||||||
#include "Network/TCPClient.h"
|
#include "Network/TCPClient.h"
|
||||||
#include "Network/TCPServer.h"
|
#include "Network/TCPServer.h"
|
||||||
|
// UDP
|
||||||
|
#include "Network/UDPServer.h"
|
||||||
|
#include "Network/UDPClient.h"
|
||||||
|
|
||||||
// Sound
|
// Sound
|
||||||
#include "Sound/SoundSystem.h"
|
#include "Sound/SoundSystem.h"
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ Client::Client(ConfigFile* config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Start(World* world, EventBroker* eventBroker)
|
void Client::Start(World* world, EventBroker* eventBroker)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,72 +1,10 @@
|
|||||||
#include "Network/HybridClient.h"
|
#include "Network/HybridClient.h"
|
||||||
|
|
||||||
using namespace boost::asio::ip;
|
|
||||||
|
|
||||||
HybridClient::HybridClient(ConfigFile * config) : Client(config), m_Socket(m_IOService)
|
HybridClient::HybridClient()
|
||||||
{
|
{
|
||||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridClient::~HybridClient()
|
HybridClient::~HybridClient()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridClient::Start(World* world, EventBroker* eventBroker)
|
|
||||||
{
|
|
||||||
Client::Start(world, eventBroker);
|
|
||||||
m_Socket.connect(m_ReceiverEndpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridClient::readFromServer()
|
|
||||||
{
|
|
||||||
while (m_Socket.available()) {
|
|
||||||
bytesRead = receive(readBuffer);
|
|
||||||
if (bytesRead > 0) {
|
|
||||||
Packet packet(readBuffer, bytesRead);
|
|
||||||
parseMessageType(packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int HybridClient::receive(char* data)
|
|
||||||
{
|
|
||||||
boost::system::error_code error;
|
|
||||||
|
|
||||||
int bytesReceived = m_Socket.receive_from(boost
|
|
||||||
::asio::buffer((void*)data, BUFFERSIZE),
|
|
||||||
m_ReceiverEndpoint,
|
|
||||||
0, error);
|
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataReceived += bytesReceived;
|
|
||||||
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
|
||||||
m_NetworkData.AmountOfMessagesReceived++;
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
|
||||||
}
|
|
||||||
return bytesReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridClient::send(Packet& packet)
|
|
||||||
{
|
|
||||||
m_Socket.send_to(boost::asio::buffer(
|
|
||||||
packet.Data(),
|
|
||||||
packet.Size()),
|
|
||||||
m_ReceiverEndpoint, 0);
|
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
m_NetworkData.AmountOfMessagesSent++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HybridClient::connect()
|
|
||||||
{
|
|
||||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
|
||||||
packet.WriteString(m_PlayerName);
|
|
||||||
m_StartPingTime = std::clock();
|
|
||||||
send(packet);
|
|
||||||
}
|
}
|
||||||
@@ -2,123 +2,8 @@
|
|||||||
|
|
||||||
HybridServer::HybridServer()
|
HybridServer::HybridServer()
|
||||||
{
|
{
|
||||||
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HybridServer::~HybridServer()
|
HybridServer::~HybridServer()
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
void HybridServer::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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::clock_t currentTime = std::clock();
|
|
||||||
// Send snapshot
|
|
||||||
if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
sendSnapshot();
|
|
||||||
previousSnapshotMessage = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send pings each
|
|
||||||
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
sendPing();
|
|
||||||
previousePingMessage = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time out logic
|
|
||||||
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
checkForTimeOuts();
|
|
||||||
timOutTimer = currentTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HybridServer::parseConnect(Packet& packet)
|
|
||||||
{
|
|
||||||
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 HybridServer::send(Packet& packet, PlayerDefinition & playerDefinition)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
int bytesSent = m_Socket->send_to(
|
|
||||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
|
||||||
playerDefinition.Endpoint,
|
|
||||||
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) {
|
|
||||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
|
||||||
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Send back to endpoint of received packet
|
|
||||||
void HybridServer::send(Packet & packet)
|
|
||||||
{
|
|
||||||
m_Socket->send_to(
|
|
||||||
boost::asio::buffer(
|
|
||||||
packet.Data(),
|
|
||||||
packet.Size()),
|
|
||||||
m_ReceiverEndpoint,
|
|
||||||
0);
|
|
||||||
if (isReadingData) {
|
|
||||||
// Network Debug data
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int HybridServer::receive(char * data)
|
|
||||||
{
|
|
||||||
unsigned int length = m_Socket->receive_from(
|
|
||||||
boost::asio::buffer((void*)data
|
|
||||||
, BUFFERSIZE)
|
|
||||||
, m_ReceiverEndpoint, 0);
|
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataReceived += length;
|
|
||||||
m_NetworkData.DataReceivedThisInterval += length;
|
|
||||||
m_NetworkData.AmountOfMessagesReceived++;
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ Server::Server()
|
|||||||
}
|
}
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
void Server::Start(World* world, EventBroker* eventBroker)
|
void Server::Start(World* world, EventBroker* eventBroker)
|
||||||
{
|
{
|
||||||
@@ -154,16 +153,20 @@ void Server::checkForTimeOuts()
|
|||||||
int startPing = 1000 * m_StartPingTime
|
int startPing = 1000 * m_StartPingTime
|
||||||
/ static_cast<double>(CLOCKS_PER_SEC);
|
/ static_cast<double>(CLOCKS_PER_SEC);
|
||||||
|
|
||||||
|
std::vector<PlayerID> playersToRemove;
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
if (kv.second.Address != boost::asio::ip::address()) {
|
if (kv.second.Address != boost::asio::ip::address()) {
|
||||||
int stopPing = 1000 * kv.second.StopTime /
|
int stopPing = 1000 * kv.second.StopTime /
|
||||||
static_cast<double>(CLOCKS_PER_SEC);
|
static_cast<double>(CLOCKS_PER_SEC);
|
||||||
if (startPing > stopPing + m_TimeoutMs) {
|
if (startPing > stopPing + m_TimeoutMs) {
|
||||||
LOG_INFO("User %i timed out!", kv.second.Name);
|
LOG_INFO("User %i timed out!", kv.second.Name);
|
||||||
disconnect(kv.first);
|
playersToRemove.push_back(kv.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < playersToRemove.size(); i++) {
|
||||||
|
disconnect(playersToRemove.at(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseDisconnect()
|
void Server::parseDisconnect()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using namespace boost::asio::ip;
|
|||||||
TCPClient::TCPClient(ConfigFile * config) : Client(config)
|
TCPClient::TCPClient(ConfigFile * config) : Client(config)
|
||||||
{
|
{
|
||||||
m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port);
|
m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||||
m_Socket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService, m_Endpoint));
|
m_Socket = std::unique_ptr<tcp::socket>(new tcp::socket(m_IOService, m_Endpoint));
|
||||||
tcp::no_delay option(true);
|
tcp::no_delay option(true);
|
||||||
m_Socket->set_option(option);
|
m_Socket->set_option(option);
|
||||||
}
|
}
|
||||||
@@ -15,10 +15,6 @@ TCPClient::~TCPClient()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPClient::Start(World * world, EventBroker * eventBroker)
|
|
||||||
{
|
|
||||||
Client::Start(world, eventBroker);
|
|
||||||
}
|
|
||||||
void TCPClient::connect()
|
void TCPClient::connect()
|
||||||
{
|
{
|
||||||
if (!m_IsConnected) {
|
if (!m_IsConnected) {
|
||||||
@@ -34,7 +30,7 @@ void TCPClient::connect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO FIX CRASH TCP CLIENT SEVER DISCONNECTS FIRST
|
|
||||||
void TCPClient::readFromServer()
|
void TCPClient::readFromServer()
|
||||||
{
|
{
|
||||||
while (m_Socket->available()) {
|
while (m_Socket->available()) {
|
||||||
@@ -50,14 +46,14 @@ int TCPClient::receive(char * data)
|
|||||||
// Read size of packet
|
// Read size of packet
|
||||||
int bytesReceived = m_Socket->read_some(boost
|
int bytesReceived = m_Socket->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 += m_Socket->read_some(boost
|
bytesReceived += m_Socket->read_some(boost
|
||||||
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
||||||
error);
|
error);
|
||||||
// Network Debug data
|
// Network Debug data
|
||||||
if (isReadingData) {
|
if (isReadingData) {
|
||||||
m_NetworkData.TotalDataReceived += bytesReceived;
|
m_NetworkData.TotalDataReceived += bytesReceived;
|
||||||
@@ -73,9 +69,10 @@ int TCPClient::receive(char * data)
|
|||||||
void TCPClient::send(Packet & packet)
|
void TCPClient::send(Packet & packet)
|
||||||
{
|
{
|
||||||
packet.UpdateSize();
|
packet.UpdateSize();
|
||||||
|
boost::system::error_code error;
|
||||||
m_Socket->send(boost::asio::buffer(
|
m_Socket->send(boost::asio::buffer(
|
||||||
packet.Data(),
|
packet.Data(),
|
||||||
packet.Size()));
|
packet.Size()), 0, error);
|
||||||
// Network Debug data
|
// Network Debug data
|
||||||
if (isReadingData) {
|
if (isReadingData) {
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ TCPServer::TCPServer()
|
|||||||
|
|
||||||
TCPServer::~TCPServer()
|
TCPServer::~TCPServer()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::readFromClients()
|
void TCPServer::readFromClients()
|
||||||
@@ -135,7 +134,6 @@ void TCPServer::send(Packet & packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//boost::shared_ptr<boost::asio::ip::tcp::socket> socket
|
|
||||||
int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket)
|
int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket)
|
||||||
{
|
{
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "Network/UDPClient.h"
|
||||||
|
|
||||||
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
|
UDPClient::UDPClient(ConfigFile * config) : Client(config), m_Socket(m_IOService)
|
||||||
|
{
|
||||||
|
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||||
|
m_Socket.connect(m_ReceiverEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPClient::~UDPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::readFromServer()
|
||||||
|
{
|
||||||
|
while (m_Socket.available()) {
|
||||||
|
bytesRead = receive(readBuffer);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
Packet packet(readBuffer, bytesRead);
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UDPClient::receive(char* data)
|
||||||
|
{
|
||||||
|
boost::system::error_code error;
|
||||||
|
|
||||||
|
int bytesReceived = m_Socket.receive_from(boost
|
||||||
|
::asio::buffer((void*)data, BUFFERSIZE),
|
||||||
|
m_ReceiverEndpoint,
|
||||||
|
0, error);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataReceived += bytesReceived;
|
||||||
|
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
||||||
|
m_NetworkData.AmountOfMessagesReceived++;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
|
}
|
||||||
|
return bytesReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::send(Packet& packet)
|
||||||
|
{
|
||||||
|
m_Socket.send_to(boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
m_ReceiverEndpoint, 0);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||||
|
m_NetworkData.AmountOfMessagesSent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::connect()
|
||||||
|
{
|
||||||
|
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||||
|
packet.WriteString(m_PlayerName);
|
||||||
|
m_StartPingTime = std::clock();
|
||||||
|
send(packet);
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
#include "Network/UDPServer.h"
|
||||||
|
|
||||||
|
UDPServer::UDPServer()
|
||||||
|
{
|
||||||
|
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::clock_t currentTime = std::clock();
|
||||||
|
// Send snapshot
|
||||||
|
if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
sendSnapshot();
|
||||||
|
previousSnapshotMessage = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send pings each
|
||||||
|
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
sendPing();
|
||||||
|
previousePingMessage = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time out logic
|
||||||
|
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
checkForTimeOuts();
|
||||||
|
timOutTimer = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPServer::parseConnect(Packet& packet)
|
||||||
|
{
|
||||||
|
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 {
|
||||||
|
int bytesSent = m_Socket->send_to(
|
||||||
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
|
playerDefinition.Endpoint,
|
||||||
|
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) {
|
||||||
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
|
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Send back to endpoint of received packet
|
||||||
|
void UDPServer::send(Packet & packet)
|
||||||
|
{
|
||||||
|
m_Socket->send_to(
|
||||||
|
boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
m_ReceiverEndpoint,
|
||||||
|
0);
|
||||||
|
if (isReadingData) {
|
||||||
|
// Network Debug data
|
||||||
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int UDPServer::receive(char * data)
|
||||||
|
{
|
||||||
|
unsigned int length = m_Socket->receive_from(
|
||||||
|
boost::asio::buffer((void*)data
|
||||||
|
, BUFFERSIZE)
|
||||||
|
, m_ReceiverEndpoint, 0);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataReceived += length;
|
||||||
|
m_NetworkData.DataReceivedThisInterval += length;
|
||||||
|
m_NetworkData.AmountOfMessagesReceived++;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+5
-3
@@ -181,13 +181,15 @@ void Game::networkFunction()
|
|||||||
bool isServer = m_Config->Get<bool>("Networking.IsServer", false);
|
bool isServer = m_Config->Get<bool>("Networking.IsServer", false);
|
||||||
if (!isServer) {
|
if (!isServer) {
|
||||||
m_IsClientOrServer = true;
|
m_IsClientOrServer = true;
|
||||||
|
m_ClientOrServer = new UDPClient(m_Config);
|
||||||
//m_ClientOrServer = new TCPClient(m_Config);
|
//m_ClientOrServer = new TCPClient(m_Config);
|
||||||
m_ClientOrServer = new HybridClient(m_Config);
|
//m_ClientOrServer = new HybridClient(m_Config);
|
||||||
}
|
}
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
m_IsClientOrServer = true;
|
m_IsClientOrServer = true;
|
||||||
//m_ClientOrServer = new TCPServer();
|
m_ClientOrServer = new UDPServer();
|
||||||
m_ClientOrServer = new HybridServer();
|
// m_ClientOrServer = new TCPServer();
|
||||||
|
//m_ClientOrServer = new HybridServer();
|
||||||
}
|
}
|
||||||
m_ClientOrServer->Start(m_World, m_EventBroker);
|
m_ClientOrServer->Start(m_World, m_EventBroker);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user