Proxy Rewrite, fixed some crashes

This commit is contained in:
Anonymous275 2020-05-04 01:16:50 +03:00
parent 1b013fb9eb
commit 93299f0fa4
4 changed files with 78 additions and 106 deletions

View File

@ -13,7 +13,7 @@ extern bool TCPTerminate;
extern bool MPDEV;
void Print(const std::string&MSG);
std::queue<std::string> VNTCPQueue;
void RUDPSEND(const std::string&Data);
void RUDPSEND(const std::string&Data,bool Rel);
#define DEFAULT_PORT "4446"
void Responder(const SOCKET *CS){
@ -135,7 +135,7 @@ void VehicleNetworkStart(){
std::cout << "Fail!" << std::endl;
}
}
RUDPSEND(buff);
RUDPSEND(buff,false);
//std::cout << "(Game->Launcher VN) Data : " << buff.length() << std::endl;
} else if (iResult == 0) {
if(MPDEV)std::cout << "(VN) Connection closing...\n";

View File

@ -3172,13 +3172,14 @@ int enet_host_check_events(ENetHost *host, ENetEvent *event) {
* @remarks enet_host_service should be called fairly regularly for adequate performance
* @ingroup host
*/
int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) {
enet_uint32 waitCondition;
if (event != NULL) {
if (event != nullptr) {
event->type = ENET_EVENT_TYPE_NONE;
event->peer = NULL;
event->packet = NULL;
event->peer = nullptr;
event->packet = nullptr;
switch (enet_protocol_dispatch_incoming_commands(host, event)) {
case 1:
@ -3197,6 +3198,7 @@ int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) {
}
host->serviceTime = enet_time_get();
auto Start = std::chrono::high_resolution_clock::now();
timeout += host->serviceTime;
do {
@ -3249,7 +3251,7 @@ int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) {
break;
}
if (event != NULL) {
if (event != nullptr) {
switch (enet_protocol_dispatch_incoming_commands(host, event)) {
case 1:
return 1;
@ -3266,19 +3268,13 @@ int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) {
}
}
if (ENET_TIME_GREATER_EQUAL(host->serviceTime, timeout)) {
return 0;
}
do {
auto end = std::chrono::high_resolution_clock::now();
int D = std::chrono::duration_cast<std::chrono::microseconds>(Start - end).count();
if (D > timeout)return 0;
host->serviceTime = enet_time_get();
if (ENET_TIME_GREATER_EQUAL(host->serviceTime, timeout)) {
return 0;
}
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
if (enet_socket_wait(host->socket, &waitCondition, ENET_TIME_DIFFERENCE(timeout, host->serviceTime)) != 0) {
if (enet_socket_wait(host->socket, &waitCondition, timeout-D > 0)) {
return -1;
}
} while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);

View File

@ -85,7 +85,7 @@ int main(int argc, char* argv[]){
const unsigned long long NPos = std::string::npos;
struct stat info{};
std::string ver = "0.901", Path = CheckDir(argv[0],ver),HTTP_Result;
std::string ver = "0.91", Path = CheckDir(argv[0],ver),HTTP_Result;
CheckForUpdates(ver);
if(argc > 1){
std::string Port = argv[1];

154
proxy.cpp
View File

@ -13,55 +13,76 @@
#include <queue>
int DEFAULT_PORT = 4445;
typedef struct {
ENetHost *host;
ENetPeer *peer;
} Client;
std::vector<std::string> Split(const std::string& String,const std::string& delimiter);
std::chrono::time_point<std::chrono::steady_clock> PingStart,PingEnd;
extern std::vector<std::string> GlobalInfo;
std::condition_variable RUDPLOCK,TCPLOCK;
std::queue<std::string> RUDPToSend;
std::queue<std::string> RUDPData; /////QUEUE WAS 196 SLOW?! NEED TO FIX
bool TCPTerminate = false;
bool Terminate = false;
bool CServer = true;
ENetPeer*ServerPeer;
SOCKET*ClientSocket;
int ping = 0;
extern bool MPDEV;
[[noreturn]] void CoreNetworkThread();
void TCPSEND(const std::string&Data){
RUDPData.push(Data);
TCPLOCK.notify_all();
if(!TCPTerminate) {
int iSendResult = send(*ClientSocket, (Data + "\n").c_str(), int(Data.length()) + 1, 0);
if (iSendResult == SOCKET_ERROR) {
if (MPDEV)std::cout << "(Proxy) send failed with error: " << WSAGetLastError() << std::endl;
TCPTerminate = true;
} else {
if (MPDEV && iSendResult > 1000) {
std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << Data.substr(0, 10)
<< Data.substr(Data.length() - 10) << std::endl;
}
//std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << RUDPData.front()<< std::endl;
}
}
}
void RUDPSEND(const std::string&Data){
RUDPToSend.push(Data);
RUDPLOCK.notify_all();
void RUDPSEND(const std::string&Data,bool Rel){
if(!Terminate && ServerPeer != nullptr){
char C = 0;
if(Data.length() > 3)C = Data.at(0);
if (C == 'O' || C == 'T')Rel = true;
enet_peer_send(ServerPeer, 0, enet_packet_create(Data.c_str(), Data.length()+1, Rel?1:8));
if (MPDEV && Data.length() > 1000) {
std::cout << "(Launcher->Server) Bytes sent: " << Data.length()
<< " : "
<< Data.substr(0, 10)
<< Data.substr(Data.length() - 10) << std::endl;
}
}
}
void NameRespond(){
std::string Packet = "NR" + GlobalInfo.at(0)+":"+GlobalInfo.at(2);
RUDPSEND(Packet,true);
}
void AutoPing(ENetPeer*peer){
while(!Terminate && peer != nullptr){
enet_peer_send(peer, 0, enet_packet_create("p", 2, ENET_PACKET_FLAG_RELIABLE));
RUDPSEND("p",true);
PingStart = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(std::chrono::seconds (1));
}
}
void NameRespond(ENetPeer*peer){
std::string Packet = "NR" + GlobalInfo.at(0)+":"+GlobalInfo.at(2);
enet_peer_send(peer, 0, enet_packet_create(Packet.c_str(), Packet.length()+1, ENET_PACKET_FLAG_RELIABLE));
}
void RUDPParser(const std::string& Data,ENetPeer*peer){
void RUDPParser(const std::string& Data){
char Code = Data.at(0),SubCode = 0;
if(Data.length() > 1)SubCode = Data.at(1);
switch (Code) {
case 'p':
PingEnd = std::chrono::high_resolution_clock::now();
ping = std::chrono::duration_cast<std::chrono::milliseconds>(PingEnd-PingStart).count();
ping = int(std::chrono::duration_cast<std::chrono::microseconds>(PingEnd-PingStart).count())/1000;
return;
case 'N':
if(SubCode == 'R')NameRespond(peer);
if(SubCode == 'R')NameRespond();
return;
}
///std::cout << "Received: " << Data << std::endl;
@ -76,7 +97,7 @@ void HandleEvent(ENetEvent event,Client client){
event.peer->data = (void*)"Connected Server";
break;
case ENET_EVENT_TYPE_RECEIVE:
RUDPParser((char*)event.packet->data,event.peer);
RUDPParser((char*)event.packet->data);
enet_packet_destroy(event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
@ -97,6 +118,7 @@ void HandleEvent(ENetEvent event,Client client){
}
}
void RUDPClientThread(const std::string& IP, int Port){
std::condition_variable lock;
if (enet_initialize() != 0) {
std::cout << "An error occurred while initializing!\n";
}
@ -112,36 +134,18 @@ void RUDPClientThread(const std::string& IP, int Port){
client.peer = enet_host_connect(client.host, &address, 2, 0);
if (client.peer == nullptr) {
if(MPDEV)std::cout << "could not connect\n";
TCPSEND("TTimeout");
TCPTerminate = true;
Terminate = true;
}
ServerPeer = client.peer;
std::thread Ping(AutoPing,client.peer);
Ping.detach();
ENetEvent event;
do {
enet_host_service(client.host, &event, 0);
while (!Terminate) {
enet_host_service(client.host, &event, 1);
HandleEvent(event,client);
while (!RUDPToSend.empty()){
if(RUDPToSend.front().length() > 3) {
int Rel = 8;
char C = RUDPToSend.front().at(0);
if (C == 'O' || C == 'T')Rel = 1;
ENetPacket *packet = enet_packet_create(RUDPToSend.front().c_str(),
RUDPToSend.front().length() + 1,
Rel);
enet_peer_send(client.peer, 0, packet);
if (RUDPToSend.front().length() > 1000) {
if(MPDEV){std::cout << "(Launcher->Server) Bytes sent: " << RUDPToSend.front().length() << " : "
<< RUDPToSend.front().substr(0, 10)
<< RUDPToSend.front().substr(RUDPToSend.front().length() - 10) << std::endl;}
}
}
RUDPToSend.pop();
}
std::mutex Lock;
std::unique_lock<std::mutex> lk(Lock);
std::chrono::high_resolution_clock::time_point tp = std::chrono::high_resolution_clock::now() + std::chrono::nanoseconds (1);
RUDPLOCK.wait_until(lk, tp, [](){return !RUDPToSend.empty();});
} while (!Terminate);
}
enet_peer_disconnect(client.peer,0);
enet_host_service(client.host, &event, 0);
HandleEvent(event,client);
@ -149,33 +153,6 @@ void RUDPClientThread(const std::string& IP, int Port){
std::cout << "Connection Terminated!" << std::endl;
}
void TCPRespond(const SOCKET *CS){
SOCKET ClientSocket = *CS;
int iSendResult;
while(!TCPTerminate){
while (!RUDPData.empty()) {
std::string Data = RUDPData.front() + "\n";
iSendResult = send(ClientSocket, Data.c_str(), Data.length(), 0);
if (iSendResult == SOCKET_ERROR) {
if(MPDEV)std::cout << "(Proxy) send failed with error: " << WSAGetLastError() << std::endl;
TCPTerminate = true;
break;
} else {
if(iSendResult > 1000){
std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << RUDPData.front().substr(0,10)
<< RUDPData.front().substr(RUDPData.front().length()-10) << std::endl;
}
//std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << RUDPData.front()<< std::endl;
RUDPData.pop();
}
}
std::mutex Lock;
std::unique_lock<std::mutex> lk(Lock);
std::chrono::high_resolution_clock::time_point tp = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(1);
TCPLOCK.wait_until(lk, tp, [](){return !RUDPData.empty();});
}
}
std::string Compress(const std::string&Data);
std::string Decompress(const std::string&Data);
void TCPServerThread(const std::string& IP, int Port){
@ -185,7 +162,7 @@ void TCPServerThread(const std::string& IP, int Port){
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
SOCKET Socket = INVALID_SOCKET;
struct addrinfo *result = nullptr;
struct addrinfo hints{};
@ -196,7 +173,6 @@ void TCPServerThread(const std::string& IP, int Port){
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
if(MPDEV)std::cout << "(Proxy) WSAStartup failed with error: " << iResult << std::endl;
std::cin.get();
exit(-1);
}
@ -241,8 +217,8 @@ void TCPServerThread(const std::string& IP, int Port){
WSACleanup();
continue;
}
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
Socket = accept(ListenSocket, nullptr, nullptr);
if (Socket == INVALID_SOCKET) {
if(MPDEV)std::cout << "(Proxy) accept failed with error: " << WSAGetLastError() << std::endl;
closesocket(ListenSocket);
WSACleanup();
@ -255,17 +231,16 @@ void TCPServerThread(const std::string& IP, int Port){
t1.detach();
CServer = false;
}
std::thread TCPSend(TCPRespond,&ClientSocket);
TCPSend.detach();
ClientSocket = &Socket;
do {
//std::cout << "(Proxy) Waiting for Game Data..." << std::endl;
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
iResult = recv(Socket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
std::string buff;
buff.resize(iResult*2);
memcpy(&buff[0],recvbuf,iResult);
buff.resize(iResult);
if(MPDEV && buff.length() > 1000) {
/*if(MPDEV && buff.length() > 1000) {
std::string cmp = Compress(buff), dcm = Decompress(cmp);
std::cout << "Compressed Size : " << cmp.length() << std::endl;
std::cout << "Decompressed Size : " << dcm.length() << std::endl;
@ -274,31 +249,31 @@ void TCPServerThread(const std::string& IP, int Port){
} else {
std::cout << "Fail!" << std::endl;
}
}
RUDPSEND(buff);
}*/
RUDPSEND(buff,false);
//std::cout << "(Game->Launcher) Data : " << buff.length() << std::endl;
} else if (iResult == 0) {
if(MPDEV)std::cout << "(Proxy) Connection closing...\n";
closesocket(ClientSocket);
closesocket(Socket);
WSACleanup();
continue;
} else {
if(MPDEV)std::cout << "(Proxy) recv failed with error: " << WSAGetLastError() << std::endl;
closesocket(ClientSocket);
closesocket(Socket);
WSACleanup();
continue;
}
} while (iResult > 0);
iResult = shutdown(ClientSocket, SD_SEND);
iResult = shutdown(Socket, SD_SEND);
if (iResult == SOCKET_ERROR) {
if(MPDEV)std::cout << "(Proxy) shutdown failed with error: " << WSAGetLastError() << std::endl;
closesocket(ClientSocket);
closesocket(Socket);
WSACleanup();
continue;
}
closesocket(ClientSocket);
closesocket(Socket);
WSACleanup();
}while (!TCPTerminate);
}
@ -310,12 +285,13 @@ void ProxyStart(){
if(MPDEV)std::cout << "Core Network Started!\n";
t1.join();
}
void Reset(){
Terminate = false;
void Reset() {
ClientSocket = nullptr;
ServerPeer = nullptr;
TCPTerminate = false;
while(!RUDPToSend.empty()) RUDPToSend.pop();
while(!RUDPData.empty()) RUDPData.pop();
Terminate = false;
}
void ProxyThread(const std::string& IP, int Port){
Reset();
std::thread t1(TCPServerThread,IP,Port);