mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-03 06:16:15 +00:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
811b04485c | ||
|
|
a64fead653 | ||
|
|
399461d1b1 | ||
|
|
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 |
4
.github/workflows/cmake-windows.yml
vendored
4
.github/workflows/cmake-windows.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Restore artifacts, or run vcpkg, build and cache artifacts
|
||||
uses: lukka/run-vcpkg@main
|
||||
uses: lukka/run-vcpkg@v7
|
||||
id: runvcpkg
|
||||
with:
|
||||
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||
vcpkgGitCommitId: '75522bb1f2e7d863078bcd06322348f053a9e33f'
|
||||
vcpkgGitCommitId: '06b5f4a769d848d1a20fa0acd556019728b56273'
|
||||
vcpkgTriplet: 'x64-windows-static'
|
||||
|
||||
- name: Create Build Environment
|
||||
|
||||
2
.github/workflows/release-build.yml
vendored
2
.github/workflows/release-build.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
with:
|
||||
vcpkgArguments: 'discord-rpc zlib rapidjson openssl'
|
||||
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
|
||||
vcpkgGitCommitId: '75522bb1f2e7d863078bcd06322348f053a9e33f'
|
||||
vcpkgGitCommitId: '06b5f4a769d848d1a20fa0acd556019728b56273'
|
||||
vcpkgTriplet: 'x64-windows-static'
|
||||
|
||||
- name: Create Build Environment
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@ cmake-build-debug
|
||||
cmake-build-release
|
||||
/.idea/
|
||||
*.log
|
||||
/*.sh
|
||||
/*.obj
|
||||
/*.exe
|
||||
@@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Logger.h"
|
||||
class HTTP{
|
||||
class HTTP {
|
||||
public:
|
||||
static bool Download(const std::string &IP, const std::string &Path);
|
||||
static std::string Post(const std::string& IP, const std::string& Fields);
|
||||
@@ -12,7 +12,8 @@
|
||||
void NetReset();
|
||||
extern bool Dev;
|
||||
extern int ping;
|
||||
void CoreNetwork();
|
||||
|
||||
[[noreturn]] void CoreNetwork();
|
||||
extern int ClientID;
|
||||
extern int LastPort;
|
||||
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()){
|
||||
DEFAULT_PORT = d["Port"].GetInt();
|
||||
}
|
||||
|
||||
//Default -1
|
||||
//Release 1
|
||||
//EA 2
|
||||
|
||||
@@ -14,16 +14,8 @@
|
||||
#include <thread>
|
||||
|
||||
std::string getDate() {
|
||||
typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>::type> days;
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
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);
|
||||
time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
tm local_tm = *localtime(&tt);
|
||||
std::stringstream date;
|
||||
int S = local_tm.tm_sec;
|
||||
int M = local_tm.tm_min;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Network/network.h"
|
||||
#include "Security/Init.h"
|
||||
|
||||
#include "http.h"
|
||||
#include "Http.h"
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include "Startup.h"
|
||||
@@ -58,7 +58,7 @@ void Parse(std::string Data,SOCKET CSocket){
|
||||
NetReset();
|
||||
Terminate = true;
|
||||
TCPTerminate = true;
|
||||
Data = Code + HTTP::Post("https://backend.beammp.com/servers","");
|
||||
Data = Code + HTTP::Get("https://backend.beammp.com/servers-info");
|
||||
break;
|
||||
case 'C':
|
||||
ListOfMods.clear();
|
||||
@@ -240,8 +240,8 @@ int Handle(EXCEPTION_POINTERS *ep){
|
||||
}
|
||||
|
||||
|
||||
void CoreNetwork(){
|
||||
while(TraceBack >= 4){
|
||||
[[noreturn]] void CoreNetwork(){
|
||||
while(true) {
|
||||
#ifndef __MINGW32__
|
||||
__try{
|
||||
#endif
|
||||
|
||||
@@ -75,7 +75,7 @@ void ServerSend(std::string Data, bool Rel){
|
||||
int DLen = int(Data.length());
|
||||
if(DLen > 3)C = Data.at(0);
|
||||
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 || DLen > 1000)SendLarge(Data);
|
||||
else TCPSend(Data,TCPSock);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <iostream>
|
||||
#include <Logger.h>
|
||||
#include <fstream>
|
||||
#include "http.h"
|
||||
#include "Http.h"
|
||||
#include <mutex>
|
||||
#include <cmath>
|
||||
#include <httplib.h>
|
||||
@@ -31,6 +31,7 @@ std::string HTTP::Get(const std::string &IP) {
|
||||
|
||||
httplib::Client cli(IP.substr(0, pos).c_str());
|
||||
cli.set_connection_timeout(std::chrono::seconds(10));
|
||||
cli.set_follow_location(true);
|
||||
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
|
||||
std::string Ret;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ std::string Auth(SOCKET Sock){
|
||||
|
||||
auto Res = TCPRcv(Sock);
|
||||
|
||||
if(Res.empty() || Res[0] == 'E'){
|
||||
if(Res.empty() || Res[0] == 'E' || Res[0] == 'K'){
|
||||
Abord();
|
||||
return "";
|
||||
}
|
||||
@@ -87,7 +87,7 @@ std::string Auth(SOCKET Sock){
|
||||
|
||||
Res = TCPRcv(Sock);
|
||||
|
||||
if(Res[0] == 'E'){
|
||||
if(Res[0] == 'E' || Res[0] == 'K'){
|
||||
Abord();
|
||||
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){
|
||||
do {
|
||||
double pr = Rcv / double(Size) * 100;
|
||||
double pr = double(Rcv) / double(Size) * 100;
|
||||
std::string Per = std::to_string(trunc(pr * 10) / 10);
|
||||
UpdateUl(true, Name + " (" + Per.substr(0, Per.find('.') + 2) + "%)");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
}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;
|
||||
|
||||
std::thread Au(AsyncUpdate,std::ref(GRcv),Size,Name);
|
||||
Au.detach();
|
||||
std::thread Au(AsyncUpdate,std::ref(GRcv), Size, Name);
|
||||
|
||||
std::packaged_task<char*()> task([&] { return TCPRcvRaw(MSock,GRcv,MSize); });
|
||||
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);
|
||||
return "";
|
||||
}
|
||||
|
||||
if(Au.joinable())Au.join();
|
||||
|
||||
|
||||
@@ -212,6 +211,11 @@ std::string MultiDownload(SOCKET MSock,SOCKET DSock, uint64_t Size, const std::s
|
||||
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){
|
||||
std::string Ret = Auth(Sock);
|
||||
@@ -238,6 +242,11 @@ void SyncResources(SOCKET Sock){
|
||||
t.clear();
|
||||
for(auto FN = FNames.begin(),FS = FSizes.begin(); FN != FNames.end() && !Terminate; ++FN,++FS) {
|
||||
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;
|
||||
Amount++;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ std::string TCPRcv(SOCKET Sock){
|
||||
#ifdef DEBUG
|
||||
//debug("Parsing from server -> " + std::to_string(Ret.size()));
|
||||
#endif
|
||||
if(Ret[0] == 'E')UUl(Ret.substr(1));
|
||||
if(Ret[0] == 'E' || Ret[0] == 'K')UUl(Ret.substr(1));
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ void lowExit(int code){
|
||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||
exit(2);
|
||||
}
|
||||
void Exit(int code){
|
||||
/*void Exit(int code){
|
||||
TraceBack = 0;
|
||||
std::string msg =
|
||||
"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));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||
exit(4);
|
||||
}
|
||||
}*/
|
||||
std::string GetGameDir(){
|
||||
if(TraceBack != 4)Exit(0);
|
||||
//if(TraceBack != 4)Exit(0);
|
||||
return GameDir.substr(0,GameDir.find_last_of('\\'));
|
||||
}
|
||||
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 a = false,b = true;
|
||||
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";
|
||||
steam += "\\config\\loginusers.vdf";
|
||||
if(fs::exists(Man) && fs::exists(steam)){
|
||||
for(const std::string&ID : GetID(steam)){
|
||||
if(ID == GetManifest(Man))b = false;
|
||||
}
|
||||
if(b)Exit(6);
|
||||
//if(b)Exit(6);
|
||||
}else a = true;
|
||||
return a;
|
||||
}
|
||||
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) {
|
||||
Result = QueryKey(hKey, 1);
|
||||
@@ -287,19 +285,22 @@ void LegitimacyCheck(){
|
||||
TraceBack++;
|
||||
}else lowExit(2);
|
||||
K2.clear();
|
||||
RegCloseKey(hKey);
|
||||
dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K3.c_str(), &hKey);
|
||||
RegCloseKey(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) {
|
||||
Result = QueryKey(hKey, 3);
|
||||
if(Result.empty())lowExit(3);
|
||||
if(IDCheck(Result,T))lowExit(5);
|
||||
//if(IDCheck(Result,T))lowExit(5);
|
||||
GameDir = Result;
|
||||
TraceBack++;
|
||||
//TraceBack++;
|
||||
}else lowExit(4);
|
||||
K3.clear();
|
||||
Result.clear();
|
||||
RegCloseKey(hKey);
|
||||
if(TraceBack < 3)exit(-1);
|
||||
//if(TraceBack < 3)exit(-1);
|
||||
}
|
||||
std::string CheckVer(const std::string &dir){
|
||||
std::string temp,Path = dir + "\\integrity.json";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/// Created by Anonymous275 on 11/26/2020
|
||||
///
|
||||
|
||||
#include "http.h"
|
||||
#include "Http.h"
|
||||
#include <filesystem>
|
||||
#include "Logger.h"
|
||||
#include <fstream>
|
||||
@@ -18,7 +18,7 @@ extern bool LoginAuth;
|
||||
std::string Role;
|
||||
|
||||
void UpdateKey(const char* newKey){
|
||||
if(newKey){
|
||||
if(newKey && std::isalnum(newKey[0])){
|
||||
std::ofstream Key("key");
|
||||
if(Key.is_open()){
|
||||
Key << newKey;
|
||||
@@ -88,13 +88,21 @@ void CheckLocalKey(){
|
||||
Key.read(&Buffer[0], Size);
|
||||
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 + "\"}");
|
||||
|
||||
json::Document d;
|
||||
d.Parse(Buffer.c_str());
|
||||
if (Buffer == "-1" || Buffer.at(0) != '{' || d.HasParseError()) {
|
||||
error(Buffer);
|
||||
fatal("Invalid answer from authentication servers, please try again later!");
|
||||
info("Invalid answer from authentication servers.");
|
||||
UpdateKey(nullptr);
|
||||
}
|
||||
if(d["success"].GetBool()){
|
||||
LoginAuth = true;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 7/16/2020
|
||||
///
|
||||
#include "zip_file.h"
|
||||
#include <windows.h>
|
||||
#include "Discord/discord_info.h"
|
||||
#include "Network/network.h"
|
||||
@@ -14,7 +15,7 @@
|
||||
#include "Logger.h"
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include "http.h"
|
||||
#include "Http.h"
|
||||
#include "Json.h"
|
||||
|
||||
extern int TraceBack;
|
||||
@@ -28,8 +29,9 @@ std::string GetVer(){
|
||||
return "2.0";
|
||||
}
|
||||
std::string GetPatch(){
|
||||
return ".4";
|
||||
return ".81";
|
||||
}
|
||||
|
||||
std::string GetEP(char*P){
|
||||
static std::string Ret = [&](){
|
||||
std::string path(P);
|
||||
@@ -194,10 +196,6 @@ size_t DirCount(const std::filesystem::path& path){
|
||||
void CheckMP(const std::string& Path) {
|
||||
if (!fs::exists(Path))return;
|
||||
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 {
|
||||
for (auto& p : fs::directory_iterator(Path)){
|
||||
if(p.exists() && !p.is_directory()){
|
||||
@@ -215,9 +213,10 @@ 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()) {
|
||||
auto Size = fs::file_size(File);
|
||||
std::string Data(Size, 0);
|
||||
db.read(&Data[0], Size);
|
||||
db.close();
|
||||
@@ -244,14 +243,9 @@ void EnableMP(){
|
||||
}
|
||||
|
||||
void PreGame(const std::string& GamePath){
|
||||
const std::string CurrVer("0.22.2.0");
|
||||
std::string GameVer = CheckVer(GamePath);
|
||||
info("Game Version : " + GameVer);
|
||||
if(GameVer < CurrVer){
|
||||
fatal("Game version is old! Please update.");
|
||||
}else if(GameVer > CurrVer){
|
||||
warn("Game is newer than recommended, multiplayer may not work as intended!");
|
||||
}
|
||||
|
||||
CheckMP(GetGamePath() + "mods/multiplayer");
|
||||
|
||||
if(!Dev) {
|
||||
@@ -264,12 +258,18 @@ void PreGame(const std::string& GamePath){
|
||||
}catch(std::exception&e){
|
||||
fatal(e.what());
|
||||
}
|
||||
std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
||||
|
||||
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
||||
"&pk=" + PublicKey +
|
||||
"&branch=" + Branch, GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
||||
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
||||
"&pk=" + PublicKey + "&branch=" + Branch, ZipPath);
|
||||
|
||||
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)");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <iostream>
|
||||
#include "Logger.h"
|
||||
#include <thread>
|
||||
#include "http.h"
|
||||
#include "Http.h"
|
||||
|
||||
[[noreturn]] void flush(){
|
||||
while(true){
|
||||
|
||||
Reference in New Issue
Block a user