forked from openairlinetycoon/ATDMasterServer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NATServer.cpp
136 lines (109 loc) · 3.67 KB
/
NATServer.cpp
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "NatPunchthroughClient.h"
#include "stdafx.h"
#include "NATServer.h"
#include <thread>
#include "RakPeerInterface.h"
#include "NatPunchthroughServer.h"
#include "UDPProxyCoordinator.h"
#include "UDPProxyServer.h"
using namespace RakNet;
class UDPProxyHandler : public RakNet::UDPProxyServerResultHandler {
public:
void OnLoginSuccess(RakNet::RakString usedPassword, RakNet::UDPProxyServer* proxyServerPlugin) override {
V_LOG("OnLoginSuccess");
}
void OnAlreadyLoggedIn(RakNet::RakString usedPassword, RakNet::UDPProxyServer* proxyServerPlugin) override {
V_LOG("OnAlreadyLoggedIn");
}
void OnNoPasswordSet(RakNet::RakString usedPassword, RakNet::UDPProxyServer* proxyServerPlugin) override {
V_LOG("OnNoPasswordSet");
}
void OnWrongPassword(RakNet::RakString usedPassword, RakNet::UDPProxyServer* proxyServerPlugin) override {
V_LOG("OnWrongPassword");
}
};
class ExNatPunchthroughServer : public NatPunchthroughServer {
public:
[[nodiscard]] unsigned int GetConnectedUserCount() const {
return this->users.Size();
}
};
NATServer::NATServer(RakNet::RakPeerInterface* rakPeer) : rakPeer(rakPeer), nat(new ExNatPunchthroughServer()), udpCoordinator(new UDPProxyCoordinator()), udpServer(new UDPProxyServer) {}
NATServer::~NATServer() {
if(rakPeer->IsActive()) {
rakPeer->Shutdown(100);
}
rakPeer->DetachPlugin(udpCoordinator);
rakPeer->DetachPlugin(nat);
NatPunchthroughServer::DestroyInstance(nat);
UDPProxyCoordinator::DestroyInstance(udpCoordinator);
RakPeerInterface::DestroyInstance(rakPeer);
}
void NATServer::StartServer() {
V_LOG("- Starting NAT & UDP Server...\n");
rakPeer->AttachPlugin(nat);
NatPunchthroughServerDebugInterface_Printf* debug = new NatPunchthroughServerDebugInterface_Printf();
nat->SetDebugInterface(debug);
udpCoordinator->SetRemoteLoginPassword(COORDINATOR_PASSWORD);
rakPeer->AttachPlugin(udpCoordinator);
SocketDescriptor sd(SocketDescriptor(UDP_SERVER_PORT, nullptr));
rakPeerUDP = RakPeerInterface::GetInstance();
udpServer->SetResultHandler(new UDPProxyHandler());
rakPeerUDP->AttachPlugin(udpServer);
StartupResult hres = rakPeerUDP->Startup(8096, &sd, 1);
}
unsigned int NATServer::GetConnectedUser() const {
return this->nat->GetConnectedUserCount();
}
int CheckConnectionPacket(Packet* p) {
switch(p->data[0]) {
case ID_CONNECTION_REQUEST_ACCEPTED:
{ // Send our ID to server so that others can connect to us
return 1;
}
case ID_CONNECTION_ATTEMPT_FAILED:
case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
case ID_OUR_SYSTEM_REQUIRES_SECURITY:
case ID_PUBLIC_KEY_MISMATCH:
case ID_INVALID_PASSWORD:
case ID_CONNECTION_BANNED:
case ID_INCOMPATIBLE_PROTOCOL_VERSION:
case ID_NO_FREE_INCOMING_CONNECTIONS:
case ID_IP_RECENTLY_CONNECTED:
V_LOG("Connect(..) failed! Reason: %d", p->data[0]);
return 0;
case ID_ALREADY_CONNECTED:
return 0;
default:
return 2;
}
}
bool AwaitConnection(RakPeerInterface* peerInterface) {
while(true) {
Packet* p = peerInterface->Receive();
if(p == nullptr)
continue;
const int result = CheckConnectionPacket(p);
if(result == 2) {
peerInterface->PushBackPacket(p, false);
} else {
peerInterface->DeallocatePacket(p);
return result == 1;
}
}
}
void NATServer::ProcessMessages() {
if(!this->hasUDPLoggedIn) {
SystemAddress coordinator_address = rakPeer->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS);
rakPeerUDP->Connect(coordinator_address.ToString(false), coordinator_address.GetPort(), nullptr, 0);
if(!AwaitConnection(rakPeerUDP)) {
throw;
}
udpServer->LoginToCoordinator(COORDINATOR_PASSWORD, coordinator_address);
this->hasUDPLoggedIn = true;
}
Packet* packet = rakPeerUDP->Receive();
if(packet) {
rakPeerUDP->DeallocatePacket(packet);
}
}