1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// This file is public domain, in case it's useful to anyone. -comex
#pragma once
#include <functional>
#include <list>
#include <memory>
#include <random>
#include <enet/enet.h>
#include "Common/Common.h"
#include "Common/Thread.h"
#include "Common/TraversalProto.h"
class TraversalClientClient
{
public:
virtual ~TraversalClientClient(){};
virtual void OnTraversalStateChanged()=0;
virtual void OnConnectReady(ENetAddress addr)=0;
virtual void OnConnectFailed(u8 reason)=0;
};
class TraversalClient
{
public:
enum State
{
Connecting,
Connected,
Failure
};
enum FailureReason
{
BadHost = 0x300,
VersionTooOld,
ServerForgotAboutUs,
SocketSendError,
ResendTimeout,
};
TraversalClient(ENetHost* netHost, const std::string& server, const u16 port);
~TraversalClient();
void Reset();
void ConnectToClient(const std::string& host);
void ReconnectToServer();
void Update();
// called from NetHost
bool TestPacket(u8* data, size_t size, ENetAddress* from);
void HandleResends();
ENetHost* m_NetHost;
TraversalClientClient* m_Client;
TraversalHostId m_HostId;
State m_State;
int m_FailureReason;
private:
struct OutgoingTraversalPacketInfo
{
TraversalPacket packet;
int tries;
enet_uint32 sendTime;
};
void HandleServerPacket(TraversalPacket* packet);
void ResendPacket(OutgoingTraversalPacketInfo* info);
TraversalRequestId SendTraversalPacket(const TraversalPacket& packet);
void OnFailure(FailureReason reason);
void HandlePing();
static int ENET_CALLBACK InterceptCallback(ENetHost* host, ENetEvent* event);
TraversalRequestId m_ConnectRequestId;
bool m_PendingConnect;
std::list<OutgoingTraversalPacketInfo> m_OutgoingTraversalPackets;
ENetAddress m_ServerAddress;
std::string m_Server;
u16 m_port;
enet_uint32 m_PingTime;
};
extern std::unique_ptr<TraversalClient> g_TraversalClient;
// the NetHost connected to the TraversalClient.
extern std::unique_ptr<ENetHost> g_MainNetHost;
// Create g_TraversalClient and g_MainNetHost if necessary.
bool EnsureTraversalClient(const std::string& server, u16 server_port, u16 listen_port = 0);
void ReleaseTraversalClient();
|