381 lines
7.6 KiB
C++
381 lines
7.6 KiB
C++
#include "ehs/io/socket/EHC.h"
|
|
#include "ehs/io/socket/ehc/NetEnc.h"
|
|
#include "ehs/io/socket/ehc/NetServerCh.h"
|
|
#include "ehs/io/socket/ehc/NetClientCh.h"
|
|
#include "ehs/io/socket/ehc/NetSys.h"
|
|
#include "ehs/io/socket/ehc/NetEnd.h"
|
|
#include "ehs/PRNG.h"
|
|
|
|
|
|
namespace ehs
|
|
{
|
|
const Version EHC::version(1, 0, 0);
|
|
|
|
EHC::~EHC()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
EHC::EHC(const IP version)
|
|
: udp(version), buffer(nullptr), bufferSize(0), lastTSC(0), delta(0.0f)
|
|
{
|
|
}
|
|
|
|
EHC::EHC(EHC &&sock) noexcept
|
|
: udp((UDP&&)sock.udp), buffer(sock.buffer), bufferSize(sock.bufferSize), lastTSC(sock.lastTSC), delta(sock.delta),
|
|
encryptions((Array<NetEnc *> &&)sock.encryptions), servers((Array<NetServerCh *> &&)sock.servers),
|
|
clients((Array<NetClientCh *> &&)sock.clients)
|
|
{
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
servers[i]->owner = this;
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
clients[i]->owner = this;
|
|
|
|
sock.buffer = nullptr;
|
|
sock.bufferSize = 0;
|
|
sock.lastTSC = 0;
|
|
sock.delta = 0.0f;
|
|
}
|
|
|
|
EHC::EHC(const EHC &sock)
|
|
: udp(sock.udp), buffer(nullptr), bufferSize(0), lastTSC(CPU::GetTSC()), delta(0.0f),
|
|
encryptions(sock.encryptions), servers(sock.servers), clients(sock.clients)
|
|
{
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
servers[i]->owner = this;
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
clients[i]->owner = this;
|
|
|
|
Initialize();
|
|
}
|
|
|
|
EHC &EHC::operator=(EHC &&sock) noexcept
|
|
{
|
|
if (this == &sock)
|
|
return *this;
|
|
|
|
udp = (UDP &&)sock.udp;
|
|
delete[] buffer;
|
|
buffer = sock.buffer;
|
|
bufferSize = sock.bufferSize;
|
|
lastTSC = sock.lastTSC;
|
|
delta = sock.delta;
|
|
|
|
for (UInt_64 i = 0; i < encryptions.Size(); i++)
|
|
delete encryptions[i];
|
|
|
|
encryptions = (Array<NetEnc *> &&)sock.encryptions;
|
|
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
delete servers[i];
|
|
|
|
servers = (Array<NetServerCh *> &&)sock.servers;
|
|
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
servers[i]->owner = this;
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
delete clients[i];
|
|
|
|
clients = (Array<NetClientCh *> &&)sock.clients;
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
clients[i]->owner = this;
|
|
|
|
sock.buffer = nullptr;
|
|
sock.bufferSize = 0;
|
|
sock.lastTSC = 0;
|
|
sock.delta = 0.0f;
|
|
|
|
return *this;
|
|
}
|
|
|
|
EHC &EHC::operator=(const EHC &sock)
|
|
{
|
|
if (this == &sock)
|
|
return *this;
|
|
|
|
udp = sock.udp;
|
|
delete[] buffer;
|
|
buffer = nullptr;
|
|
bufferSize = 0;
|
|
lastTSC = 0;
|
|
delta = 0.0f;
|
|
|
|
for (UInt_64 i = 0; i < encryptions.Size(); i++)
|
|
delete encryptions[i];
|
|
|
|
encryptions = sock.encryptions;
|
|
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
delete servers[i];
|
|
|
|
servers = sock.servers;
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
servers[i]->owner = this;
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
delete clients[i];
|
|
|
|
clients = sock.clients;
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
clients[i]->owner = this;
|
|
|
|
Initialize();
|
|
|
|
return *this;
|
|
}
|
|
|
|
void EHC::Initialize()
|
|
{
|
|
if (!udp.IsValid())
|
|
return;
|
|
|
|
udp.SetBlocking(false);
|
|
|
|
if (udp.GetLocalEndpoint().version == IP::V4)
|
|
{
|
|
buffer = new Byte[EHS_IPV4_UDP_PAYLOAD];
|
|
bufferSize = EHS_IPV4_UDP_PAYLOAD;
|
|
}
|
|
else if (udp.GetLocalEndpoint().version == IP::V6)
|
|
{
|
|
buffer = new Byte[EHS_IPV6_UDP_PAYLOAD];
|
|
bufferSize = EHS_IPV6_UDP_PAYLOAD;
|
|
}
|
|
}
|
|
|
|
void EHC::Release()
|
|
{
|
|
if (!udp.IsValid())
|
|
return;
|
|
|
|
delete[] buffer;
|
|
buffer = nullptr;
|
|
bufferSize = 0;
|
|
|
|
for (UInt_64 i = 0; i < encryptions.Size(); i++)
|
|
delete encryptions[i];
|
|
encryptions.Clear();
|
|
|
|
for (UInt_64 i = 0; i < servers.Size(); i++)
|
|
delete servers[i];
|
|
servers.Clear();
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); i++)
|
|
delete clients[i];
|
|
clients.Clear();
|
|
|
|
udp.Release();
|
|
}
|
|
|
|
void EHC::Bind(const Endpoint &endpoint)
|
|
{
|
|
udp.Bind(endpoint);
|
|
}
|
|
|
|
void EHC::Poll()
|
|
{
|
|
if (!udp.IsValid())
|
|
return;
|
|
|
|
UInt_64 newTSC = CPU::GetTSC();
|
|
delta = (float)(newTSC - lastTSC) / (float)CPU::GetTSC_Freq();
|
|
lastTSC = newTSC;
|
|
|
|
Endpoint remoteEndpoint;
|
|
UInt_16 received;
|
|
|
|
while ((received = udp.Receive(&remoteEndpoint, buffer, bufferSize)))
|
|
{
|
|
Serializer<UInt_64> payload(Endianness::LE, buffer, received);
|
|
|
|
Version remoteVer = payload.ReadVersion();
|
|
if (remoteVer != version)
|
|
continue;
|
|
|
|
UInt_64 encId = payload.Read<UInt_64>();
|
|
if (encId)
|
|
{
|
|
Version remoteEncVersion = payload.ReadVersion();
|
|
|
|
NetEnc* enc = GetEncryption(encId);
|
|
if (!enc || enc->GetVersion() != remoteEncVersion)
|
|
continue;
|
|
|
|
enc->Decrypt(&payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
|
|
}
|
|
|
|
payload.SetOffset(0);
|
|
|
|
Header header = ReadHeader(payload);
|
|
|
|
if (!header.channelId)
|
|
continue;
|
|
|
|
if (header.channelType == NetChannelType::SERVER)
|
|
{
|
|
NetServerCh *server = GetServer(header.channelId);
|
|
if (!server)
|
|
continue;
|
|
|
|
server->Process(delta, remoteEndpoint, header, payload);
|
|
}
|
|
else if (header.channelType == NetChannelType::CLIENT)
|
|
{
|
|
NetClientCh *client = GetClient(header.channelId);
|
|
if (!client)
|
|
continue;
|
|
|
|
client->Process(delta, remoteEndpoint, header, payload);
|
|
}
|
|
}
|
|
|
|
for (UInt_64 i = 0; i < servers.Size(); ++i)
|
|
servers[i]->Poll(delta);
|
|
|
|
for (UInt_64 i = 0; i < clients.Size(); ++i)
|
|
clients[i]->Poll(delta);
|
|
}
|
|
|
|
bool EHC::IsInitialized() const
|
|
{
|
|
return udp.IsValid();
|
|
}
|
|
|
|
Endpoint EHC::GetLocalEndpoint() const
|
|
{
|
|
return udp.GetLocalEndpoint();
|
|
}
|
|
|
|
bool EHC::IsBound() const
|
|
{
|
|
return udp.IsBound();
|
|
}
|
|
|
|
Version EHC::GetVersion()
|
|
{
|
|
return version;
|
|
}
|
|
|
|
bool EHC::AddEncryption(NetEnc* enc)
|
|
{
|
|
if (HasEncryption(enc->GetId()))
|
|
return false;
|
|
|
|
encryptions.Push(enc);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EHC::HasServer(const UInt_64 serverId) const
|
|
{
|
|
for (UInt_64 i = 0; i < servers.Size(); ++i)
|
|
if (servers[i]->GetId() == serverId)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool EHC::HasServer(const Str_8 &serverName) const
|
|
{
|
|
return HasServer(serverName.Hash_64());
|
|
}
|
|
|
|
bool EHC::AddServer(NetServerCh *server)
|
|
{
|
|
if (HasServer(server->GetId()))
|
|
return false;
|
|
|
|
server->owner = this;
|
|
|
|
servers.Push(server);
|
|
|
|
return true;
|
|
}
|
|
|
|
NetServerCh *EHC::GetServer(const UInt_64 serverId) const
|
|
{
|
|
for (UInt_64 i = 0; i < servers.Size(); ++i)
|
|
if (servers[i]->GetId() == serverId)
|
|
return servers[i];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
NetServerCh *EHC::GetServer(const Str_8 &serverName) const
|
|
{
|
|
return GetServer(serverName.Hash_64());
|
|
}
|
|
|
|
bool EHC::HasClient(const UInt_64 clientId) const
|
|
{
|
|
for (UInt_64 i = 0; i < clients.Size(); ++i)
|
|
if (clients[i]->GetId() == clientId)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool EHC::HasClient(const Str_8 &clientName) const
|
|
{
|
|
return HasClient(clientName.Hash_64());
|
|
}
|
|
|
|
bool EHC::AddClient(NetClientCh *client)
|
|
{
|
|
if (HasServer(client->GetId()))
|
|
return false;
|
|
|
|
client->owner = this;
|
|
|
|
clients.Push(client);
|
|
|
|
return true;
|
|
}
|
|
|
|
NetClientCh *EHC::GetClient(const UInt_64 clientId) const
|
|
{
|
|
for (UInt_64 i = 0; i < clients.Size(); ++i)
|
|
if (clients[i]->GetId() == clientId)
|
|
return clients[i];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
NetClientCh *EHC::GetClient(const Str_8 &clientName) const
|
|
{
|
|
return GetClient(clientName.Hash_64());
|
|
}
|
|
|
|
bool EHC::HasEncryption(UInt_64 encId) const
|
|
{
|
|
for (UInt_64 i = 0; i < encryptions.Size(); ++i)
|
|
if (encryptions[i]->GetId() == encId)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool EHC::HasEncryption(const Str_8& encName) const
|
|
{
|
|
return HasEncryption(encName.Hash_64());
|
|
}
|
|
|
|
NetEnc* EHC::GetEncryption(UInt_64 encId) const
|
|
{
|
|
for (UInt_64 i = 0; i < encryptions.Size(); ++i)
|
|
if (encryptions[i]->GetId() == encId)
|
|
return encryptions[i];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
NetEnc* EHC::GetEncryption(const Str_8& encName) const
|
|
{
|
|
return GetEncryption(encName.Hash_64());
|
|
}
|
|
}
|