mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-05 07:16:29 +00:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec5e8ed5b3 | ||
|
|
5655164e60 | ||
|
|
3d9b7c2d67 | ||
|
|
764e3ab5c1 | ||
|
|
3314362faf | ||
|
|
e483f520db | ||
|
|
c92e32c0e1 | ||
|
|
cb872f8a41 | ||
|
|
0aae245054 | ||
|
|
480a7d038f | ||
|
|
f62f44d4c0 | ||
|
|
e316b89fb1 | ||
|
|
3b2dbcac1b | ||
|
|
d881c9faf6 | ||
|
|
11d9375f36 | ||
|
|
4207d7adcf | ||
|
|
832b1d66a0 | ||
|
|
cd829f9f22 | ||
|
|
f7c70eb6df | ||
|
|
01960f6470 | ||
|
|
f6065a1c00 | ||
|
|
ba3b7f0ed0 | ||
|
|
056eadbef2 | ||
|
|
2bb2dc9040 | ||
|
|
17553fd412 | ||
|
|
08c1c0f682 | ||
|
|
84959ae9c9 | ||
|
|
c90c102097 | ||
|
|
5b004426ce | ||
|
|
69c9060dd2 | ||
|
|
49870639ff | ||
|
|
0843862af9 | ||
|
|
71a9a567bc | ||
|
|
a6e3d0fad9 | ||
|
|
411d0786a5 | ||
|
|
acb6b11e24 | ||
|
|
1739393a73 | ||
|
|
298ef33ab7 | ||
|
|
d2433cceca | ||
|
|
705e0ab9c4 | ||
|
|
53c40a2bc3 | ||
|
|
96c60ef05a | ||
|
|
61759b8531 | ||
|
|
691be8cd08 | ||
|
|
082445c295 | ||
|
|
f4bda81be0 | ||
|
|
1ad8e0b8e5 | ||
|
|
6c673e78e5 | ||
|
|
09abe75fbb | ||
|
|
b45e4b40f2 | ||
|
|
15d1539a92 | ||
|
|
14a5f47549 | ||
|
|
584998277d |
4
.github/workflows/cmake-windows.yml
vendored
4
.github/workflows/cmake-windows.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
|||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
|
||||||
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
||||||
uses: lukka/run-vcpkg@main
|
uses: lukka/run-vcpkg@v7
|
||||||
id: runvcpkg
|
id: runvcpkg
|
||||||
with:
|
with:
|
||||||
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
||||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||||
vcpkgGitCommitId: '75522bb1f2e7d863078bcd06322348f053a9e33f'
|
vcpkgGitCommitId: '86ff75c6d8232b54d3ebd0e71525b4634dcd9523'
|
||||||
vcpkgTriplet: 'x64-windows-static'
|
vcpkgTriplet: 'x64-windows-static'
|
||||||
|
|
||||||
- name: Create Build Environment
|
- name: Create Build Environment
|
||||||
|
|||||||
2
.github/workflows/release-build.yml
vendored
2
.github/workflows/release-build.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
||||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||||
vcpkgGitCommitId: '75522bb1f2e7d863078bcd06322348f053a9e33f'
|
vcpkgGitCommitId: '86ff75c6d8232b54d3ebd0e71525b4634dcd9523'
|
||||||
vcpkgTriplet: 'x64-windows-static'
|
vcpkgTriplet: 'x64-windows-static'
|
||||||
|
|
||||||
- name: Create Build Environment
|
- name: Create Build Environment
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@ cmake-build-debug
|
|||||||
cmake-build-release
|
cmake-build-release
|
||||||
/.idea/
|
/.idea/
|
||||||
*.log
|
*.log
|
||||||
|
/*.sh
|
||||||
|
/*.obj
|
||||||
|
/*.exe
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
class HTTP{
|
class HTTP {
|
||||||
public:
|
public:
|
||||||
static bool Download(const std::string &IP, const std::string &Path);
|
static bool Download(const std::string &IP, const std::string &Path);
|
||||||
static std::string Post(const std::string& IP, const std::string& Fields);
|
static std::string Post(const std::string& IP, const std::string& Fields);
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
void NetReset();
|
void NetReset();
|
||||||
extern bool Dev;
|
extern bool Dev;
|
||||||
extern int ping;
|
extern int ping;
|
||||||
void CoreNetwork();
|
|
||||||
|
[[noreturn]] void CoreNetwork();
|
||||||
extern int ClientID;
|
extern int ClientID;
|
||||||
extern int LastPort;
|
extern int LastPort;
|
||||||
extern bool ModLoaded;
|
extern bool ModLoaded;
|
||||||
|
|||||||
5710
include/zip_file.h
Normal file
5710
include/zip_file.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@ void ParseConfig(const json::Document& d){
|
|||||||
if(d["Port"].IsInt()){
|
if(d["Port"].IsInt()){
|
||||||
DEFAULT_PORT = d["Port"].GetInt();
|
DEFAULT_PORT = d["Port"].GetInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Default -1
|
//Default -1
|
||||||
//Release 1
|
//Release 1
|
||||||
//EA 2
|
//EA 2
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <iostream>
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
unsigned long GamePID = 0;
|
unsigned long GamePID = 0;
|
||||||
@@ -36,7 +35,9 @@ std::string GetGamePath(){
|
|||||||
Path = QueryKey(hKey,5);
|
Path = QueryKey(hKey,5);
|
||||||
Path += "\\BeamNG.drive\\";
|
Path += "\\BeamNG.drive\\";
|
||||||
}
|
}
|
||||||
Path += CheckVer(GetGameDir()) + "\\";
|
std::string Ver = CheckVer(GetGameDir());
|
||||||
|
Ver = Ver.substr(0,Ver.find('.',Ver.find('.')+1));
|
||||||
|
Path += Ver + "\\";
|
||||||
return Path;
|
return Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,16 +14,8 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
std::string getDate() {
|
std::string getDate() {
|
||||||
typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>::type> days;
|
time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
tm local_tm = *localtime(&tt);
|
||||||
std::chrono::system_clock::duration tp = now.time_since_epoch();
|
|
||||||
days d = std::chrono::duration_cast<days>(tp);tp -= d;
|
|
||||||
auto h = std::chrono::duration_cast<std::chrono::hours>(tp);tp -= h;
|
|
||||||
auto m = std::chrono::duration_cast<std::chrono::minutes>(tp);tp -= m;
|
|
||||||
auto s = std::chrono::duration_cast<std::chrono::seconds>(tp);tp -= s;
|
|
||||||
time_t tt = std::chrono::system_clock::to_time_t(now);
|
|
||||||
tm local_tm{};
|
|
||||||
localtime_s(&local_tm,&tt);
|
|
||||||
std::stringstream date;
|
std::stringstream date;
|
||||||
int S = local_tm.tm_sec;
|
int S = local_tm.tm_sec;
|
||||||
int M = local_tm.tm_min;
|
int M = local_tm.tm_min;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "Network/network.h"
|
#include "Network/network.h"
|
||||||
#include "Security/Init.h"
|
#include "Security/Init.h"
|
||||||
|
|
||||||
#include "http.h"
|
#include "Http.h"
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
@@ -58,7 +58,7 @@ void Parse(std::string Data,SOCKET CSocket){
|
|||||||
NetReset();
|
NetReset();
|
||||||
Terminate = true;
|
Terminate = true;
|
||||||
TCPTerminate = true;
|
TCPTerminate = true;
|
||||||
Data = Code + HTTP::Post("https://backend.beammp.com/servers","");
|
Data = Code + HTTP::Get("https://backend.beammp.com/servers-info");
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
ListOfMods.clear();
|
ListOfMods.clear();
|
||||||
@@ -240,8 +240,8 @@ int Handle(EXCEPTION_POINTERS *ep){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CoreNetwork(){
|
[[noreturn]] void CoreNetwork(){
|
||||||
while(TraceBack >= 4){
|
while(true) {
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
__try{
|
__try{
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void ServerSend(std::string Data, bool Rel){
|
|||||||
int DLen = int(Data.length());
|
int DLen = int(Data.length());
|
||||||
if(DLen > 3)C = Data.at(0);
|
if(DLen > 3)C = Data.at(0);
|
||||||
if (C == 'O' || C == 'T')Ack = true;
|
if (C == 'O' || C == 'T')Ack = true;
|
||||||
if(C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')Rel = true;
|
if(C == 'N' || C == 'W' || C == 'Y' || C == 'V' || C == 'E' || C == 'C')Rel = true;
|
||||||
if(Ack || Rel){
|
if(Ack || Rel){
|
||||||
if(Ack || DLen > 1000)SendLarge(Data);
|
if(Ack || DLen > 1000)SendLarge(Data);
|
||||||
else TCPSend(Data,TCPSock);
|
else TCPSend(Data,TCPSock);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <Logger.h>
|
#include <Logger.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "http.h"
|
#include "Http.h"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <httplib.h>
|
#include <httplib.h>
|
||||||
@@ -31,6 +31,7 @@ std::string HTTP::Get(const std::string &IP) {
|
|||||||
|
|
||||||
httplib::Client cli(IP.substr(0, pos).c_str());
|
httplib::Client cli(IP.substr(0, pos).c_str());
|
||||||
cli.set_connection_timeout(std::chrono::seconds(10));
|
cli.set_connection_timeout(std::chrono::seconds(10));
|
||||||
|
cli.set_follow_location(true);
|
||||||
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
|
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
|
||||||
std::string Ret;
|
std::string Ret;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ std::string Auth(SOCKET Sock){
|
|||||||
|
|
||||||
auto Res = TCPRcv(Sock);
|
auto Res = TCPRcv(Sock);
|
||||||
|
|
||||||
if(Res.empty() || Res[0] == 'E'){
|
if(Res.empty() || Res[0] == 'E' || Res[0] == 'K'){
|
||||||
Abord();
|
Abord();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ std::string Auth(SOCKET Sock){
|
|||||||
|
|
||||||
Res = TCPRcv(Sock);
|
Res = TCPRcv(Sock);
|
||||||
|
|
||||||
if(Res[0] == 'E'){
|
if(Res[0] == 'E' || Res[0] == 'K'){
|
||||||
Abord();
|
Abord();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -109,11 +109,10 @@ void UpdateUl(bool D,const std::string&msg){
|
|||||||
|
|
||||||
void AsyncUpdate(uint64_t& Rcv,uint64_t Size,const std::string& Name){
|
void AsyncUpdate(uint64_t& Rcv,uint64_t Size,const std::string& Name){
|
||||||
do {
|
do {
|
||||||
double pr = Rcv / double(Size) * 100;
|
double pr = double(Rcv) / double(Size) * 100;
|
||||||
std::string Per = std::to_string(trunc(pr * 10) / 10);
|
std::string Per = std::to_string(trunc(pr * 10) / 10);
|
||||||
UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)");
|
UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)");
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
|
||||||
}while(!Terminate && Rcv < Size);
|
}while(!Terminate && Rcv < Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,8 +175,7 @@ std::string MultiDownload(SOCKET MSock,SOCKET DSock, uint64_t Size, const std::s
|
|||||||
|
|
||||||
uint64_t GRcv = 0, MSize = Size/2, DSize = Size - MSize;
|
uint64_t GRcv = 0, MSize = Size/2, DSize = Size - MSize;
|
||||||
|
|
||||||
std::thread Au(AsyncUpdate,std::ref(GRcv),Size,Name);
|
std::thread Au(AsyncUpdate,std::ref(GRcv), Size, Name);
|
||||||
Au.detach();
|
|
||||||
|
|
||||||
std::packaged_task<char*()> task([&] { return TCPRcvRaw(MSock,GRcv,MSize); });
|
std::packaged_task<char*()> task([&] { return TCPRcvRaw(MSock,GRcv,MSize); });
|
||||||
std::future<char*> f1 = task.get_future();
|
std::future<char*> f1 = task.get_future();
|
||||||
@@ -198,6 +196,7 @@ std::string MultiDownload(SOCKET MSock,SOCKET DSock, uint64_t Size, const std::s
|
|||||||
MultiKill(MSock,DSock);
|
MultiKill(MSock,DSock);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Au.joinable())Au.join();
|
if(Au.joinable())Au.join();
|
||||||
|
|
||||||
|
|
||||||
@@ -212,6 +211,11 @@ std::string MultiDownload(SOCKET MSock,SOCKET DSock, uint64_t Size, const std::s
|
|||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InvalidResource(const std::string& File){
|
||||||
|
UUl("Invalid mod \"" + File + "\"");
|
||||||
|
warn("The server tried to sync \"" + File + "\" that is not a .zip file!");
|
||||||
|
Terminate = true;
|
||||||
|
}
|
||||||
|
|
||||||
void SyncResources(SOCKET Sock){
|
void SyncResources(SOCKET Sock){
|
||||||
std::string Ret = Auth(Sock);
|
std::string Ret = Auth(Sock);
|
||||||
@@ -238,6 +242,11 @@ void SyncResources(SOCKET Sock){
|
|||||||
t.clear();
|
t.clear();
|
||||||
for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) {
|
for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) {
|
||||||
auto pos = FN->find_last_of('/');
|
auto pos = FN->find_last_of('/');
|
||||||
|
auto ZIP = FN->find(".zip");
|
||||||
|
if (ZIP == std::string::npos || FN->length() - ZIP != 4) {
|
||||||
|
InvalidResource(*FN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (pos == std::string::npos)continue;
|
if (pos == std::string::npos)continue;
|
||||||
Amount++;
|
Amount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ std::string TCPRcv(SOCKET Sock){
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
//debug("Parsing from server -> " + std::to_string(Ret.size()));
|
//debug("Parsing from server -> " + std::to_string(Ret.size()));
|
||||||
#endif
|
#endif
|
||||||
if(Ret[0] == 'E')UUl(Ret.substr(1));
|
if(Ret[0] == 'E' || Ret[0] == 'K')UUl(Ret.substr(1));
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ void lowExit(int code){
|
|||||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
void Exit(int code){
|
/*void Exit(int code){
|
||||||
TraceBack = 0;
|
TraceBack = 0;
|
||||||
std::string msg =
|
std::string msg =
|
||||||
"Sorry. We do not support cracked copies report this if you believe this is a mistake code ";
|
"Sorry. We do not support cracked copies report this if you believe this is a mistake code ";
|
||||||
@@ -43,9 +43,9 @@ void SteamExit(int code){
|
|||||||
error(msg+std::to_string(code));
|
error(msg+std::to_string(code));
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}*/
|
||||||
std::string GetGameDir(){
|
std::string GetGameDir(){
|
||||||
if(TraceBack != 4)Exit(0);
|
//if(TraceBack != 4)Exit(0);
|
||||||
return GameDir.substr(0,GameDir.find_last_of('\\'));
|
return GameDir.substr(0,GameDir.find_last_of('\\'));
|
||||||
}
|
}
|
||||||
LONG OpenKey(HKEY root,const char* path,PHKEY hKey){
|
LONG OpenKey(HKEY root,const char* path,PHKEY hKey){
|
||||||
@@ -244,25 +244,23 @@ std::string GetManifest(const std::string& Man){
|
|||||||
bool IDCheck(std::string Man, std::string steam){
|
bool IDCheck(std::string Man, std::string steam){
|
||||||
bool a = false,b = true;
|
bool a = false,b = true;
|
||||||
int pos = int(Man.rfind("steamapps"));
|
int pos = int(Man.rfind("steamapps"));
|
||||||
if(pos == -1)Exit(5);
|
// if(pos == -1)Exit(5);
|
||||||
Man = Man.substr(0,pos+9) + "\\appmanifest_284160.acf";
|
Man = Man.substr(0,pos+9) + "\\appmanifest_284160.acf";
|
||||||
steam += "\\config\\loginusers.vdf";
|
steam += "\\config\\loginusers.vdf";
|
||||||
if(fs::exists(Man) && fs::exists(steam)){
|
if(fs::exists(Man) && fs::exists(steam)){
|
||||||
for(const std::string&ID : GetID(steam)){
|
for(const std::string&ID : GetID(steam)){
|
||||||
if(ID == GetManifest(Man))b = false;
|
if(ID == GetManifest(Man))b = false;
|
||||||
}
|
}
|
||||||
if(b)Exit(6);
|
//if(b)Exit(6);
|
||||||
}else a = true;
|
}else a = true;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
void LegitimacyCheck(){
|
void LegitimacyCheck(){
|
||||||
std::string Result,T;
|
|
||||||
std::string K1 = R"(Software\Valve\Steam)";
|
|
||||||
std::string K2 = R"(Software\Valve\Steam\Apps\284160)";
|
|
||||||
std::string K3 = R"(Software\BeamNG\BeamNG.drive)";
|
|
||||||
HKEY hKey;
|
|
||||||
|
|
||||||
LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey);
|
//std::string K1 = R"(Software\Valve\Steam)";
|
||||||
|
//std::string K2 = R"(Software\Valve\Steam\Apps\284160)";
|
||||||
|
|
||||||
|
/*LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey);
|
||||||
|
|
||||||
if(dwRegOPenKey == ERROR_SUCCESS) {
|
if(dwRegOPenKey == ERROR_SUCCESS) {
|
||||||
Result = QueryKey(hKey, 1);
|
Result = QueryKey(hKey, 1);
|
||||||
@@ -287,19 +285,22 @@ void LegitimacyCheck(){
|
|||||||
TraceBack++;
|
TraceBack++;
|
||||||
}else lowExit(2);
|
}else lowExit(2);
|
||||||
K2.clear();
|
K2.clear();
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);*/
|
||||||
dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K3.c_str(), &hKey);
|
std::string Result;
|
||||||
|
std::string K3 = R"(Software\BeamNG\BeamNG.drive)";
|
||||||
|
HKEY hKey;
|
||||||
|
LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K3.c_str(), &hKey);
|
||||||
if(dwRegOPenKey == ERROR_SUCCESS) {
|
if(dwRegOPenKey == ERROR_SUCCESS) {
|
||||||
Result = QueryKey(hKey, 3);
|
Result = QueryKey(hKey, 3);
|
||||||
if(Result.empty())lowExit(3);
|
if(Result.empty())lowExit(3);
|
||||||
if(IDCheck(Result,T))lowExit(5);
|
//if(IDCheck(Result,T))lowExit(5);
|
||||||
GameDir = Result;
|
GameDir = Result;
|
||||||
TraceBack++;
|
//TraceBack++;
|
||||||
}else lowExit(4);
|
}else lowExit(4);
|
||||||
K3.clear();
|
K3.clear();
|
||||||
Result.clear();
|
Result.clear();
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
if(TraceBack < 3)exit(-1);
|
//if(TraceBack < 3)exit(-1);
|
||||||
}
|
}
|
||||||
std::string CheckVer(const std::string &dir){
|
std::string CheckVer(const std::string &dir){
|
||||||
std::string temp,Path = dir + "\\integrity.json";
|
std::string temp,Path = dir + "\\integrity.json";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/// Created by Anonymous275 on 11/26/2020
|
/// Created by Anonymous275 on 11/26/2020
|
||||||
///
|
///
|
||||||
|
|
||||||
#include "http.h"
|
#include "Http.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -18,7 +18,7 @@ extern bool LoginAuth;
|
|||||||
std::string Role;
|
std::string Role;
|
||||||
|
|
||||||
void UpdateKey(const char* newKey){
|
void UpdateKey(const char* newKey){
|
||||||
if(newKey){
|
if(newKey && std::isalnum(newKey[0])){
|
||||||
std::ofstream Key("key");
|
std::ofstream Key("key");
|
||||||
if(Key.is_open()){
|
if(Key.is_open()){
|
||||||
Key << newKey;
|
Key << newKey;
|
||||||
@@ -88,13 +88,21 @@ void CheckLocalKey(){
|
|||||||
Key.read(&Buffer[0], Size);
|
Key.read(&Buffer[0], Size);
|
||||||
Key.close();
|
Key.close();
|
||||||
|
|
||||||
|
for (char& c : Buffer) {
|
||||||
|
if (!std::isalnum(c) && c != '-') {
|
||||||
|
UpdateKey(nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Buffer = HTTP::Post("https://auth.beammp.com/userlogin", R"({"pk":")" + Buffer + "\"}");
|
Buffer = HTTP::Post("https://auth.beammp.com/userlogin", R"({"pk":")" + Buffer + "\"}");
|
||||||
|
|
||||||
json::Document d;
|
json::Document d;
|
||||||
d.Parse(Buffer.c_str());
|
d.Parse(Buffer.c_str());
|
||||||
if (Buffer == "-1" || Buffer.at(0) != '{' || d.HasParseError()) {
|
if (Buffer == "-1" || Buffer.at(0) != '{' || d.HasParseError()) {
|
||||||
error(Buffer);
|
error(Buffer);
|
||||||
fatal("Invalid answer from authentication servers, please try again later!");
|
info("Invalid answer from authentication servers.");
|
||||||
|
UpdateKey(nullptr);
|
||||||
}
|
}
|
||||||
if(d["success"].GetBool()){
|
if(d["success"].GetBool()){
|
||||||
LoginAuth = true;
|
LoginAuth = true;
|
||||||
|
|||||||
117
src/Startup.cpp
117
src/Startup.cpp
@@ -5,6 +5,7 @@
|
|||||||
///
|
///
|
||||||
/// Created by Anonymous275 on 7/16/2020
|
/// Created by Anonymous275 on 7/16/2020
|
||||||
///
|
///
|
||||||
|
#include "zip_file.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "Discord/discord_info.h"
|
#include "Discord/discord_info.h"
|
||||||
#include "Network/network.h"
|
#include "Network/network.h"
|
||||||
@@ -12,8 +13,10 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include <fstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "http.h"
|
#include "Http.h"
|
||||||
|
#include "Json.h"
|
||||||
|
|
||||||
extern int TraceBack;
|
extern int TraceBack;
|
||||||
bool Dev = false;
|
bool Dev = false;
|
||||||
@@ -26,8 +29,9 @@ std::string GetVer(){
|
|||||||
return "2.0";
|
return "2.0";
|
||||||
}
|
}
|
||||||
std::string GetPatch(){
|
std::string GetPatch(){
|
||||||
return ".2";
|
return ".80";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetEP(char*P){
|
std::string GetEP(char*P){
|
||||||
static std::string Ret = [&](){
|
static std::string Ret = [&](){
|
||||||
std::string path(P);
|
std::string path(P);
|
||||||
@@ -120,27 +124,78 @@ void CustomPort(int argc, char* argv[]){
|
|||||||
if(argc > 2)Dev = true;
|
if(argc > 2)Dev = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LinuxPatch(){
|
||||||
|
HKEY hKey = nullptr;
|
||||||
|
LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, R"(Software\Wine)", 0, KEY_READ, &hKey);
|
||||||
|
if (result != ERROR_SUCCESS || getenv("USER") == nullptr)return;
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
info("Wine/Proton Detected! If you are on windows delete HKEY_CURRENT_USER\\Software\\Wine in regedit");
|
||||||
|
info("Applying patches...");
|
||||||
|
|
||||||
|
result = RegCreateKey(HKEY_CURRENT_USER, R"(Software\Valve\Steam\Apps\284160)", &hKey);
|
||||||
|
|
||||||
|
if (result != ERROR_SUCCESS){
|
||||||
|
fatal(R"(failed to create HKEY_CURRENT_USER\Software\Valve\Steam\Apps\284160)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = RegSetValueEx(hKey, "Name", 0, REG_SZ, (BYTE*)"BeamNG.drive", 12);
|
||||||
|
|
||||||
|
if (result != ERROR_SUCCESS){
|
||||||
|
fatal(R"(failed to create the value "Name" under HKEY_CURRENT_USER\Software\Valve\Steam\Apps\284160)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
std::string Path = R"(Z:\home\)" + std::string(getenv("USER")) + R"(\.steam\steam\Steam.exe)";
|
||||||
|
|
||||||
|
if(!fs::exists(Path)) {
|
||||||
|
std::ofstream ofs(Path);
|
||||||
|
if (!ofs.is_open()) {
|
||||||
|
fatal("Failed to create file \"" + Path + "\"");
|
||||||
|
return;
|
||||||
|
} else ofs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
result = RegOpenKeyEx(HKEY_CURRENT_USER, R"(Software\Valve\Steam)", 0, KEY_ALL_ACCESS, &hKey);
|
||||||
|
if (result != ERROR_SUCCESS){
|
||||||
|
fatal(R"(failed to open HKEY_CURRENT_USER\Software\Valve\Steam)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = RegSetValueEx(hKey, "SteamExe", 0, REG_SZ, (BYTE*)Path.c_str(), Path.size());
|
||||||
|
|
||||||
|
if (result != ERROR_SUCCESS){
|
||||||
|
fatal(R"(failed to create the value "Name" under HKEY_CURRENT_USER\Software\Valve\Steam\Apps\284160)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
info("Patched!");
|
||||||
|
}
|
||||||
|
|
||||||
void InitLauncher(int argc, char* argv[]) {
|
void InitLauncher(int argc, char* argv[]) {
|
||||||
system("cls");
|
system("cls");
|
||||||
SetConsoleTitleA(("BeamMP Launcher v" + std::string(GetVer()) + GetPatch()).c_str());
|
SetConsoleTitleA(("BeamMP Launcher v" + std::string(GetVer()) + GetPatch()).c_str());
|
||||||
InitLog();
|
InitLog();
|
||||||
CheckName(argc, argv);
|
CheckName(argc, argv);
|
||||||
|
LinuxPatch();
|
||||||
CheckLocalKey();
|
CheckLocalKey();
|
||||||
ConfigInit();
|
ConfigInit();
|
||||||
CustomPort(argc, argv);
|
CustomPort(argc, argv);
|
||||||
Discord_Main();
|
Discord_Main();
|
||||||
CheckForUpdates(argc, argv, std::string(GetVer()) + GetPatch());
|
CheckForUpdates(argc, argv, std::string(GetVer()) + GetPatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DirCount(const std::filesystem::path& path){
|
size_t DirCount(const std::filesystem::path& path){
|
||||||
return (size_t)std::distance(std::filesystem::directory_iterator{path}, std::filesystem::directory_iterator{});
|
return (size_t)std::distance(std::filesystem::directory_iterator{path}, std::filesystem::directory_iterator{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckMP(const std::string& Path) {
|
void CheckMP(const std::string& Path) {
|
||||||
if (!fs::exists(Path))return;
|
if (!fs::exists(Path))return;
|
||||||
size_t c = DirCount(fs::path(Path));
|
size_t c = DirCount(fs::path(Path));
|
||||||
if (c > 3) {
|
|
||||||
warn(std::to_string(c - 1) + " multiplayer mods will be wiped from mods/multiplayer! Close this if you don't want that!");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(15));
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
for (auto& p : fs::directory_iterator(Path)){
|
for (auto& p : fs::directory_iterator(Path)){
|
||||||
if(p.exists() && !p.is_directory()){
|
if(p.exists() && !p.is_directory()){
|
||||||
@@ -154,8 +209,41 @@ void CheckMP(const std::string& Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnableMP(){
|
||||||
|
std::string File(GetGamePath() + "mods/db.json");
|
||||||
|
if(!fs::exists(File))return;
|
||||||
|
auto Size = fs::file_size(File);
|
||||||
|
if(Size < 2)return;
|
||||||
|
std::ifstream db(File);
|
||||||
|
if(db.is_open()) {
|
||||||
|
std::string Data(Size, 0);
|
||||||
|
db.read(&Data[0], Size);
|
||||||
|
db.close();
|
||||||
|
json::Document d;
|
||||||
|
d.Parse(Data.c_str());
|
||||||
|
if(Data.at(0) != '{' || d.HasParseError()){
|
||||||
|
//error("Failed to parse " + File); //TODO illegal formatting
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!d["mods"].IsNull() && !d["mods"]["multiplayerbeammp"].IsNull()){
|
||||||
|
d["mods"]["multiplayerbeammp"]["active"] = true;
|
||||||
|
rapidjson::StringBuffer buffer;
|
||||||
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||||
|
d.Accept(writer);
|
||||||
|
std::ofstream ofs(File);
|
||||||
|
if(ofs.is_open()){
|
||||||
|
ofs << buffer.GetString();
|
||||||
|
ofs.close();
|
||||||
|
}else{
|
||||||
|
error("Failed to write " + File);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PreGame(const std::string& GamePath){
|
void PreGame(const std::string& GamePath){
|
||||||
const std::string CurrVer("0.22.1.0");
|
const std::string CurrVer("0.26.1.0");
|
||||||
std::string GameVer = CheckVer(GamePath);
|
std::string GameVer = CheckVer(GamePath);
|
||||||
info("Game Version : " + GameVer);
|
info("Game Version : " + GameVer);
|
||||||
if(GameVer < CurrVer){
|
if(GameVer < CurrVer){
|
||||||
@@ -171,15 +259,22 @@ void PreGame(const std::string& GamePath){
|
|||||||
if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
|
if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
|
||||||
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
||||||
}
|
}
|
||||||
|
EnableMP();
|
||||||
}catch(std::exception&e){
|
}catch(std::exception&e){
|
||||||
fatal(e.what());
|
fatal(e.what());
|
||||||
}
|
}
|
||||||
|
std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
||||||
|
|
||||||
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
||||||
"&pk=" + PublicKey +
|
"&pk=" + PublicKey + "&branch=" + Branch, ZipPath);
|
||||||
"&branch=" + Branch, GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
|
||||||
|
std::string Target(GetGamePath() + "mods/unpacked/beammp");
|
||||||
|
|
||||||
|
if(fs::is_directory(Target)) {
|
||||||
|
fs::remove_all(Target);
|
||||||
|
}
|
||||||
|
|
||||||
//HTTP::Download("beammp.com/builds/client", GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
//HTTP::Download("beammp.com/builds/client", GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "http.h"
|
#include "Http.h"
|
||||||
|
|
||||||
[[noreturn]] void flush(){
|
[[noreturn]] void flush(){
|
||||||
while(true){
|
while(true){
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::thread th(flush);
|
std::thread th(flush);
|
||||||
|
|||||||
Reference in New Issue
Block a user