mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-08-16 00:06:41 +00:00
v2.0.84
- add hash check - new routes for updates - use C++ 20
This commit is contained in:
parent
c731718f50
commit
3b479abf64
@ -7,7 +7,7 @@ if (WIN32)
|
|||||||
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
///
|
///
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <compare>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
void InitLauncher(int argc, char* argv[]);
|
void InitLauncher(int argc, char* argv[]);
|
||||||
std::string GetEP(char*P = nullptr);
|
std::string GetEP(char*P = nullptr);
|
||||||
std::string GetGamePath();
|
std::string GetGamePath();
|
||||||
@ -14,4 +17,12 @@ std::string GetVer();
|
|||||||
std::string GetEN();
|
std::string GetEN();
|
||||||
void StartProxy();
|
void StartProxy();
|
||||||
void ConfigInit();
|
void ConfigInit();
|
||||||
extern bool Dev;
|
extern bool Dev;
|
||||||
|
|
||||||
|
struct VersionParser {
|
||||||
|
explicit VersionParser(const std::string& from_string);
|
||||||
|
std::strong_ordering operator<=>(VersionParser const& rhs) const noexcept;
|
||||||
|
bool operator==(VersionParser const& rhs) const noexcept;
|
||||||
|
std::vector<std::string> split;
|
||||||
|
std::vector<size_t> data;
|
||||||
|
};
|
||||||
|
4642
include/hashpp.h
Normal file
4642
include/hashpp.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -80,7 +80,9 @@ void Parse(std::string Data,SOCKET CSocket){
|
|||||||
case 'O': //open default browser with URL
|
case 'O': //open default browser with URL
|
||||||
if(IsAllowedLink(Data.substr(1))) {
|
if(IsAllowedLink(Data.substr(1))) {
|
||||||
ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr,SW_SHOW); ///TODO: Look at when working on linux port
|
ShellExecuteA(nullptr, "open", Data.substr(1).c_str(), nullptr, nullptr,SW_SHOW); ///TODO: Look at when working on linux port
|
||||||
|
info("Opening Link \"" + Data.substr(1) + "\"");
|
||||||
}
|
}
|
||||||
|
Data.clear();
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
Data = Code + std::to_string(ProxyPort);
|
Data = Code + std::to_string(ProxyPort);
|
||||||
|
@ -144,9 +144,9 @@ void FileList(std::vector<std::string>&a,const std::string& Path){
|
|||||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||||
const auto& DPath = entry.path();
|
const auto& DPath = entry.path();
|
||||||
if (!entry.is_directory()) {
|
if (!entry.is_directory()) {
|
||||||
a.emplace_back(DPath.u8string());
|
a.emplace_back(DPath.string());
|
||||||
}else if(NameValid(DPath.filename().u8string())){
|
}else if(NameValid(DPath.filename().string())){
|
||||||
FileList(a, DPath.u8string());
|
FileList(a, DPath.string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ bool Find(const std::string& FName,const std::string& Path){
|
|||||||
bool FindHack(const std::string& Path){
|
bool FindHack(const std::string& Path){
|
||||||
bool s = true;
|
bool s = true;
|
||||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||||
std::string Name = entry.path().filename().u8string();
|
std::string Name = entry.path().filename().string();
|
||||||
for(char&c : Name)c = char(tolower(c));
|
for(char&c : Name)c = char(tolower(c));
|
||||||
if(Name == "steam.exe")s = false;
|
if(Name == "steam.exe")s = false;
|
||||||
if(Name.find("greenluma") != -1){
|
if(Name.find("greenluma") != -1){
|
||||||
|
118
src/Startup.cpp
118
src/Startup.cpp
@ -15,17 +15,46 @@
|
|||||||
#include "Security/Init.h"
|
#include "Security/Init.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
|
#include "hashpp.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "Http.h"
|
#include "Http.h"
|
||||||
|
|
||||||
|
|
||||||
extern int TraceBack;
|
extern int TraceBack;
|
||||||
bool Dev = false;
|
bool Dev = false;
|
||||||
int ProxyPort = 0;
|
int ProxyPort = 0;
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
VersionParser::VersionParser(const std::string& from_string) {
|
||||||
|
std::string token;
|
||||||
|
std::istringstream tokenStream(from_string);
|
||||||
|
while (std::getline(tokenStream, token, '.')) {
|
||||||
|
data.emplace_back(std::stol(token));
|
||||||
|
split.emplace_back(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::strong_ordering VersionParser::operator<=>(
|
||||||
|
const VersionParser& rhs) const noexcept {
|
||||||
|
size_t const fields = std::min(data.size(), rhs.data.size());
|
||||||
|
for (size_t i = 0; i != fields; ++i) {
|
||||||
|
if (data[i] == rhs.data[i]) continue;
|
||||||
|
else if (data[i] < rhs.data[i]) return std::strong_ordering::less;
|
||||||
|
else return std::strong_ordering::greater;
|
||||||
|
}
|
||||||
|
if (data.size() == rhs.data.size()) return std::strong_ordering::equal;
|
||||||
|
else if (data.size() > rhs.data.size()) return std::strong_ordering::greater;
|
||||||
|
else return std::strong_ordering::less;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VersionParser::operator==(const VersionParser& rhs) const noexcept {
|
||||||
|
return std::is_eq(*this <=> rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string GetEN(){
|
std::string GetEN(){
|
||||||
return "BeamMP-Launcher.exe";
|
return "BeamMP-Launcher.exe";
|
||||||
}
|
}
|
||||||
@ -75,44 +104,50 @@ void CheckName(int argc,char* args[]){
|
|||||||
URelaunch(argc,args);
|
URelaunch(argc,args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* std::string LatestHash = HTTP::Get("https://backend.beammp.com/sha/launcher?branch=" + TargetBuild + "&pk=" + PublicKey);
|
||||||
|
std::string LatestVersion = HTTP::Get("https://backend.beammp.com/version/launcher?branch=" + TargetBuild + "&pk=" + PublicKey);
|
||||||
|
|
||||||
void CheckForUpdates(int argc,char*args[],const std::string& CV){
|
transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower);
|
||||||
std::string link;
|
|
||||||
std::string HTTP = HTTP::Get("https://beammp.com/builds/launcher?version=true");
|
|
||||||
bool fallback = false;
|
|
||||||
if(HTTP.find_first_of("0123456789") == std::string::npos){
|
|
||||||
HTTP = HTTP::Get("https://backup1.beammp.com/builds/launcher?version=true");
|
|
||||||
fallback = true;
|
|
||||||
if(HTTP.find_first_of("0123456789") == std::string::npos) {
|
|
||||||
fatal("Primary Servers Offline! sorry for the inconvenience!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fallback){
|
|
||||||
link = "https://backup1.beammp.com/builds/launcher?download=true";
|
|
||||||
}else link = "https://beammp.com/builds/launcher?download=true";
|
|
||||||
|
|
||||||
|
std::string FileHash = hashpp::get::getFileHash(hashpp::ALGORITHMS::SHA2_256, (CurrentPath/"BeamMP-Launcher.exe").string());
|
||||||
std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back");
|
std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back");
|
||||||
|
|
||||||
if(fs::exists(Back))remove(Back.c_str());
|
if(FileHash != LatestHash && VersionParser(LatestVersion) > VersionParser(FullVersion)) {
|
||||||
|
LOG(INFO) << "Launcher update found!";
|
||||||
|
fs::remove(CurrentPath/"BeamMP-Launcher.back");
|
||||||
|
fs::rename(CurrentPath/"BeamMP-Launcher.exe", CurrentPath/"BeamMP-Launcher.back");
|
||||||
|
LOG(INFO) << "Downloading Launcher update " << LatestHash;
|
||||||
|
HTTP::Download(
|
||||||
|
"https://backend.beammp.com/builds/launcher?download=true"
|
||||||
|
"&pk=" +
|
||||||
|
PublicKey + "&branch=" + TargetBuild,
|
||||||
|
(CurrentPath/"BeamMP-Launcher.exe").string());
|
||||||
|
throw ShutdownException("Launcher update");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void CheckForUpdates(int argc, char* args[], const std::string& CV) {
|
||||||
|
std::string LatestHash = HTTP::Get("https://backend.beammp.com/sha/launcher?branch=" + Branch + "&pk=" + PublicKey);
|
||||||
|
std::string LatestVersion = HTTP::Get(
|
||||||
|
"https://backend.beammp.com/version/launcher?branch=" + Branch + "&pk=" + PublicKey);
|
||||||
|
|
||||||
if(HTTP > CV){
|
transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower);
|
||||||
system("cls");
|
std::string EP(GetEP() + GetEN()), Back(GetEP() + "BeamMP-Launcher.back");
|
||||||
info("Update found!");
|
|
||||||
info("Updating...");
|
|
||||||
if(std::rename(EP.c_str(), Back.c_str()))error("failed creating a backup!");
|
|
||||||
|
|
||||||
if(!HTTP::Download(link, EP)){
|
std::string FileHash = hashpp::get::getFileHash(hashpp::ALGORITHMS::SHA2_256, EP);
|
||||||
error("Launcher Update failed! trying again...");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
|
||||||
|
|
||||||
if(!HTTP::Download(link, EP)){
|
if (FileHash != LatestHash && VersionParser(LatestVersion) > VersionParser(GetVer()+GetPatch())) {
|
||||||
error("Launcher Update failed!");
|
info("Launcher update found!");
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
fs::remove(Back);
|
||||||
ReLaunch(argc,args);
|
fs::rename(EP, Back);
|
||||||
}
|
info("Downloading Launcher update " + LatestHash);
|
||||||
}
|
HTTP::Download(
|
||||||
URelaunch(argc,args);
|
"https://backend.beammp.com/builds/launcher?download=true"
|
||||||
}else info("Launcher version is up to date");
|
"&pk=" +
|
||||||
|
PublicKey + "&branch=" + Branch,
|
||||||
|
EP);
|
||||||
|
URelaunch(argc, args);
|
||||||
|
} else info("Launcher version is up to date");
|
||||||
TraceBack++;
|
TraceBack++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +213,7 @@ void CheckMP(const std::string& Path) {
|
|||||||
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()){
|
||||||
std::string Name = p.path().filename().u8string();
|
std::string Name = p.path().filename().string();
|
||||||
for(char&Ch : Name)Ch = char(tolower(Ch));
|
for(char&Ch : Name)Ch = char(tolower(Ch));
|
||||||
if(Name != "beammp.zip")fs::remove(p.path());
|
if(Name != "beammp.zip")fs::remove(p.path());
|
||||||
}
|
}
|
||||||
@ -224,7 +259,11 @@ void PreGame(const std::string& GamePath){
|
|||||||
CheckMP(GetGamePath() + "mods/multiplayer");
|
CheckMP(GetGamePath() + "mods/multiplayer");
|
||||||
|
|
||||||
if(!Dev) {
|
if(!Dev) {
|
||||||
info("Downloading mod please wait...");
|
std::string LatestHash = HTTP::Get("https://backend.beammp.com/sha/mod?branch=" + Branch + "&pk=" + PublicKey);
|
||||||
|
transform(LatestHash.begin(), LatestHash.end(), LatestHash.begin(), ::tolower);
|
||||||
|
LatestHash.erase(std::remove_if(LatestHash.begin(), LatestHash.end(),
|
||||||
|
[](auto const& c ) -> bool { return !std::isalnum(c); } ), LatestHash.end());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
|
if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
|
||||||
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
||||||
@ -233,20 +272,23 @@ void PreGame(const std::string& GamePath){
|
|||||||
}catch(std::exception&e){
|
}catch(std::exception&e){
|
||||||
fatal(e.what());
|
fatal(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
std::string ZipPath(GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
||||||
|
|
||||||
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
std::string FileHash = hashpp::get::getFileHash(hashpp::ALGORITHMS::SHA2_256, ZipPath);
|
||||||
"&pk=" + PublicKey + "&branch=" + Branch, ZipPath);
|
|
||||||
|
if (FileHash != LatestHash) {
|
||||||
|
info("Downloading BeamMP Update " + LatestHash);
|
||||||
|
HTTP::Download("https://backend.beammp.com/builds/client?download=true"
|
||||||
|
"&pk=" + PublicKey + "&branch=" + Branch, ZipPath);
|
||||||
|
}
|
||||||
|
|
||||||
std::string Target(GetGamePath() + "mods/unpacked/beammp");
|
std::string Target(GetGamePath() + "mods/unpacked/beammp");
|
||||||
|
|
||||||
if(fs::is_directory(Target)) {
|
if(fs::is_directory(Target)) {
|
||||||
fs::remove_all(Target);
|
fs::remove_all(Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
//HTTP::Download("beammp.com/builds/client", GetGamePath() + R"(mods\multiplayer\BeamMP.zip)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartProxy() {
|
void StartProxy() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user