diff --git a/CMakeLists.txt b/CMakeLists.txt index 99869e3..67de9b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.15) include_directories(${PROJECT_SOURCE_DIR}/include) -project(BeamNG-MP-Launcher) +project(BeamMP-Launcher) set(CMAKE_CXX_STANDARD 14) -add_executable(BeamNG-MP-Launcher main.cpp proxy.cpp Security.cpp http.cpp Discord.cpp) +add_executable(BeamMP-Launcher main.cpp proxy.cpp Security.cpp http.cpp Discord.cpp UpdateCheck.cpp) -target_link_libraries(BeamNG-MP-Launcher discord-rpc) \ No newline at end of file +target_link_libraries(BeamMP-Launcher discord-rpc) \ No newline at end of file diff --git a/Security.cpp b/Security.cpp index 912617a..2960d27 100644 --- a/Security.cpp +++ b/Security.cpp @@ -6,9 +6,9 @@ #include #include #include - #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 + void Exit(const std::string& Msg); int TraceBack = 0; @@ -197,3 +197,76 @@ std::vector Check(){ RegCloseKey(hKey); return Data; } + +std::string HWID(){ + SYSTEM_INFO siSysInfo; + GetSystemInfo(&siSysInfo); + int I1 = siSysInfo.dwOemId; + int I2 = siSysInfo.dwNumberOfProcessors; + int I3 = siSysInfo.dwProcessorType; + int I4 = siSysInfo.dwActiveProcessorMask; + int I5 = siSysInfo.wProcessorLevel; + int I6 = siSysInfo.wProcessorRevision; + return std::to_string((I1*I2+I3)*(I4*I5+I6)); +} + +char* HashMD5(char* data, DWORD *result) +{ + DWORD dwStatus = 0; + DWORD cbHash = 16; + int i = 0; + HCRYPTPROV cryptProv; + HCRYPTHASH cryptHash; + BYTE hash[16]; + char hex[] = "0123456789abcdef"; + char *strHash; + strHash = (char*)malloc(500); + memset(strHash, '\0', 500); + if (!CryptAcquireContext(&cryptProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + dwStatus = GetLastError(); + printf("CryptAcquireContext failed: %d\n", dwStatus); + *result = dwStatus; + return nullptr; + } + if (!CryptCreateHash(cryptProv, CALG_MD5, 0, 0, &cryptHash)) + { + dwStatus = GetLastError(); + printf("CryptCreateHash failed: %d\n", dwStatus); + CryptReleaseContext(cryptProv, 0); + *result = dwStatus; + return nullptr; + } + if (!CryptHashData(cryptHash, (BYTE*)data, strlen(data), 0)) + { + dwStatus = GetLastError(); + printf("CryptHashData failed: %d\n", dwStatus); + CryptReleaseContext(cryptProv, 0); + CryptDestroyHash(cryptHash); + *result = dwStatus; + return nullptr; + } + if (!CryptGetHashParam(cryptHash, HP_HASHVAL, hash, &cbHash, 0)) + { + dwStatus = GetLastError(); + printf("CryptGetHashParam failed: %d\n", dwStatus); + CryptReleaseContext(cryptProv, 0); + CryptDestroyHash(cryptHash); + *result = dwStatus; + return nullptr; + } + for (i = 0; i < cbHash; i++) + { + strHash[i * 2] = hex[hash[i] >> 4]; + strHash[(i * 2) + 1] = hex[hash[i] & 0xF]; + } + CryptReleaseContext(cryptProv, 0); + CryptDestroyHash(cryptHash); + return strHash; +} +std::string getHardwareID() +{ + DWORD err; + std::string hash = HashMD5((char*)HWID().c_str(), &err); + return hash; +} diff --git a/UpdateCheck.cpp b/UpdateCheck.cpp new file mode 100644 index 0000000..18327a7 --- /dev/null +++ b/UpdateCheck.cpp @@ -0,0 +1,32 @@ +/// +/// Created by Anonymous275 on 3/29/2020 +/// + +#include +#include + + +void Download(const std::string& URL,const std::string& path); +std::string HTTP_REQUEST(const std::string&url,int port); +void SystemExec(const std::string& cmd); +void WinExec(const std::string& cmd); + +void CheckForUpdates(){ + system ("cls"); + std::string CV = "0.11"; + std::string HTTP = HTTP_REQUEST("backend.beamng-mp.com/builds/launcher/latest?version=true",80); + HTTP = HTTP.substr(HTTP.find_last_of("ver=")+1,HTTP.find_last_of('.')).substr(0,4); + std::cout << "Current Version : " << CV << "\nRemote version : " << HTTP << std::endl; + if(HTTP > CV){ + struct stat buffer{}; + if(stat ("BeamMP-Launcher.back", &buffer) == 0)remove("BeamMP-Launcher.back"); + std::cout << "Update found!" << std::endl; + std::cout << "Updating..." << std::endl; + SystemExec("rename BeamMP-Launcher.exe BeamMP-Launcher.back>nul"); + Download("http://backend.beamng-mp.com/builds/launcher/latest?download=true", "BeamMP-Launcher.exe"); + WinExec("BeamMP-Launcher.exe"); + exit(1); + }else{ + std::cout << "Version is up to date" << std::endl; + } +} \ No newline at end of file diff --git a/http.cpp b/http.cpp index 46ec187..8a0ddda 100644 --- a/http.cpp +++ b/http.cpp @@ -7,7 +7,7 @@ #include #include -std::string HTTP_REQUEST(){ +std::string HTTP_REQUEST(const std::string& IP,int port){ WSADATA wsaData; SOCKET Socket; @@ -22,27 +22,27 @@ std::string HTTP_REQUEST(){ std::string website_HTML; - std::string url = "s1.yourthought.co.uk"; + std::string url = IP.substr(0,IP.find('/'));//"s1.yourthought.co.uk"; - std::string get_http = "GET /servers-info HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n"; + std::string get_http = "GET "+IP.substr(IP.find('/'))+" HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n"; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){ std::cout << "WSAStartup failed.\n"; - system("pause"); + //return 1; } Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + host = gethostbyname(url.c_str()); - SockAddr.sin_port=htons(3599); //PORT + SockAddr.sin_port=htons(port); //PORT SockAddr.sin_family=AF_INET; SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){ std::cout << "Could not connect"; - //system("pause"); - //return 1; + return ""; } send(Socket,get_http.c_str(), strlen(get_http.c_str()),0 ); @@ -50,7 +50,6 @@ std::string HTTP_REQUEST(){ while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){ int i = 0; while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){ - website_HTML+=buffer[i]; i += 1; } @@ -59,5 +58,5 @@ std::string HTTP_REQUEST(){ closesocket(Socket); WSACleanup(); - return website_HTML.substr(website_HTML.find("[{"),website_HTML.size()); + return website_HTML; } \ No newline at end of file diff --git a/main.cpp b/main.cpp index cd7bad7..231dec1 100644 --- a/main.cpp +++ b/main.cpp @@ -5,8 +5,27 @@ #include #include #include +#include +#include +#include +#pragma comment(lib, "urlmon.lib") +std::string HTTP_REQUEST(const std::string&url,int port); +std::vector Discord_Main(); std::vector Check(); +std::string getHardwareID(); +void CheckForUpdates(); +void ProxyStart(); + +void Download(const std::string& URL,const std::string& path){ + URLDownloadToFileA(nullptr, URL.c_str(), path.c_str(), 0, nullptr); +} +void SystemExec(const std::string& cmd){ + system(cmd.c_str()); +} +void WinExec(const std::string& cmd){ + WinExec(cmd.c_str(), SW_HIDE); +} void Exit(const std::string& Msg){ std::cout << Msg << std::endl; @@ -14,28 +33,72 @@ void Exit(const std::string& Msg){ std::cin.ignore(); exit(-1); } +std::string CheckDir(char*dir){ + system("title BeamMP Launcher"); + char*temp;size_t len; + _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(CDir.substr(0,CDir.find_last_of('\\')) != AD){ + _mkdir(AD.c_str()); + SystemExec(R"(move "BeamMP-Launcher.exe" ")" + AD + "\">nul"); + } + SystemExec(R"(powershell "$s=(New-Object -COM WScript.Shell).CreateShortcut('%userprofile%\Desktop\BeamMP-Launcher.lnk');$s.TargetPath=')"+AD+"\\"+DN+"';$s.Save()\""); + SetCurrentDirectoryA(AD.c_str()); + CreateDirectoryA("BeamNG",nullptr); + CreateDirectoryA("BeamNG\\mods",nullptr); + SetFileAttributesA("BeamNG",2|4); + return AD + "\\BeamNG"; +} -void ProxyStart(); -std::string HTTP_REQUEST(); -std::vector Discord_Main(); -int main() +std::string CheckVer(const std::string &path){ + std::string vec,Path = path.substr(0,path.find_last_of('\\')) + "\\integrity.json"; + std::ifstream f(Path.c_str(), std::ios::binary); + f.seekg(0, std::ios_base::end); + std::streampos fileSize = f.tellg(); + vec.resize(size_t(fileSize) + 1); + f.seekg(0, std::ios_base::beg); + f.read(&vec[0], fileSize); + f.close(); + vec = vec.substr(vec.find_last_of("version"),vec.length()); + return vec.substr(vec.find(" \"")+2,vec.find_last_of('"')-6); +} + + +int main(int argc, char* argv[]) { + std::string Path = CheckDir(argv[0]),HTTP_Result; + + CheckForUpdates(); //Update Check + //Security std::vector Data = Check(); + std::string GamePath = Data.at(2); std::cout << "You own BeamNG on this machine!" << std::endl; + std::cout << "Game Ver : " << CheckVer(GamePath) << std::endl; - //std::cout << Data.at(2) << "\\BeamNG.drive.exe"; std::cout << "Name : " << Discord_Main().at(0) << std::endl; std::cout << "Discriminator : " << Discord_Main().at(1) << std::endl; std::cout << "Unique ID : " << Discord_Main().at(2) << std::endl; + std::cout << "HWID : " << getHardwareID() << std::endl; - //std::cout << "\nHTTP TEST :\n\n"; - //std::cout << HTTP_REQUEST(); + std::string ExeDir = GamePath.substr(0,GamePath.find_last_of('\\')) + "\\Bin64\\BeamNG.drive.x64.exe"; + Download("https://beamng-mp.com/builds/latest",Path + R"(\mods\BeamMP.zip)"); - /// Update, Mods ect... + /*WinExec(ExeDir + " -userpath " + Path); + std::cout << "Game Launched!\n";*/ + ///HTTP REQUEST FOR SERVER LIST + /* std::string HTTP_Result = HTTP_REQUEST("s1.yourthought.co.uk/servers-info",3599); + std::cout << HTTP_Result.substr(HTTP_Result.find("[{"));*/ + + + ///Mods //Start(); //Proxy main start Exit("");