mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-03 00:16:50 +00:00
Proxy Rewrite, fixed some crashes
This commit is contained in:
parent
1b013fb9eb
commit
93299f0fa4
@ -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";
|
||||
|
@ -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);
|
||||
|
2
main.cpp
2
main.cpp
@ -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
154
proxy.cpp
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user