192 lines
5.0 KiB
C++
192 lines
5.0 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include <cstring>
|
|
#include "network_enet/enet_network.h"
|
|
#include "nstring/nstring.h"
|
|
#include "thread/mutex.h"
|
|
#include "log/log.h"
|
|
|
|
using GS::String;
|
|
using namespace GS::Network;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Enet::GetStatistics(Statistics &stat)
|
|
{
|
|
stat.received_data = host->totalReceivedData;
|
|
stat.sent_data = host->totalSentData;
|
|
}
|
|
int Enet::GetPeerPacketLossRatio(void *peer)
|
|
{
|
|
ENetPeer *enet_peer = (ENetPeer *)peer;
|
|
return enet_peer && enet_peer->packetsSent ? (enet_peer->packetsLost * 100) / enet_peer->packetsSent : 0;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Enet::SetPeerTimeout(void *peer, Timeout timeout)
|
|
{
|
|
int k = 1;
|
|
|
|
switch (timeout)
|
|
{
|
|
case TimeoutLong: k = 2; break;
|
|
case TimeoutVeryLong: k = 4; break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
enet_peer_timeout((ENetPeer *)peer, ENET_PEER_TIMEOUT_LIMIT * k, ENET_PEER_TIMEOUT_MINIMUM * k, ENET_PEER_TIMEOUT_MAXIMUM * k);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Enet::UpdateHost()
|
|
{
|
|
if (host)
|
|
{
|
|
ENetEvent event;
|
|
while (enet_host_service(host, &event, 0) > 0)
|
|
switch (event.type)
|
|
{
|
|
case ENET_EVENT_TYPE_CONNECT:
|
|
OnPeerConnection(event.peer);
|
|
break;
|
|
|
|
case ENET_EVENT_TYPE_RECEIVE:
|
|
OnPacketReceived(event.peer, (void *)event.packet->data, (size_t)event.packet->dataLength);
|
|
enet_packet_destroy(event.packet);
|
|
break;
|
|
|
|
case ENET_EVENT_TYPE_DISCONNECT:
|
|
OnConnectionClosed(event.peer);
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Enet::Close()
|
|
{
|
|
if (host)
|
|
enet_host_destroy(host);
|
|
host = NULL;
|
|
}
|
|
bool Enet::OpenServer(const char *hostname, int port)
|
|
{
|
|
Close();
|
|
|
|
ENetAddress address;
|
|
if (hostname)
|
|
enet_address_set_host(&address, hostname);
|
|
else
|
|
address.host = ENET_HOST_ANY;
|
|
address.port = (enet_uint16)port;
|
|
|
|
__LOG__ << "Starting server on " << (hostname ? hostname : "ANY") << ":" << port << "... ";
|
|
if ((host = enet_host_create(&address, 4, 0, 0, 0)) != NULL)
|
|
__LOG__ << "OK\n";
|
|
else
|
|
__LOG__ << "FAILED\n";
|
|
/*
|
|
if (host)
|
|
enet_host_compress_with_range_coder(host);
|
|
*/
|
|
return asbool(host);
|
|
}
|
|
bool Enet::OpenClient(const char *hostname, int port)
|
|
{
|
|
Close();
|
|
|
|
if ((host = enet_host_create(NULL, 1, 0, 0, 0)) == NULL)
|
|
return false;
|
|
|
|
// enet_host_compress_with_range_coder(host);
|
|
|
|
ENetAddress address;
|
|
enet_address_set_host(&address, hostname);
|
|
address.port = (enet_uint16)port;
|
|
|
|
// Connect on one channel to server.
|
|
__LOG__ << "Opening client connection to " << hostname << ":" << port << "... ";
|
|
bool r = asbool(enet_host_connect(host, &address, 1, 0));
|
|
if (r)
|
|
__LOG__ << "OK.\n";
|
|
else
|
|
__LOG__ << "FAILED\n";
|
|
return r;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Enet::GetHostAddress(String &address)
|
|
{
|
|
if (host)
|
|
{
|
|
char ip[64];
|
|
if (enet_address_get_host_ip(&((ENetHost *)host)->address, ip, 63) < 0)
|
|
return false;
|
|
address = ip;
|
|
}
|
|
return true;
|
|
}
|
|
bool Enet::GetPeerAddress(void *peer, String &address)
|
|
{
|
|
if (peer)
|
|
{
|
|
char ip[64];
|
|
if (enet_address_get_host_ip(&((ENetPeer *)peer)->address, ip, 63) < 0)
|
|
return false;
|
|
address = ip;
|
|
}
|
|
return true;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Enet::Send(void *peer, const void *data, size_t size)
|
|
{
|
|
// __LOG_V__ << "Send Enet packet of " << size << " bytes.\n";
|
|
|
|
ENetPacket *packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
|
if (!packet || enet_peer_send((ENetPeer *)peer, 0, packet))
|
|
return false;
|
|
enet_host_flush(host);
|
|
return true;
|
|
}
|
|
bool Enet::Broadcast(const void *data, size_t size)
|
|
{
|
|
ENetPacket *packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
|
if (!packet)
|
|
return false;
|
|
enet_host_broadcast(host, 0, packet);
|
|
enet_host_flush(host);
|
|
return true;
|
|
}
|
|
void Enet::Disconnect(void *peer)
|
|
{
|
|
if (peer)
|
|
enet_peer_disconnect((ENetPeer *)peer, 0);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Enet::Enet()
|
|
{
|
|
host = NULL;
|
|
enet_initialize();
|
|
}
|
|
Enet::~Enet()
|
|
{
|
|
Close();
|
|
enet_deinitialize();
|
|
}
|
|
//------------------------------------------------------------------------------
|