Major rewrite, speed, and stability improvements

This commit is contained in:
Anonymous275 2020-06-04 01:52:48 +03:00
parent 4a3235f445
commit 422e94f833
6 changed files with 153 additions and 47 deletions

View File

@ -21,8 +21,8 @@ extern bool TCPTerminate;
extern bool MPDEV;
void StartSync(const std::string &Data){
std::thread t1(ProxyThread,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1)));
//std::thread t1(ProxyThread,"127.0.0.1",30814);
//std::thread t1(ProxyThread,Data.substr(1,Data.find(':')-1),std::stoi(Data.substr(Data.find(':')+1)));
std::thread t1(ProxyThread,"127.0.0.1",30814);
t1.detach();
}

View File

@ -26,17 +26,28 @@ void DeleteKey(){
RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey);
RegDeleteValueA(hKey, TEXT("userpath_override"));
}
void RollBack(const std::string&Val){
std::this_thread::sleep_for(std::chrono::seconds(7));
void RollBack(const std::string&Val,int T){
std::this_thread::sleep_for(std::chrono::seconds(T));
if(!Val.empty())Write(Val);
else DeleteKey();
}
void StartGame(const std::string&ExeDir,const std::string&Current){
std::cout << "Game Launched!\n";
std::thread RB(RollBack,Write(Current));
RB.detach();
SystemExec(ExeDir + " -nocrashreport");
std::cout << "\nGame Closed! launcher closing in 5 secs\n";
BOOL bSuccess = FALSE;
PROCESS_INFORMATION pi;
STARTUPINFO si = {0};
si.cb = sizeof(si);
std::string BaseDir = ExeDir.substr(0,ExeDir.find_last_of('\\'));
bSuccess = CreateProcessA(ExeDir.c_str(), nullptr, nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi);
if (bSuccess)
{
std::cout << "Game Launched!\n";
DWORD dwPid = pi.dwProcessId; //Gets the PID
std::thread RB(RollBack,Write(Current),7);
RB.detach();
WaitForSingleObject(pi.hProcess, INFINITE);
std::cout << "\nGame Closed! launcher closing in 5 secs\n";
}else std::cout << "\nFailed to Launch the game! launcher closing in 5 secs\n";
RollBack(Write(Current),0);
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(2);
}

View File

@ -12,7 +12,6 @@
#include <vector>
int ClientID = -1;
extern int DEFAULT_PORT;
std::chrono::time_point<std::chrono::steady_clock> PingStart,PingEnd;
extern std::vector<std::string> GlobalInfo;
@ -36,20 +35,19 @@ void GameSend(const std::string&Data){
//std::cout << "(Launcher->Game) Bytes sent: " << iSendResult << " : " << Data << std::endl;
}
}
void TCPSendLarge(const std::string&Data);
void SendLarge(const std::string&Data);
void TCPSend(const std::string&Data);
void UDPSend(const std::string&Data);
void ServerSend(const std::string&Data, bool Rel){
if(Terminate || Data.empty())return;
char C = 0;
bool Ack = false;
if(Data.length() > 3)C = Data.at(0);
if (C == 'O' || C == 'T')Rel = true;
if(Rel){
if(Data.length() > 1000 || Data.substr(0,2) == "Od")TCPSendLarge(Data);
if (C == 'O' || C == 'T')Ack = true;
if(Ack || Rel){
if(Ack || Data.length() > 1000)SendLarge(Data);
else TCPSend(Data);
}
else UDPSend(Data);
}else UDPSend(Data);
if (MPDEV && Data.length() > 1000) {
std::cout << "(Launcher->Server) Bytes sent: " << Data.length()

View File

@ -6,16 +6,29 @@
#include <WS2tcpip.h>
#include <iostream>
#include <thread>
#include <set>
#include <string>
#include <array>
#include <set>
extern bool Terminate;
extern int ClientID;
extern bool MPDEV;
SOCKET UDPSock;
sockaddr_in ToServer{};
struct PacketData{
int ID;
std::string Data;
int Tries;
};
std::set<std::pair<int,std::string>> BigDataAcks;
struct SplitData{
int Total;
int ID;
std::set<std::pair<int,std::string>> Fragments;
};
std::set<SplitData*> SplitPackets;
std::set<PacketData*> BigDataAcks;
void UDPSend(const std::string&Data){
if(ClientID == -1 || UDPSock == INVALID_SOCKET)return;
std::string Packet = char(ClientID+1) + std::string(":") + Data;
@ -25,42 +38,132 @@ void UDPSend(const std::string&Data){
void LOOP(){
while(UDPSock != -1) {
for (const std::pair<int, std::string>& a : BigDataAcks) {
UDPSend(a.second);
for (PacketData* p : BigDataAcks) {
if(p->Tries < 20){
p->Tries++;
UDPSend(p->Data);
}else{
BigDataAcks.erase(p);
break;
}
}
std::this_thread::sleep_for(std::chrono::seconds(2));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
void AckID(int ID){
for(const std::pair<int,std::string>& a : BigDataAcks){
if(a.first == ID){
BigDataAcks.erase(a);
for(PacketData* p : BigDataAcks){
if(p->ID == ID){
BigDataAcks.erase(p);
break;
}
}
}
void TCPSendLarge(const std::string&Data){
static int ID = 0;
std::string Header = "BD:" + std::to_string(ID) + ":";
BigDataAcks.insert(std::make_pair(ID,Header+Data));
if(ID > 483647)ID = 0;
int PacktID(){
static int ID = -1;
if(ID > 999999)ID = 0;
else ID++;
return ID;
}
int SplitID(){
static int SID = -1;
if(SID > 999999)SID = 0;
else SID++;
return SID;
}
void SendLarge(const std::string&Data){
int ID = PacktID();
std::string Packet;
if(Data.length() > 1000){
std::string pckt = Data;
int S = 1,Split = ceil(float(pckt.length()) / 1000);
int SID = SplitID();
while(pckt.length() > 1000){
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+std::to_string(ID)+"|"+
std::to_string(SID)+":"+pckt.substr(0,1000);
BigDataAcks.insert(new PacketData{ID,Packet,1});
UDPSend(Packet);
pckt = pckt.substr(1000);
S++;
ID = PacktID();
}
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+
std::to_string(ID)+"|"+std::to_string(SID)+":"+pckt;
BigDataAcks.insert(new PacketData{ID,Packet,1});
UDPSend(Packet);
}else{
Packet = "BD:" + std::to_string(ID) + ":" + Data;
BigDataAcks.insert(new PacketData{ID,Packet,1});
UDPSend(Packet);
}
}
std::array<int, 50> HandledIDs;
void IDReset(){
for(int C = 0;C < 50;C++){
HandledIDs.at(C) = -1;
}
}
bool Handled(int ID){
static int Pos = 0;
for(int id : HandledIDs){
if(id == ID)return true;
}
if(Pos > 49)Pos = 0;
HandledIDs.at(Pos) = ID;
Pos++;
return false;
}
SplitData*GetSplit(int SplitID){
for(SplitData* a : SplitPackets){
if(a->ID == SplitID)return a;
}
SplitData* a = new SplitData();
SplitPackets.insert(a);
return a;
}
void ServerParser(const std::string& Data);
void HandleChunk(const std::string&Data){
int pos1 = Data.find(':')+1,pos2 = Data.find(':',pos1),pos3 = Data.find('/');
int pos4 = Data.find('|');
int Max = stoi(Data.substr(pos3+1,pos1-pos3-2));
int Current = stoi(Data.substr(2,pos3-2));
int ID = stoi(Data.substr(pos1,pos4-pos1));
int SplitID = stoi(Data.substr(pos4+1,pos2-pos4-1));
std::string ack = "ACK:" + Data.substr(pos1,pos4-pos1);
UDPSend(ack);
if(Handled(ID))return;
SplitData* SData = GetSplit(SplitID);
SData->Total = Max;
SData->ID = SplitID;
SData->Fragments.insert(std::make_pair(Current,Data.substr(pos2+1)));
if(SData->Fragments.size() == SData->Total){
std::string ToHandle;
for(const std::pair<int,std::string>& a : SData->Fragments){
ToHandle += a.second;
}
ServerParser(ToHandle);
SplitPackets.erase(SData);
}
}
void UDPParser(const std::string&Packet){
if(Packet.substr(0,4) == "ACK:"){
AckID(stoi(Packet.substr(4)));
if(MPDEV)std::cout << "Got Ack for sending large data" << std::endl;
if(MPDEV)std::cout << "Got Ack for data" << std::endl;
return;
}else if(Packet.substr(0,3) == "BD:"){
int pos = Packet.find(':',4);
std::string pckt = "ACK:" + Packet.substr(3,pos-3);
int ID = stoi(Packet.substr(3,pos-3));
std::string pckt = "ACK:" + std::to_string(ID);
UDPSend(pckt);
pckt = Packet.substr(pos+1);
ServerParser(pckt);
if(!Handled(ID)) {
pckt = Packet.substr(pos + 1);
ServerParser(pckt);
}
return;
}else if(Packet.substr(0,2) == "SC"){
HandleChunk(Packet);
return;
}
ServerParser(Packet);
@ -89,7 +192,6 @@ void UDPClientMain(const std::string& IP,int Port){
std::cout << "Can't start Winsock! " << std::endl;
return;
}
ToServer.sin_family = AF_INET;
ToServer.sin_port = htons(Port);
inet_pton(AF_INET, IP.c_str(), &ToServer.sin_addr);
@ -97,12 +199,10 @@ void UDPClientMain(const std::string& IP,int Port){
BigDataAcks.clear();
std::thread Ack(LOOP);
Ack.detach();
IDReset();
TCPSend("P");
UDPSend("p");
while (!Terminate){
UDPRcv();
}
while(!Terminate)UDPRcv();
closesocket(UDPSock);
WSACleanup();
}

View File

@ -4,7 +4,6 @@
#include <chrono>
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#include <thread>
@ -58,7 +57,7 @@ void TCPRcv(){
ServerParser(std::string(buf));
}
void GameSend(const std::string&Data);
void SyncResources(SOCKET TCPSock);
void TCPClientMain(const std::string& IP,int Port){
WSADATA wsaData;
@ -89,11 +88,9 @@ void TCPClientMain(const std::string& IP,int Port){
getsockname(TCPSock, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
SyncResources(TCPSock);
while(!Terminate){
TCPRcv();
}
while(!Terminate)TCPRcv();
GameSend("T");
////Game Send Terminate
if( shutdown(TCPSock, SD_SEND) != 0 && MPDEV)
std::cout << "(TCP) shutdown error code: " << WSAGetLastError() << std::endl;

View File

@ -126,7 +126,7 @@ int main(int argc, char* argv[]){
std::string GamePath = SData.at(2);
if(MPDEV)std::cout << "You own BeamNG on this machine!" << std::endl;
std::cout << "Game Version : " << CheckVer(GamePath) << std::endl;
std::string ExeDir = "\""+GamePath.substr(0,GamePath.find_last_of('\\')) + R"(\Bin64\BeamNG.drive.x64.exe")";
std::string ExeDir = GamePath.substr(0,GamePath.find_last_of('\\')) + R"(\Bin64\BeamNG.drive.x64.exe)";
std::string Settings = Path + "\\settings\\uiapps-layouts.json";
if(stat(Settings.c_str(),&info)!=0){
link = "https://beamng-mp.com/client-data";