Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better header (redone) #139

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion include/Utils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
#pragma once
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <array>
#include <cerrno>
#include <cstring>
#include <stdexcept>
#if defined(__linux__)
#include <sys/socket.h>
#include "linuxfixes.h"
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

namespace Utils {
inline std::vector<std::string> Split(const std::string& String, const std::string& delimiter) {
Expand All @@ -17,4 +30,39 @@ namespace Utils {
Val.push_back(s);
return Val;
};
};

template<typename T>
inline std::vector<char> PrependHeader(const T& data) {
std::vector<char> size_buffer(4);
uint32_t len = data.size();
std::memcpy(size_buffer.data(), &len, 4);
std::vector<char> buffer;
buffer.reserve(size_buffer.size() + data.size());
buffer.insert(buffer.begin(), size_buffer.begin(), size_buffer.end());
buffer.insert(buffer.end(), data.begin(), data.end());
return buffer;
}

inline uint32_t RecvHeader(SOCKET socket) {
std::array<uint8_t, sizeof(uint32_t)> header_buffer {};
auto n = recv(socket, reinterpret_cast<char*>(header_buffer.data()), header_buffer.size(), MSG_WAITALL);
if (n < 0) {
throw std::runtime_error(std::string("recv() of header failed: ") + std::strerror(errno));
} else if (n == 0) {
throw std::runtime_error("Game disconnected");
}
return *reinterpret_cast<uint32_t*>(header_buffer.data());
}

/// Throws!!!
inline void ReceiveFromGame(SOCKET socket, std::vector<char>& out_data) {
auto header = RecvHeader(socket);
out_data.resize(header);
auto n = recv(socket, reinterpret_cast<char*>(out_data.data()), out_data.size(), MSG_WAITALL);
if (n < 0) {
throw std::runtime_error(std::string("recv() of data failed: ") + std::strerror(errno));
} else if (n == 0) {
throw std::runtime_error("Game disconnected");
}
}
};
25 changes: 19 additions & 6 deletions src/GameStart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// Created by Anonymous275 on 7/19/2020
///

#include <cstring>
#if defined(_WIN32)
#include <windows.h>
#include <shlobj.h>
Expand Down Expand Up @@ -105,7 +106,6 @@ void StartGame(std::string Dir) {
}
#elif defined(__linux__)
void StartGame(std::string Dir) {
int status;
std::string filename = (Dir + "/BinLinux/BeamNG.drive.x64");
std::vector<const char*> argv;
argv.push_back(filename.data());
Expand All @@ -115,11 +115,24 @@ void StartGame(std::string Dir) {

argv.push_back(nullptr);
pid_t pid;
posix_spawn_file_actions_t spawn_actions;
posix_spawn_file_actions_init(&spawn_actions);
posix_spawn_file_actions_addclose(&spawn_actions, STDOUT_FILENO);
posix_spawn_file_actions_addclose(&spawn_actions, STDERR_FILENO);
int result = posix_spawn(&pid, filename.c_str(), &spawn_actions, nullptr, const_cast<char**>(argv.data()), environ);

posix_spawn_file_actions_t file_actions;
auto status = posix_spawn_file_actions_init(&file_actions);
// disable stdout
if (status != 0) {
error(std::string("posix_spawn_file_actions_init failed: ") + std::strerror(errno));
}
status = posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO);
if (status != 0) {
error(std::string("posix_spawn_file_actions_addclose for STDOUT failed: ") + std::strerror(errno));
}
status = posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO);
if (status != 0) {
error(std::string("posix_spawn_file_actions_addclose for STDERR failed: ") + std::strerror(errno));
}

// launch the game
int result = posix_spawn(&pid, filename.c_str(), &file_actions, NULL, const_cast<char**>(argv.data()), environ);

if (result != 0) {
error("Failed to Launch the game! launcher closing soon");
Expand Down
12 changes: 6 additions & 6 deletions src/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,35 @@ void addToLog(const std::string& Line) {
}
void info(const std::string& toPrint) {
std::string Print = getDate() + "[INFO] " + toPrint + "\n";
std::cout << Print;
std::cout << Print << std::flush;
addToLog(Print);
}
void debug(const std::string& toPrint) {
std::string Print = getDate() + "[DEBUG] " + toPrint + "\n";
if (options.verbose) {
std::cout << Print;
std::cout << Print << std::flush;
}
addToLog(Print);
}
void warn(const std::string& toPrint) {
std::string Print = getDate() + "[WARN] " + toPrint + "\n";
std::cout << Print;
std::cout << Print << std::flush;
addToLog(Print);
}
void error(const std::string& toPrint) {
std::string Print = getDate() + "[ERROR] " + toPrint + "\n";
std::cout << Print;
std::cout << Print << std::flush;
addToLog(Print);
}
void fatal(const std::string& toPrint) {
std::string Print = getDate() + "[FATAL] " + toPrint + "\n";
std::cout << Print;
std::cout << Print << std::flush;
addToLog(Print);
std::this_thread::sleep_for(std::chrono::seconds(5));
std::exit(1);
}
void except(const std::string& toPrint) {
std::string Print = getDate() + "[EXCEP] " + toPrint + "\n";
std::cout << Print;
std::cout << Print << std::flush;
addToLog(Print);
}
53 changes: 14 additions & 39 deletions src/Network/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Http.h"
#include "Network/network.hpp"
#include "Security/Init.h"
#include "Utils.h"
#include <cstdlib>
#include <regex>
#if defined(_WIN32)
Expand Down Expand Up @@ -89,7 +90,8 @@ void StartSync(const std::string& Data) {

void CoreSend(std::string data) {
if (CoreSocket != -1) {
int res = send(CoreSocket, (data + "\n").c_str(), int(data.size()) + 1, 0);
auto ToSend = Utils::PrependHeader(data);
int res = send(CoreSocket, ToSend.data(), ToSend.size(), 0);
if (res < 0) {
debug("(Core) send failed with error: " + std::to_string(WSAGetLastError()));
}
Expand Down Expand Up @@ -165,7 +167,7 @@ void Parse(std::string Data, SOCKET CSocket) {
Ping = "-2";
else
Ping = std::to_string(ping);
Data = std::string(UlStatus) + "\n" + "Up" + Ping;
Data = "Up" + Ping;
}
break;
case 'M':
Expand Down Expand Up @@ -227,53 +229,26 @@ void Parse(std::string Data, SOCKET CSocket) {
break;
}
if (!Data.empty() && CSocket != -1) {
int res = send(CSocket, (Data + "\n").c_str(), int(Data.size()) + 1, 0);
auto ToSend = Utils::PrependHeader(Data);
int res = send(CSocket, ToSend.data(), ToSend.size(), 0);
if (res < 0) {
debug("(Core) send failed with error: " + std::to_string(WSAGetLastError()));
}
}
}
void GameHandler(SOCKET Client) {
CoreSocket = Client;
int32_t Size, Temp, Rcv;
char Header[10] = { 0 };
std::vector<char> data{};
do {
Rcv = 0;
do {
Temp = recv(Client, &Header[Rcv], 1, 0);
if (Temp < 1)
break;
if (!isdigit(Header[Rcv]) && Header[Rcv] != '>') {
error("(Core) Invalid lua communication");
KillSocket(Client);
return;
}
} while (Header[Rcv++] != '>');
if (Temp < 1)
break;
if (std::from_chars(Header, &Header[Rcv], Size).ptr[0] != '>') {
debug("(Core) Invalid lua Header -> " + std::string(Header, Rcv));
try {
Utils::ReceiveFromGame(Client, data);
Parse(std::string(data.data(), data.size()), Client);
} catch (const std::exception& e) {
error(std::string("Error while receiving from game on core: ") + e.what());
break;
}
std::string Ret(Size, 0);
Rcv = 0;

do {
Temp = recv(Client, &Ret[Rcv], Size - Rcv, 0);
if (Temp < 1)
break;
Rcv += Temp;
} while (Rcv < Size);
if (Temp < 1)
break;

Parse(Ret, Client);
} while (Temp > 0);
if (Temp == 0) {
debug("(Core) Connection closing");
} else {
debug("(Core) recv failed with error: " + std::to_string(WSAGetLastError()));
}
} while (true);
debug("(Core) Connection closing");
NetReset();
KillSocket(Client);
}
Expand Down
69 changes: 15 additions & 54 deletions src/Network/GlobalHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/// Created by Anonymous275 on 7/25/2020
///
#include "Network/network.hpp"
#include "Utils.h"
#include <memory>
#include <zlib.h>
#if defined(_WIN32)
Expand All @@ -22,11 +23,11 @@
#endif

#include "Logger.h"
#include "Options.h"
#include <charconv>
#include <mutex>
#include <string>
#include <thread>
#include "Options.h"

std::chrono::time_point<std::chrono::high_resolution_clock> PingStart, PingEnd;
bool GConnected = false;
Expand Down Expand Up @@ -61,30 +62,13 @@ bool CheckBytes(uint32_t Bytes) {
void GameSend(std::string_view Data) {
static std::mutex Lock;
std::scoped_lock Guard(Lock);
if (TCPTerminate || !GConnected || CSocket == -1)
return;
int32_t Size, Temp, Sent;
Size = int32_t(Data.size());
Sent = 0;
#ifdef DEBUG
if (Size > 1000) {
debug("Launcher -> game (" + std::to_string(Size) + ")");
}
#endif
do {
if (Sent > -1) {
Temp = send(CSocket, &Data[Sent], Size - Sent, 0);
}
if (!CheckBytes(Temp))
return;
Sent += Temp;
} while (Sent < Size);
// send separately to avoid an allocation for += "\n"
Temp = send(CSocket, "\n", 1, 0);
if (!CheckBytes(Temp)) {
return;
auto ToSend = Utils::PrependHeader<std::string_view>(Data);
auto Result = send(CSocket, ToSend.data(), ToSend.size(), 0);
if (Result < 0) {
error("(Game) send failed with error: " + std::to_string(WSAGetLastError()));
}
}

void ServerSend(std::string Data, bool Rel) {
if (Terminate || Data.empty())
return;
Expand Down Expand Up @@ -262,42 +246,19 @@ void TCPGameServer(const std::string& IP, int Port) {
NetMainThread = std::make_unique<std::thread>(NetMain, IP, Port);
CServer = false;
}
int32_t Size, Temp, Rcv;
char Header[10] = { 0 };
std::vector<char> data {};

// Read byte by byte until '>' is rcved then get the size and read based on it
do {
Rcv = 0;

do {
Temp = recv(CSocket, &Header[Rcv], 1, 0);
if (Temp < 1 || TCPTerminate)
break;
} while (Header[Rcv++] != '>');
if (Temp < 1 || TCPTerminate)
break;
if (std::from_chars(Header, &Header[Rcv], Size).ptr[0] != '>') {
debug("(Game) Invalid lua Header -> " + std::string(Header, Rcv));
try {
Utils::ReceiveFromGame(CSocket, data);
ServerSend(std::string(data.data(), data.size()), false);
} catch (const std::exception& e) {
error(std::string("Error while receiving from game on proxy: ") + e.what());
break;
}
std::string Ret(Size, 0);
Rcv = 0;
do {
Temp = recv(CSocket, &Ret[Rcv], Size - Rcv, 0);
if (Temp < 1)
break;
Rcv += Temp;
} while (Rcv < Size && !TCPTerminate);
if (Temp < 1 || TCPTerminate)
break;

ServerSend(Ret, false);

} while (Temp > 0 && !TCPTerminate);
if (Temp == 0)
debug("(Proxy) Connection closing");
else
debug("(Proxy) recv failed error : " + std::to_string(WSAGetLastError()));
} while (!TCPTerminate);
debug("(Proxy) Connection closing");
}
TCPTerminate = true;
GConnected = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Startup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ std::string GetEN() {
}

std::string GetVer() {
return "2.2";
return "2.3";
}
std::string GetPatch() {
return ".1";
Expand Down
Loading