diff --git a/CoreNetwork.cpp b/CoreNetwork.cpp index 2f01b77..29dd156 100644 --- a/CoreNetwork.cpp +++ b/CoreNetwork.cpp @@ -17,6 +17,8 @@ void SyncResources(const std::string& IP, int port); extern std::string UlStatus; extern std::string MStatus; extern int ping; +extern bool Terminate; +extern bool TCPTerminate; void StartSync(const std::string &Data){ std::thread t1(SyncResources,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1))); t1.detach(); @@ -41,14 +43,22 @@ std::string Parse(const std::string& Data){ if(!SubCode)return UlStatus+ "\n" + "Up" + std::to_string(ping); case 'M': return MStatus; + case 'Q': + if(SubCode == 'S'){ + Terminate = true; + TCPTerminate = true; ////Revisit later when TCP is stable + } + if(SubCode == 'G')exit(2); + return ""; default: return ""; } } -void CoreNetworkThread(){ +[[noreturn]] void CoreNetworkThread(){ do{ + std::cout << "Core Network on start!" << std::endl; WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; @@ -76,14 +86,14 @@ void CoreNetworkThread(){ // Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { - std::cout << "getaddrinfo failed with error: " << iResult << std::endl; + std::cout << "(Core) getaddrinfo failed with error: " << iResult << std::endl; WSACleanup(); } // Create a socket for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { - std::cout << "socket failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) socket failed with error: " << WSAGetLastError() << std::endl; freeaddrinfo(result); WSACleanup(); } @@ -91,7 +101,7 @@ void CoreNetworkThread(){ // Setup the TCP listening socket iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { - std::cout << "bind failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) bind failed with error: " << WSAGetLastError() << std::endl; freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); @@ -101,13 +111,13 @@ void CoreNetworkThread(){ iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { - std::cout << "listen failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) listen failed with error: " << WSAGetLastError() << std::endl; closesocket(ListenSocket); WSACleanup(); } ClientSocket = accept(ListenSocket, nullptr, nullptr); if (ClientSocket == INVALID_SOCKET) { - std::cout << "accept failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) accept failed with error: " << WSAGetLastError() << std::endl; closesocket(ListenSocket); WSACleanup(); } @@ -124,14 +134,14 @@ void CoreNetworkThread(){ } else if (iResult == 0) - std::cout << "Connection closing...\n"; + std::cout << "(Core) Connection closing...\n"; else { - std::cout << "(Core Network) recv failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) recv failed with error: " << WSAGetLastError() << std::endl; closesocket(ClientSocket); WSACleanup(); } if(!Response.empty()){ - iSendResult = send( ClientSocket, Response.c_str(), int(Response.length()), 0); + iSendResult = send( ClientSocket, Response.c_str(), Response.length(), 0); if (iSendResult == SOCKET_ERROR) { std::cout << "send failed with error: " << WSAGetLastError() << std::endl; closesocket(ClientSocket); @@ -144,9 +154,10 @@ void CoreNetworkThread(){ iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { - std::cout << "shutdown failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Core) shutdown failed with error: " << WSAGetLastError() << std::endl; closesocket(ClientSocket); WSACleanup(); + Sleep(500); } closesocket(ClientSocket); WSACleanup(); diff --git a/main.cpp b/main.cpp index 73b97c5..0fddd57 100644 --- a/main.cpp +++ b/main.cpp @@ -39,22 +39,18 @@ void Exit(const std::string& Msg){ std::string CheckDir(char*dir, const std::string& ver){ system(("title BeamMP Launcher v" + ver).c_str()); char*temp;size_t len; + struct stat info{}; _dupenv_s(&temp, &len,"APPDATA"); std::string DN = "BeamMP-Launcher.exe",CDir = dir, AD = temp,FN = CDir.substr(CDir.find_last_of('\\')+1,CDir.size()); AD += "\\BeamMP-Launcher"; - - if(FN != DN){ - SystemExec("rename \""+ FN +"\" " + DN + ">nul"); - } - + if(stat(DN.c_str(),&info)==0)remove(DN.c_str()); + if(FN != DN)SystemExec("rename \""+ FN +"\" " + DN + ">nul"); if(CDir.substr(0,CDir.find_last_of('\\')) != AD){ _mkdir(AD.c_str()); SystemExec(R"(move "BeamMP-Launcher.exe" ")" + AD + "\">nul"); } - SetCurrentDirectoryA(AD.c_str()); SystemExec("rename *.exe " + DN + ">nul"); - SystemExec(R"(powershell "$s=(New-Object -COM WScript.Shell).CreateShortcut('%userprofile%\Desktop\BeamMP-Launcher.lnk');$s.TargetPath=')"+AD+"\\"+DN+"';$s.Save()\""); CreateDirectoryA("BeamNG",nullptr); CreateDirectoryA("BeamNG\\mods",nullptr); @@ -80,7 +76,7 @@ std::string CheckVer(const std::string &path){ void SyncResources(const std::string&IP,int Port); int main(int argc, char* argv[]) { - std::string ver = "0.40", Path = CheckDir(argv[0],ver),HTTP_Result; + std::string ver = "0.51", Path = CheckDir(argv[0],ver),HTTP_Result; CheckForUpdates(ver); //Update Check //Security diff --git a/proxy.cpp b/proxy.cpp index 7e168be..98256bc 100644 --- a/proxy.cpp +++ b/proxy.cpp @@ -21,14 +21,17 @@ typedef struct { } Client; std::chrono::time_point PingStart,PingEnd; extern std::vector GlobalInfo; -std::queue RUDPData; std::queue RUDPToSend; +std::queue RUDPData; +bool TCPTerminate = false; bool Terminate = false; +bool CServer = true; int ping = 0; -void CoreNetworkThread(); + +[[noreturn]] void CoreNetworkThread(); void AutoPing(ENetPeer*peer){ - while(!Terminate){ + while(!Terminate && peer != nullptr){ enet_peer_send(peer, 0, enet_packet_create("p", 2, ENET_PACKET_FLAG_RELIABLE)); PingStart = std::chrono::high_resolution_clock::now(); Sleep(1000); @@ -51,18 +54,15 @@ void RUDPParser(const std::string& Data,ENetPeer*peer){ if(SubCode == 'R')NameRespond(peer); return; } - std::cout << "Received: " << Data << std::endl; + ///std::cout << "Received: " << Data << std::endl; RUDPData.push(Data); } - -#pragma clang diagnostic pop -#pragma clang diagnostic pop void HandleEvent(ENetEvent event,Client client){ switch (event.type){ case ENET_EVENT_TYPE_CONNECT: - printf("Client Connected port : %u.\n",event.peer->address.port); - //Name Of the Server + std::cout << "(Launcher->Server) Client Connected!" << std::endl; + //printf("Client Connected port : %u.\n",event.peer->address.port); event.peer->data = (void *)"Connected Server"; break; case ENET_EVENT_TYPE_RECEIVE: @@ -71,12 +71,13 @@ void HandleEvent(ENetEvent event,Client client){ break; case ENET_EVENT_TYPE_DISCONNECT: printf ("%s disconnected.\n", (char *)event.peer->data); - // Reset the peer's client information. event.peer->data = nullptr; break; case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: printf ("%s timeout.\n", (char *)event.peer->data); + CServer = true; + Terminate = true; event.peer->data = nullptr; break; @@ -98,7 +99,7 @@ void RUDPClientThread(const std::string& IP, int Port){ address.port = Port; - std::cout << "starting client...\n"; + std::cout << "(Launcher->Server) Connecting...\n"; enet_address_set_host(&address, IP.c_str()); client.host = enet_host_create(nullptr, 1, 2, 0, 0); @@ -108,16 +109,16 @@ void RUDPClientThread(const std::string& IP, int Port){ } std::thread Ping(AutoPing,client.peer); Ping.detach(); + ENetEvent event; do { - ENetEvent event; enet_host_service(client.host, &event, 0); - HandleEvent(event,client); //Handles the Events + HandleEvent(event,client); while (!RUDPToSend.empty()){ ENetPacket* packet = enet_packet_create(RUDPToSend.front().c_str(), RUDPToSend.front().length()+1, - ENET_PACKET_FLAG_RELIABLE); + ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); enet_peer_send(client.peer, 0, packet); - std::cout << "sending : " << RUDPToSend.front() << std::endl; + std::cout << "(Launcher->Server) sending : " << RUDPToSend.front() << std::endl; RUDPToSend.pop(); } while(RUDPToSend.empty() && Interval < 1000){ @@ -125,13 +126,36 @@ void RUDPClientThread(const std::string& IP, int Port){ Interval = std::chrono::duration_cast(done-start).count(); } } while (!Terminate); + enet_peer_disconnect(client.peer,0); + enet_host_service(client.host, &event, 0); + HandleEvent(event,client); + CServer = true; + std::cout << "(Launcher->Server) Terminated!" << std::endl; +} + +void TCPRespond(SOCKET *CS){ + int iSendResult; + SOCKET ClientSocket = *CS; + while(ClientSocket != INVALID_SOCKET){ + while (!RUDPData.empty()) { + RUDPData.front() += "\n"; + iSendResult = send(ClientSocket, RUDPData.front().c_str(), RUDPData.front().length(), 0); + if (iSendResult == SOCKET_ERROR) { + std::cout << "(Proxy) send failed with error: " << WSAGetLastError() << std::endl; + break; + } else { + RUDPData.pop(); + std::cout << "(Proxy->Game) Bytes sent: " << iSendResult << std::endl; + } + } + } } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-noreturn" void TCPServerThread(const std::string& IP, int Port){ + std::cout << "Proxy Started! " << IP << ":" << Port << std::endl; + do { Terminate = false; - std::cout << "Proxy Started!" << std::endl; + std::cout << "Proxy on Start" << std::endl; WSADATA wsaData; int iResult; SOCKET ListenSocket = INVALID_SOCKET; @@ -145,9 +169,11 @@ void TCPServerThread(const std::string& IP, int Port){ int recvbuflen = DEFAULT_BUFLEN; // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { - std::cout <<"WSAStartup failed with error: " << iResult << std::endl; + std::cout << "(Proxy) WSAStartup failed with error: " << iResult << std::endl; + std::cin.get(); + exit(-1); } ZeroMemory(&hints, sizeof(hints)); @@ -158,91 +184,88 @@ void TCPServerThread(const std::string& IP, int Port){ // Resolve the server address and port iResult = getaddrinfo(nullptr, DEFAULT_PORT, &hints, &result); - if ( iResult != 0 ) { - std::cout << "getaddrinfo failed with error: " << iResult << std::endl; + if (iResult != 0) { + std::cout << "(Proxy) getaddrinfo failed with error: " << iResult << std::endl; WSACleanup(); + break; } // Create a socket for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { - std::cout << "socket failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Proxy) socket failed with error: " << WSAGetLastError() << std::endl; freeaddrinfo(result); WSACleanup(); + break; } // Setup the TCP listening socket - iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); + iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen); if (iResult == SOCKET_ERROR) { - std::cout << "bind failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Proxy) bind failed with error: " << WSAGetLastError() << std::endl; freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); + break; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { - std::cout << "listen failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Proxy) listen failed with error: " << WSAGetLastError() << std::endl; closesocket(ListenSocket); WSACleanup(); + continue; } ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { - std::cout << "accept failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Proxy) accept failed with error: " << WSAGetLastError() << std::endl; closesocket(ListenSocket); WSACleanup(); + continue; } closesocket(ListenSocket); - - std::thread t1(RUDPClientThread,IP,Port); - t1.detach(); - + std::cout << "(Proxy) Game Connected!" << std::endl; + if(CServer){ + std::thread t1(RUDPClientThread, IP, Port); + t1.detach(); + CServer = false; + } + std::thread TCPSend(TCPRespond,&ClientSocket); + TCPSend.detach(); do { - while(!RUDPData.empty()){ - iSendResult = send( ClientSocket, RUDPData.front().c_str(), int(RUDPData.front().length())+1, 0); - if (iSendResult == SOCKET_ERROR) { - std::cout << "send failed with error: " << WSAGetLastError() << std::endl; - closesocket(ClientSocket); - WSACleanup(); - }else{ - RUDPData.pop(); - std::cout << "Bytes sent: " << iSendResult << std::endl; - } - } - + std::cout << "(Proxy) Waiting for Game Data..." << std::endl; iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { std::string buff = recvbuf; buff.resize(iResult); RUDPToSend.push(buff); - std::cout << "size : " << buff.size() << std::endl; - std::cout << "Data : " << buff.c_str() << std::endl; - } + std::cout << "(Game->Launcher) Data : " << buff.c_str() << std::endl; + } else if (iResult == 0) { + std::cout << "(Proxy) Connection closing...\n"; + closesocket(ClientSocket); + WSACleanup(); - else if (iResult == 0) { - std::cout << "Connection closing...\n"; - - } - else { + continue; + } else { std::cout << "(Proxy) recv failed with error: " << WSAGetLastError() << std::endl; closesocket(ClientSocket); WSACleanup(); + continue; } - } while (iResult > 0); iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { - std::cout << "shutdown failed with error: " << WSAGetLastError() << std::endl; + std::cout << "(Proxy) shutdown failed with error: " << WSAGetLastError() << std::endl; closesocket(ClientSocket); WSACleanup(); + continue; } - closesocket(ClientSocket); WSACleanup(); - Terminate = true; + }while (!TCPTerminate); } @@ -254,7 +277,6 @@ void ProxyStart(){ } void ProxyThread(const std::string& IP, int Port){ - Terminate = false; std::thread t1(TCPServerThread,IP,Port); t1.detach(); } \ No newline at end of file