mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-03 06:16:15 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc6167cd2e | ||
|
|
e216b6ec06 | ||
|
|
6597fe5e26 | ||
|
|
2fa5d69369 | ||
|
|
fec80e2c67 | ||
|
|
fa8627a22b | ||
|
|
dd5256ae22 | ||
|
|
e24cbf61bb | ||
|
|
472e2d16b6 | ||
|
|
ae650cc142 | ||
|
|
ad7177bec8 | ||
|
|
a4005c5876 | ||
|
|
a3ad6f8700 | ||
|
|
d3bddb0203 |
52
README.md
52
README.md
@@ -2,57 +2,7 @@
|
||||
|
||||
The launcher is the way we communitcate to outside the game, it does a few automated actions such as but not limited to: downloading the mod, launching the game, and create a connection to a server.
|
||||
|
||||
**To clone this repository**: `git clone --recurse-submodules https://github.com/BeamMP/BeamMP-Launcher.git`
|
||||
|
||||
## How to build for Windows
|
||||
|
||||
Make sure you have the necessary development tools installed:
|
||||
|
||||
[vcpkg](https://vcpkg.io/en/)
|
||||
|
||||
### Release
|
||||
|
||||
In the root directory of the project,
|
||||
1. `cmake -DCMAKE_BUILD_TYPE=Release . -B bin -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static`
|
||||
2. `cmake --build bin --parallel --config Release`
|
||||
|
||||
Remember to change `C:/vcpkg` to wherever you have vcpkg installed.
|
||||
|
||||
### Debug
|
||||
|
||||
In the root directory of the project,
|
||||
1. `cmake . -B bin -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static`
|
||||
2. `cmake --build bin --parallel`
|
||||
|
||||
Remember to change `C:/vcpkg` to wherever you have vcpkg installed.
|
||||
|
||||
## How to build for Linux
|
||||
|
||||
Make sure you have `vcpkg` installed, as well as basic development tools, often found in packages, for example:
|
||||
|
||||
- Debian: `sudo apt install build-essential`
|
||||
- Fedora: `sudo dnf groupinstall "Development Tools"`
|
||||
- Arch: `sudo pacman -S base-devel`
|
||||
- openSUSE: `zypper in -t pattern devel-basis`
|
||||
|
||||
### Release
|
||||
|
||||
In the root directory of the project,
|
||||
1. `cmake -DCMAKE_BUILD_TYPE=Release . -B bin -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-linux`
|
||||
2. `cmake --build bin --parallel --config Release`
|
||||
|
||||
### Debug
|
||||
|
||||
In the root directory of the project,
|
||||
1. `cmake . -B bin -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-linux`
|
||||
2. `cmake --build bin --parallel`
|
||||
|
||||
## Running out of RAM while building
|
||||
|
||||
Should you run out of RAM while building, you can ommit the `--parallel` instruction, it will then use less RAM due to building only on one CPU thread.
|
||||
|
||||
You can also specify a number of threads to use, for example `--parallel 4` will use four CPU threads, but due to the small project size, you may be faster just omitting `--parallel` instead of trying to find the highest possible multithread number
|
||||
|
||||
## [Getting started](https://docs.beammp.com/game/getting-started/)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -90,6 +90,8 @@ void StartGame(std::string Dir) {
|
||||
gameArgs += options.game_arguments[i];
|
||||
}
|
||||
|
||||
debug("BeamNG executable path: " + Dir);
|
||||
|
||||
bSuccess = CreateProcessA(nullptr, (LPSTR)(Dir + gameArgs).c_str(), nullptr, nullptr, TRUE, 0, nullptr, BaseDir.c_str(), &si, &pi);
|
||||
if (bSuccess) {
|
||||
info("Game Launched!");
|
||||
@@ -97,7 +99,19 @@ void StartGame(std::string Dir) {
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
error("Game Closed! launcher closing soon");
|
||||
} else {
|
||||
error("Failed to Launch the game! launcher closing soon");
|
||||
std::string err = "";
|
||||
|
||||
DWORD dw = GetLastError();
|
||||
LPVOID lpErrorMsgBuffer;
|
||||
|
||||
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpErrorMsgBuffer, 0, nullptr) == 0) {
|
||||
err = "Unknown error code: " + std::to_string(dw);
|
||||
} else {
|
||||
err = "Error " + std::to_string(dw) + ": " + (char*)lpErrorMsgBuffer;
|
||||
}
|
||||
|
||||
error("Failed to Launch the game! launcher closing soon. " + err);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
exit(2);
|
||||
|
||||
@@ -141,7 +141,7 @@ void GetServerInfo(std::string Data) {
|
||||
const std::string buffer = ([&]() -> std::string {
|
||||
int32_t Header;
|
||||
std::vector<char> data(sizeof(Header));
|
||||
int32_t Temp = recv(ISock, data.data(), sizeof(Header), MSG_WAITALL);
|
||||
int Temp = recv(ISock, data.data(), sizeof(Header), MSG_WAITALL);
|
||||
|
||||
auto checkBytes = ([&](const int32_t bytes) -> bool {
|
||||
if (bytes == 0) {
|
||||
@@ -200,7 +200,17 @@ bool IsAllowedLink(const std::string& Link) {
|
||||
return std::regex_search(Link, link_match, link_pattern) && link_match.position() == 0;
|
||||
}
|
||||
|
||||
std::vector<std::future<void>> futures;
|
||||
|
||||
void Parse(std::string Data, SOCKET CSocket) {
|
||||
std::erase_if(futures, [](const std::future<void>& f) {
|
||||
if (f.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
char Code = Data.at(0), SubCode = 0;
|
||||
if (Data.length() > 1)
|
||||
SubCode = Data.at(1);
|
||||
@@ -213,9 +223,9 @@ void Parse(std::string Data, SOCKET CSocket) {
|
||||
Terminate = true;
|
||||
TCPTerminate = true;
|
||||
Data.clear();
|
||||
auto future = std::async(std::launch::async, []() {
|
||||
futures.push_back(std::async(std::launch::async, []() {
|
||||
CoreSend("B" + HTTP::Get("https://backend.beammp.com/servers-info"));
|
||||
});
|
||||
}));
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
@@ -312,9 +322,9 @@ void Parse(std::string Data, SOCKET CSocket) {
|
||||
}
|
||||
Data = "N" + Auth.dump();
|
||||
} else {
|
||||
auto future = std::async(std::launch::async, [data = std::move(Data)]() {
|
||||
futures.push_back(std::async(std::launch::async, [data = std::move(Data)]() {
|
||||
CoreSend("N" + Login(data.substr(data.find(':') + 1)));
|
||||
});
|
||||
}));
|
||||
Data.clear();
|
||||
}
|
||||
break;
|
||||
@@ -342,7 +352,8 @@ void Parse(std::string Data, SOCKET CSocket) {
|
||||
}
|
||||
void GameHandler(SOCKET Client) {
|
||||
CoreSocket = Client;
|
||||
int32_t Size, Temp, Rcv;
|
||||
int32_t Size, Rcv;
|
||||
int Temp;
|
||||
char Header[10] = { 0 };
|
||||
do {
|
||||
Rcv = 0;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include "Options.h"
|
||||
#include <chrono>
|
||||
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> PingStart, PingEnd;
|
||||
bool GConnected = false;
|
||||
@@ -261,7 +262,8 @@ void TCPGameServer(const std::string& IP, int Port) {
|
||||
NetMainThread = std::make_unique<std::thread>(NetMain, IP, Port);
|
||||
CServer = false;
|
||||
}
|
||||
int32_t Size, Temp, Rcv;
|
||||
int32_t Size, Rcv;
|
||||
int Temp;
|
||||
char Header[10] = { 0 };
|
||||
|
||||
// Read byte by byte until '>' is rcved then get the size and read based on it
|
||||
|
||||
@@ -164,9 +164,12 @@ std::vector<char> TCPRcvRaw(SOCKET Sock, uint64_t& GRcv, uint64_t Size) {
|
||||
do {
|
||||
// receive at most some MB at a time
|
||||
int Len = std::min(int(Size - Rcv), 1 * 1024 * 1024);
|
||||
int32_t Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL);
|
||||
if (Temp < 1) {
|
||||
info(std::to_string(Temp));
|
||||
int Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL);
|
||||
if (Temp == -1 || Temp == 0) {
|
||||
debug("Recv returned: " + std::to_string(Temp));
|
||||
if (Temp == -1) {
|
||||
error("Socket error during download: " + std::to_string(WSAGetLastError()));
|
||||
}
|
||||
UUl("Socket Closed Code 1");
|
||||
KillSocket(Sock);
|
||||
Terminate = true;
|
||||
@@ -177,8 +180,8 @@ std::vector<char> TCPRcvRaw(SOCKET Sock, uint64_t& GRcv, uint64_t Size) {
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto difference = end - start;
|
||||
float bits_per_s = float(Rcv * 8) / float(std::chrono::duration_cast<std::chrono::milliseconds>(difference).count());
|
||||
float megabits_per_s = bits_per_s / 1000;
|
||||
double bits_per_s = double(Rcv * 8) / double(std::chrono::duration_cast<std::chrono::milliseconds>(difference).count());
|
||||
double megabits_per_s = bits_per_s / 1000;
|
||||
DownloadSpeed = megabits_per_s;
|
||||
// every 8th iteration print the speed
|
||||
if (i % 8 == 0) {
|
||||
|
||||
@@ -81,7 +81,8 @@ std::string TCPRcv(SOCKET Sock) {
|
||||
UUl("Invalid Socket");
|
||||
return "";
|
||||
}
|
||||
int32_t Header, Temp;
|
||||
int32_t Header;
|
||||
int Temp;
|
||||
std::vector<char> Data(sizeof(Header));
|
||||
Temp = recv(Sock, Data.data(), sizeof(Header), MSG_WAITALL);
|
||||
if (!CheckBytes(Temp)) {
|
||||
|
||||
@@ -84,7 +84,7 @@ std::string GetVer() {
|
||||
return "2.4";
|
||||
}
|
||||
std::string GetPatch() {
|
||||
return ".0";
|
||||
return ".1";
|
||||
}
|
||||
|
||||
std::string GetEP(const char* P) {
|
||||
|
||||
Reference in New Issue
Block a user