diff --git a/src/Network/Server.cpp b/src/Network/Server.cpp index 8048c4f..fd522c5 100644 --- a/src/Network/Server.cpp +++ b/src/Network/Server.cpp @@ -4,6 +4,7 @@ /// #define WIN32_LEAN_AND_MEAN + #include "Compressor.h" #include "Server.h" #include "Launcher.h" @@ -12,7 +13,7 @@ #include #include "Logger.h" -Server::Server(Launcher* Instance) : LauncherInstance(Instance) { +Server::Server(Launcher *Instance) : LauncherInstance(Instance) { WSADATA wsaData; int iRes = WSAStartup(514, &wsaData); //2.2 if (iRes != 0) { @@ -29,7 +30,7 @@ Server::~Server() { void Server::TCPClientMain() { SOCKADDR_IN ServerAddr; TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(TCPSocket == -1) { + if (TCPSocket == -1) { LOG(ERROR) << "Socket failed! Error code: " << GetSocketApiError(); return; } @@ -42,17 +43,21 @@ void Server::TCPClientMain() { ServerAddr.sin_port = htons(Port); inet_pton(AF_INET, IP.c_str(), &ServerAddr.sin_addr); status = connect(TCPSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)); - if(status != 0){ + if (status != 0) { UStatus = "Connection Failed!"; LOG(ERROR) << "Connect failed! Error code: " << GetSocketApiError(); - Close(); + Terminate.store(true); + return; + } + + char Code = 'C'; + if (send(TCPSocket, &Code, 1, 0) != 1) { + Terminate.store(true); return; } LOG(INFO) << "Connected!"; - char Code = 'C'; - send(TCPSocket, &Code, 1, 0); SyncResources(); - while(!Terminate.load()) { + while (!Terminate.load()) { ServerParser(TCPRcv()); } LauncherInstance->SendIPC("T", false); @@ -60,25 +65,26 @@ void Server::TCPClientMain() { } void Server::StartUDP() { - if(TCPConnection.joinable() && !UDPConnection.joinable()) { + if (TCPConnection.joinable() && !UDPConnection.joinable()) { LOG(INFO) << "Connecting UDP"; UDPConnection = std::thread(&Server::UDPMain, this); } } void Server::UDPSend(std::string Data) { - if(ClientID == -1 || UDPSocket == -1)return; - if(Data.length() > 400){ + if (ClientID == -1 || UDPSocket == -1)return; + if (Data.length() > 400) { std::string CMP(Zlib::Comp(Data)); Data = "ABG:" + CMP; } - std::string Packet = char(ClientID+1) + std::string(":") + Data; - int sendOk = sendto(UDPSocket, Packet.c_str(), int(Packet.size()), 0, (sockaddr*)UDPSockAddress.get(), sizeof(sockaddr_in)); + std::string Packet = char(ClientID + 1) + std::string(":") + Data; + int sendOk = sendto(UDPSocket, Packet.c_str(), int(Packet.size()), 0, (sockaddr *) UDPSockAddress.get(), + sizeof(sockaddr_in)); if (sendOk == SOCKET_ERROR)LOG(ERROR) << "UDP Socket Error Code : " << GetSocketApiError(); } void Server::UDPParser(std::string Packet) { - if(Packet.substr(0,4) == "ABG:"){ + if (Packet.substr(0, 4) == "ABG:") { Packet = Zlib::DeComp(Packet.substr(4)); } ServerParser(Packet); @@ -88,11 +94,11 @@ void Server::UDPRcv() { sockaddr_in FromServer{}; int clientLength = sizeof(FromServer); ZeroMemory(&FromServer, clientLength); - std::string Ret(10240,0); - if(UDPSocket == -1)return; - int32_t Rcv = recvfrom(UDPSocket, &Ret[0], 10240, 0, (sockaddr*)&FromServer, &clientLength); + std::string Ret(10240, 0); + if (UDPSocket == -1)return; + int32_t Rcv = recvfrom(UDPSocket, &Ret[0], 10240, 0, (sockaddr *) &FromServer, &clientLength); if (Rcv == SOCKET_ERROR)return; - UDPParser(Ret.substr(0,Rcv)); + UDPParser(Ret.substr(0, Rcv)); } void Server::UDPClient() { @@ -100,10 +106,10 @@ void Server::UDPClient() { UDPSockAddress->sin_port = htons(Port); inet_pton(AF_INET, IP.c_str(), &UDPSockAddress->sin_addr); UDPSocket = socket(AF_INET, SOCK_DGRAM, 0); - LauncherInstance->SendIPC("P"+std::to_string(ClientID), false); + LauncherInstance->SendIPC("P" + std::to_string(ClientID), false); TCPSend("H"); UDPSend("p"); - while(!Terminate)UDPRcv(); + while (!Terminate)UDPRcv(); KillSocket(UDPSocket); } @@ -114,18 +120,21 @@ void Server::UDPMain() { LOG(INFO) << "Connection terminated"; } -void Server::Connect(const std::string& Data) { +void Server::Connect(const std::string &Data) { ModList.clear(); Terminate.store(false); - IP = GetAddress(Data.substr(1,Data.find(':')-1)); - if(IP.find('.') == -1){ - if(IP == "DNS")UStatus ="Connection Failed! (DNS Lookup Failed)"; + IP = GetAddress(Data.substr(1, Data.find(':') - 1)); + std::string port = Data.substr(Data.find(':') + 1); + bool ValidPort = std::all_of(port.begin(), port.end(), ::isdigit); + if (IP.find('.') == -1 || !ValidPort) { + if (IP == "DNS") UStatus = "Connection Failed! (DNS Lookup Failed)"; + else if (!ValidPort) UStatus = "Connection Failed! (Invalid Port)"; else UStatus = "Connection Failed! (WSA failed to start)"; ModList = "-"; Terminate.store(true); return; } - Port = std::stoi(Data.substr(Data.find(':')+1)); + Port = std::stoi(port); LauncherInstance->CheckKey(); UStatus = "Loading..."; Ping = -1; @@ -134,7 +143,7 @@ void Server::Connect(const std::string& Data) { } void Server::SendLarge(std::string Data) { - if(Data.length() > 400) { + if (Data.length() > 400) { std::string CMP(Zlib::Comp(Data)); Data = "ABG:" + CMP; } @@ -151,12 +160,12 @@ std::string Server::GetSocketApiError() { err = WSAGetLastError(); FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - msgbuf, - sizeof(msgbuf), - nullptr); + nullptr, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + msgbuf, + sizeof(msgbuf), + nullptr); if (*msgbuf) { return std::to_string(WSAGetLastError()) + " - " + std::string(msgbuf); @@ -166,23 +175,23 @@ std::string Server::GetSocketApiError() { } void Server::ServerSend(std::string Data, bool Rel) { - if(Terminate || Data.empty())return; + if (Terminate || Data.empty())return; char C = 0; int DLen = int(Data.length()); - if(DLen > 3)C = Data.at(0); + if (DLen > 3)C = Data.at(0); bool Ack = C == 'O' || C == 'T'; - if(C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')Rel = true; - if(Ack || Rel) { - if(Ack || DLen > 1000)SendLarge(Data); + if (C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')Rel = true; + if (Ack || Rel) { + if (Ack || DLen > 1000)SendLarge(Data); else TCPSend(Data); - }else UDPSend(Data); + } else UDPSend(Data); } void Server::PingLoop() { - while(!Terminate){ + while (!Terminate) { ServerSend("p", false); PingStart = std::chrono::high_resolution_clock::now(); - std::this_thread::sleep_for(std::chrono::seconds (1)); + std::this_thread::sleep_for(std::chrono::seconds(1)); } } @@ -191,13 +200,13 @@ void Server::Close() { KillSocket(TCPSocket); KillSocket(UDPSocket); Ping = -1; - if(TCPConnection.joinable()) { + if (TCPConnection.joinable()) { TCPConnection.join(); } - if(UDPConnection.joinable()) { + if (UDPConnection.joinable()) { UDPConnection.join(); } - if(AutoPing.joinable()) { + if (AutoPing.joinable()) { AutoPing.join(); } } @@ -218,24 +227,24 @@ int Server::getPing() const { return Ping; } -const std::string& Server::getUIStatus() { +const std::string &Server::getUIStatus() { return UStatus; } -std::string Server::GetAddress(const std::string& Data) { - if(Data.find_first_not_of("0123456789.") == -1)return Data; - hostent* host; +std::string Server::GetAddress(const std::string &Data) { + if (Data.find_first_not_of("0123456789.") == -1)return Data; + hostent *host; host = gethostbyname(Data.c_str()); - if(!host){ + if (!host) { LOG(ERROR) << "DNS lookup failed! on " << Data; return "DNS"; } - std::string Ret = inet_ntoa(*((struct in_addr *)host->h_addr)); + std::string Ret = inet_ntoa(*((struct in_addr *) host->h_addr)); return Ret; } int Server::KillSocket(uint64_t Dead) { - if(Dead == (SOCKET)-1)return 0; + if (Dead == (SOCKET) -1)return 0; shutdown(Dead, SD_BOTH); return closesocket(Dead); } @@ -244,16 +253,16 @@ void Server::setModLoaded() { ModLoaded.store(true); } -void Server::UUl(const std::string& R) { +void Server::UUl(const std::string &R) { UStatus = "Disconnected: " + R; } bool Server::CheckBytes(int32_t Bytes) { - if (Bytes == 0){ + if (Bytes == 0) { //debug("(TCP) Connection closing... CheckBytes(16)"); Terminate = true; return false; - }else if (Bytes < 0) { + } else if (Bytes < 0) { //debug("(TCP CB) recv failed with error: " + GetSocketApiError(); KillSocket(TCPSocket); Terminate = true; @@ -262,23 +271,23 @@ bool Server::CheckBytes(int32_t Bytes) { return true; } -void Server::TCPSend(const std::string& Data) { +void Server::TCPSend(const std::string &Data) { - if(TCPSocket == -1) { + if (TCPSocket == -1) { Terminate = true; UUl("Invalid Socket"); return; } - int32_t Size,Sent,Temp; - std::string Send(4,0); + int32_t Size, Sent, Temp; + std::string Send(4, 0); Size = int32_t(Data.size()); - memcpy(&Send[0],&Size,sizeof(Size)); + memcpy(&Send[0], &Size, sizeof(Size)); Send += Data; // Do not use Size before this point for anything but the header Sent = 0; Size += 4; - do{ + do { if (size_t(Sent) >= Send.size()) { LOG(ERROR) << "string OOB in " << std::string(__func__); UUl("TCP Send OOB"); @@ -286,57 +295,57 @@ void Server::TCPSend(const std::string& Data) { return; } Temp = send(TCPSocket, &Send[Sent], Size - Sent, 0); - if(!CheckBytes(Temp)){ + if (!CheckBytes(Temp)) { UUl("Socket Closed Code 2"); Terminate = true; return; } Sent += Temp; - }while(Sent < Size); + } while (Sent < Size); } std::string Server::TCPRcv() { - if(TCPSocket == -1){ + if (TCPSocket == -1) { Terminate = true; UUl("Invalid Socket"); return ""; } - int32_t Header,BytesRcv = 0,Temp; + int32_t Header, BytesRcv = 0, Temp; std::vector Data(sizeof(Header)); - do{ - Temp = recv(TCPSocket, &Data[BytesRcv], 4-BytesRcv, 0); - if(!CheckBytes(Temp)){ + do { + Temp = recv(TCPSocket, &Data[BytesRcv], 4 - BytesRcv, 0); + if (!CheckBytes(Temp)) { UUl("Socket Closed Code 3"); Terminate = true; return ""; } BytesRcv += Temp; - }while(BytesRcv < 4); - memcpy(&Header,&Data[0],sizeof(Header)); + } while (BytesRcv < 4); + memcpy(&Header, &Data[0], sizeof(Header)); - if(!CheckBytes(BytesRcv)){ + if (!CheckBytes(BytesRcv)) { UUl("Socket Closed Code 4"); Terminate = true; return ""; } Data.resize(Header); BytesRcv = 0; - do{ - Temp = recv(TCPSocket, &Data[BytesRcv], Header-BytesRcv, 0); - if(!CheckBytes(Temp)){ + do { + Temp = recv(TCPSocket, &Data[BytesRcv], Header - BytesRcv, 0); + if (!CheckBytes(Temp)) { UUl("Socket Closed Code 5"); Terminate = true; return ""; } BytesRcv += Temp; - }while(BytesRcv < Header); + } while (BytesRcv < Header); - std::string Ret(Data.data(),Header); + std::string Ret(Data.data(), Header); if (Ret.substr(0, 4) == "ABG:") { Ret = Zlib::DeComp(Ret.substr(4)); } - if(Ret[0] == 'E')UUl(Ret.substr(1)); + if (Ret[0] == 'E')UUl(Ret.substr(1)); return Ret; }