new auth system + major optimization

This commit is contained in:
Anonymous275
2020-12-16 01:36:35 +02:00
parent 6a29384b5c
commit 19b7f7f579
54 changed files with 16891 additions and 351 deletions

View File

@@ -34,7 +34,7 @@ std::string GenerateCall() {
return Ret.str();
}
std::string RunPromise(const std::string& IP, const std::string& R) {
std::packaged_task<std::string()> task([&] { return PostHTTP(IP, R); });
std::packaged_task<std::string()> task([&] { return PostHTTP(IP, R, false); });
std::future<std::string> f1 = task.get_future();
std::thread t(std::move(task));
t.detach();
@@ -46,7 +46,7 @@ std::string RunPromise(const std::string& IP, const std::string& R) {
_Exit(0);
}
void Heartbeat() {
[[noreturn]] void Heartbeat() {
DebugPrintTID();
std::string R, T;
bool isAuth = false;
@@ -54,17 +54,16 @@ void Heartbeat() {
R = GenerateCall();
if (!CustomIP.empty())
R += "&ip=" + CustomIP;
std::string link = Sec("https://beammp.com/heartbeatv2");
std::string link ="https://beammp.com/heartbeatv2";
T = RunPromise(link, R);
if (T.find_first_not_of(Sec("20")) != std::string::npos) {
if (T.substr(0,2) != "20") {
//Backend system refused server startup!
std::this_thread::sleep_for(std::chrono::seconds(10));
std::string Backup = Sec("https://backup1.beammp.com/heartbeatv2");
std::string Backup = "https://backup1.beammp.com/heartbeatv2";
T = RunPromise(Backup, R);
if (T.find_first_not_of(Sec("20")) != std::string::npos) {
error(Sec("Backend system refused server! Check your AuthKey"));
std::this_thread::sleep_for(std::chrono::seconds(3));
_Exit(-1);
if (T.substr(0,2) != "20") {
warn("Backend system refused server! Server might not show in the public list");
}
}
//Server Authenticated
@@ -76,7 +75,7 @@ void Heartbeat() {
WebsocketInit();
isAuth = true;
}
std::this_thread::sleep_for(std::chrono::seconds(3));
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void HBInit() {

View File

@@ -9,22 +9,21 @@
std::string CustomIP;
std::string GetSVer() {
return std::string(Sec("1.13"));
return std::string(Sec("1.20"));
}
std::string GetCVer() {
return std::string(Sec("1.70"));
return std::string(Sec("1.71"));
}
void Args(int argc, char* argv[]) {
info(Sec("BeamMP Server Running version ") + GetSVer());
info("BeamMP Server Running version " + GetSVer());
if (argc > 1) {
CustomIP = argv[1];
size_t n = std::count(CustomIP.begin(), CustomIP.end(), '.');
auto p = CustomIP.find_first_not_of(Sec(".0123456789"));
if (p != std::string::npos || n != 3 || CustomIP.substr(0, 3) == Sec("127")) {
CustomIP.clear();
warn(Sec("IP Specified is invalid! Ignoring"));
} else
info(Sec("Server started with custom IP"));
warn("IP Specified is invalid! Ignoring");
} else info("Server started with custom IP");
}
}
void InitServer(int argc, char* argv[]) {

View File

@@ -279,16 +279,14 @@ int lua_GetPlayerCount(lua_State* L) {
lua_pushinteger(L, CI->Size());
return 1;
}
int lua_GetDID(lua_State* L) {
int lua_GetGuest(lua_State* L) {
if (lua_isnumber(L, 1)) {
int ID = int(lua_tonumber(L, 1));
Client* c = GetClient(ID);
if (c != nullptr)
lua_pushstring(L, c->GetDID().c_str());
else
return 0;
if (c != nullptr)lua_pushboolean(L, c->isGuest);
else return 0;
} else {
SendError(L, Sec("GetDID not enough arguments"));
SendError(L, "GetGuest not enough arguments");
return 0;
}
return 1;
@@ -339,8 +337,6 @@ int lua_dropPlayer(lua_State* L) {
Client* c = GetClient(ID);
if (c == nullptr)
return 0;
if (c->GetRole() == Sec("MDEV"))
return 0;
std::string Reason;
if (Args > 1 && lua_isstring(L, 2)) {
Reason = std::string(Sec(" Reason : ")) + lua_tostring(L, 2);
@@ -391,8 +387,6 @@ int lua_RemoveVehicle(lua_State* L) {
SendError(L, Sec("RemoveVehicle invalid Player ID"));
return 0;
}
if (c->GetRole() == "MDEV")
return 0;
if (!c->GetCarData(VID).empty()) {
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
SendToAll(nullptr, Destroy, true, true);
@@ -589,6 +583,19 @@ void Lua::SetPluginName(const std::string& Name) {
void Lua::SetFileName(const std::string& Name) {
_FileName = Name;
}
int lua_TempFix(lua_State*L) {
if (lua_isnumber(L, 1)) {
int ID = int(lua_tonumber(L, 1));
Client* c = GetClient(ID);
if (c == nullptr)return 0;
std::string Ret;
if(c->isGuest){
Ret = "Guest-" + c->GetName();
}else Ret = c->GetName();
lua_pushstring(L,Ret.c_str());
} else SendError(L, "GetDID not enough arguments");
return 1;
}
void Lua::Init() {
Assert(luaState);
luaL_openlibs(luaState);
@@ -600,11 +607,12 @@ void Lua::Init() {
lua_register(luaState, "RegisterEvent", lua_RegisterEvent);
lua_register(luaState, "GetPlayerName", lua_GetPlayerName);
lua_register(luaState, "RemoveVehicle", lua_RemoveVehicle);
lua_register(luaState, "GetPlayerDiscordID", lua_GetDID);
lua_register(luaState, "GetPlayerVehicles", lua_GetCars);
lua_register(luaState, "GetPlayerDiscordID", lua_TempFix);
lua_register(luaState, "CreateThread", lua_CreateThread);
lua_register(luaState, "GetPlayerVehicles", lua_GetCars);
lua_register(luaState, "SendChatMessage", lua_sendChat);
lua_register(luaState, "GetPlayers", lua_GetAllPlayers);
lua_register(luaState, "GetPlayerGuest", lua_GetGuest);
lua_register(luaState, "StopThread", lua_StopThread);
lua_register(luaState, "DropPlayer", lua_dropPlayer);
lua_register(luaState, "GetPlayerHWID", lua_HWID);

View File

@@ -1,233 +1,109 @@
///
/// Created by Anonymous275 on 7/31/2020
///
#include "Curl/Http.h"
#include "Logger.h"
#include "Network.h"
#include <Lua/LuaSystem.hpp>
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <algorithm>
#include <atomic>
#include "Curl/Http.h"
#include "Settings.h"
#include "Network.h"
#include "Logger.h"
#include <cstring>
#include <sstream>
#include <string>
#include <thread>
#include "Json.h"
bool Send(SOCKET TCPSock, std::string Data) {
#ifdef WIN32
int BytesSent;
int len = static_cast<int>(Data.size());
#else
int64_t BytesSent;
size_t len = Data.size();
#endif // WIN32
BytesSent = send(TCPSock, Data.c_str(), len, 0);
Data.clear();
if (BytesSent <= 0) {
#ifndef WIN32
error(__func__ + std::string(" ") + strerror(errno));
#else
error(__func__ + std::string(" ") + std::to_string(WSAGetLastError()));
#endif // WIN32
return false;
}
return true;
}
std::string Rcv(SOCKET TCPSock) {
uint32_t RealSize;
#ifdef WIN32
int64_t BytesRcv = recv(TCPSock, reinterpret_cast<char*>(&RealSize), sizeof(RealSize), 0);
#else
int64_t BytesRcv = recv(TCPSock, reinterpret_cast<void*>(&RealSize), sizeof(RealSize), 0);
#endif
if (BytesRcv != sizeof(RealSize)) {
error(std::string(Sec("invalid packet: expected 4, got ")) + std::to_string(BytesRcv));
return "";
}
// RealSize is big-endian, so we convert it to host endianness
RealSize = ntohl(RealSize);
debug(std::string("got ") + std::to_string(RealSize) + " as size");
if (RealSize > 7000) {
error(Sec("Larger than allowed TCP packet received"));
return "";
}
char buf[7000];
std::fill_n(buf, 7000, 0);
BytesRcv = recv(TCPSock, buf, RealSize, 0);
if (BytesRcv != RealSize) {
debug("expected " + std::to_string(RealSize) + " bytes, got " + std::to_string(BytesRcv) + " instead");
}
if (BytesRcv <= 0)
return "";
return std::string(buf);
}
std::string GetRole(const std::string& DID) {
if (!DID.empty()) {
std::string a = HttpRequest(Sec("https://beammp.com/entitlement?did=") + DID, 443);
std::string b = HttpRequest(Sec("https://backup1.beammp.com/entitlement?did=") + DID, 443);
if (!a.empty() || !b.empty()) {
if (a != b)
a = b;
auto pos = a.find('"');
if (pos != std::string::npos) {
return a.substr(pos + 1, a.find('"', pos + 1) - 2);
} else if (a == "[]")
return Sec("Member");
}
std::string GetClientInfo(const std::string& PK) {
if (!PK.empty()) {
return PostHTTP("https://auth.beammp.com/pkToUser", R"({"key":")"+PK+"\"}",true);;
}
return "";
}
void Check(SOCKET TCPSock, std::shared_ptr<std::atomic_bool> ok) {
DebugPrintTID();
size_t accum = 0;
while (!*ok) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
accum += 100;
if (accum >= 5000) {
error(Sec("Identification timed out (Check accum)"));
CloseSocketProper(TCPSock);
return;
}
}
}
int Max() {
int M = MaxPlayers;
for (auto& c : CI->Clients) {
if (c != nullptr) {
if (c->GetRole() == Sec("MDEV"))
M++;
}
}
return M;
}
void CreateClient(SOCKET TCPSock, const std::string& Name, const std::string& DID, const std::string& Role) {
Client* CreateClient(SOCKET TCPSock) {
auto* c = new Client;
c->SetTCPSock(TCPSock);
c->SetName(Name);
c->SetRole(Role);
c->SetDID(DID);
Client& Client = *c;
CI->AddClient(std::move(c));
InitClient(&Client);
}
std::pair<int, int> Parse(const std::string& msg) {
std::stringstream ss(msg);
std::string t;
std::pair<int, int> a = { 0, 0 }; //N then E
while (std::getline(ss, t, 'g')) {
if (t.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)
return a;
if (a.first == 0) {
a.first = std::stoi(t, nullptr, 16);
} else if (a.second == 0) {
a.second = std::stoi(t, nullptr, 16);
} else
return a;
}
return { 0, 0 };
}
std::string GenerateM(RSA* key) {
std::stringstream stream;
stream << std::hex << key->n << "g" << key->e << "g" << RSA_E(Sec("IDC"), key);
return stream.str();
//c->SetRoles(Roles);
//c->isGuest = Guest;
//c->SetName(Name);
return c;
}
void Identification(SOCKET TCPSock, RSA* Skey) {
void ClientKick(Client* c, const std::string& R){
info("Client kicked: " + R);
TCPSend(c, "E" + R);
CloseSocketProper(c->GetTCPSock());
}
void Identification(SOCKET TCPSock) {
DebugPrintTID();
Assert(Skey);
std::shared_ptr<std::atomic_bool> ok = std::make_shared<std::atomic_bool>(false);
std::thread Timeout(Check, TCPSock, ok);
Timeout.detach();
std::string Name, DID, Role;
if (!Send(TCPSock, GenerateM(Skey))) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
std::string msg = Rcv(TCPSock);
auto Keys = Parse(msg);
if (!Send(TCPSock, RSA_E("HC", Keys.second, Keys.first))) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
auto* c = CreateClient(TCPSock);
std::string Res = Rcv(TCPSock);
std::string Ver = Rcv(TCPSock);
*ok = true;
Ver = RSA_D(Ver, Skey);
if (Ver.size() > 3 && Ver.substr(0, 2) == Sec("VC")) {
Ver = Ver.substr(2);
if (Ver.length() > 4 || Ver != GetCVer()) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
info("Identifying new client...");
std::string Rc = TCPRcv(c);
if (Rc.size() > 3 && Rc.substr(0, 2) == "VC") {
Rc = Rc.substr(2);
if (Rc.length() > 4 || Rc != GetCVer()) {
ClientKick(c,"Outdated Version!");
return;
}
} else {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
ClientKick(c,"Invalid version header!");
return;
}
Res = RSA_D(Res, Skey);
if (Res.size() < 3 || Res.substr(0, 2) != Sec("NR")) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
TCPSend(c, "S");
Rc = TCPRcv(c);
if(Rc.size() > 50){
ClientKick(c,"Invalid Key!");
return;
}
if (Res.find(':') == std::string::npos) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
Rc = GetClientInfo(Rc);
json::Document d;
d.Parse(Rc.c_str());
if(Rc == "-1" || d.HasParseError()){
ClientKick(c,"Invalid key!");
return;
}
Name = Res.substr(2, Res.find(':') - 2);
DID = Res.substr(Res.find(':') + 1);
Role = GetRole(DID);
if (Role.empty() || Role.find(Sec("Error")) != std::string::npos) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
if(d["username"].IsString() && d["roles"].IsString() && d["guest"].IsBool()){
c->SetName(d["username"].GetString());
c->SetRoles(d["roles"].GetString());
c->isGuest = d["guest"].GetBool();
}else{
ClientKick(c,"Invalid authentication data!");
return;
}
// DebugPrintTIDInternal(std::string("Client(") + Name + ")");
debug(Sec("Name -> ") + Name + Sec(", Role -> ") + Role + Sec(", ID -> ") + DID);
for (auto& c : CI->Clients) {
if (c != nullptr) {
if (c->GetDID() == DID) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(c->GetTCPSock());
c->SetStatus(-2);
debug("Name -> " + c->GetName() + ", Guest -> " + std::to_string(c->isGuest) + ", Roles -> " + c->GetRoles());
for (auto& Cl : CI->Clients) {
if (Cl != nullptr) {
if (Cl->GetName() == c->GetName()) {
info("Old client (" +Cl->GetName()+ ") kicked: Reconnecting");
CloseSocketProper(Cl->GetTCPSock());
Cl->SetStatus(-2);
break;
}
}
}
if (Role == Sec("MDEV") || CI->Size() < Max()) {
debug("Identification success");
CreateClient(TCPSock, Name, DID, Role);
} else {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
auto arg = std::make_unique<LuaArg>(LuaArg{{c->GetName(),c->GetRoles(),c->isGuest}});
int Res = TriggerLuaEvent("onPlayerAuth",false,nullptr, std::move(arg), true);
if(Res){
ClientKick(c,"you are not allowed on the server!");
return;
}
}
void Identify(SOCKET TCPSock) {
RSA* Skey = GenKey();
// this disgusting ifdef stuff is needed because for some
// reason MSVC defines __try and __except and libg++ defines
// __try and __catch so its all a big mess if we leave this in or undefine
// the macros
/*#ifdef WIN32
__try{
#endif // WIN32*/
Identification(TCPSock, Skey);
/*#ifdef WIN32
}__except(1){
if(TCPSock != -1){
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
}
}
#endif // WIN32*/
delete Skey;
if (CI->Size() < MaxPlayers) {
info("Identification success");
Client& Client = *c;
CI->AddClient(std::move(c));
InitClient(&Client);
} else ClientKick(c,"Server full!");
}
void TCPServerMain() {
@@ -264,7 +140,7 @@ void TCPServerMain() {
warn(Sec("Got an invalid client socket on connect! Skipping..."));
continue;
}
std::thread ID(Identify, client);
std::thread ID(Identification, client);
ID.detach();
} catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what()));

View File

@@ -3,22 +3,18 @@
///
#include "Client.hpp"
#include <memory>
std::string Client::GetName() {
return Name;
}
void Client::SetName(const std::string& name) {
Name = name;
}
void Client::SetDID(const std::string& did) {
DID = did;
}
std::string Client::GetDID() {
return DID;
}
void Client::SetRole(const std::string& role) {
void Client::SetRoles(const std::string& role) {
Role = role;
}
std::string Client::GetRole() {
std::string Client::GetRoles() {
return Role;
}
int Client::GetID() {
@@ -71,17 +67,13 @@ int Client::GetOpenCarID() {
return OpenID;
}
void Client::AddNewCar(int ident, const std::string& Data) {
VehicleData.insert(std::unique_ptr<VData>(new VData { ident, Data }));
VehicleData.insert(std::make_unique<VData>(VData { ident, Data }));
}
std::set<std::unique_ptr<VData>>& Client::GetAllCars() {
return VehicleData;
}
const std::set<std::unique_ptr<VData>>& Client::GetAllCars() const {
return VehicleData;
}
std::string Client::GetCarData(int ident) {
for (auto& v : VehicleData) {
if (v != nullptr && v->ID == ident) {

View File

@@ -48,7 +48,7 @@ void VehicleParser(Client* c, const std::string& Pckt) {
if (Data.at(0) == '0') {
int CarID = c->GetOpenCarID();
debug(c->GetName() + Sec(" created a car with ID ") + std::to_string(CarID));
Packet = "Os:" + c->GetRole() + ":" + c->GetName() + ":" + std::to_string(c->GetID()) + "-" + std::to_string(CarID) + Packet.substr(4);
Packet = "Os:" + c->GetRoles() + ":" + c->GetName() + ":" + std::to_string(c->GetID()) + "-" + std::to_string(CarID) + Packet.substr(4);
if (c->GetCarCount() >= MaxCars || TriggerLuaEvent(Sec("onVehicleSpawn"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true)) {
Respond(c, Packet, true);
std::string Destroy = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(CarID);

View File

@@ -28,7 +28,10 @@ std::string HttpRequest(const std::string& IP, int port) {
return readBuffer;
}
std::string PostHTTP(const std::string& IP, const std::string& Fields) {
std::string PostHTTP(const std::string& IP, const std::string& Fields, bool json) {
static auto *header = new curl_slist{(char*)"Content-Type: application/json"};
static std::mutex Lock;
std::scoped_lock Guard(Lock);
CURL* curl;
CURLcode res;
std::string readBuffer;
@@ -36,6 +39,7 @@ std::string PostHTTP(const std::string& IP, const std::string& Fields) {
Assert(curl);
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
if(json)curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

View File

@@ -2,6 +2,8 @@
/// Created by Anonymous275 on 8/1/2020
///
#include "Client.hpp"
#include <memory>
#include "Logger.h"
#include "Lua/LuaSystem.hpp"
#include "Network.h"
@@ -66,11 +68,8 @@ void UpdatePlayers() {
SendToAll(nullptr, Packet, true, true);
}
void OnDisconnect(Client* c, bool kicked) {
Assert(c);
info(c->GetName() + Sec(" Connection Terminated"));
if (c == nullptr)
return;
std::string Packet;
for (auto& v : c->GetAllCars()) {
if (v != nullptr) {
@@ -83,7 +82,7 @@ void OnDisconnect(Client* c, bool kicked) {
Packet = Sec("L") + c->GetName() + Sec(" Left the server!");
SendToAll(c, Packet, false, true);
Packet.clear();
TriggerLuaEvent(Sec("onPlayerDisconnect"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
TriggerLuaEvent(Sec("onPlayerDisconnect"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
CI->RemoveClient(c); ///Removes the Client from existence
}
void OnConnect(Client* c) {
@@ -91,11 +90,11 @@ void OnConnect(Client* c) {
info(Sec("Client connected"));
c->SetID(OpenID());
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
TriggerLuaEvent(Sec("onPlayerConnecting"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
TriggerLuaEvent(Sec("onPlayerConnecting"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
SyncResources(c);
if (c->GetStatus() < 0)
return;
Respond(c, "M" + MapName, true); //Send the Map on connect
info(c->GetName() + Sec(" : Connected"));
TriggerLuaEvent(Sec("onPlayerJoining"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
TriggerLuaEvent(Sec("onPlayerJoining"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID() } }), false);
}

View File

@@ -1,53 +1,30 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Client.hpp"
#include "Logger.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include "Settings.h"
#include "Client.hpp"
#include "Network.h"
#include "Logger.h"
#include <fstream>
#ifdef __linux
// we need this for `struct stat`
#include <sys/stat.h>
#endif // __linux
void STCPSend(Client* c, std::string Data) {
Assert(c);
if (c == nullptr)
return;
#ifdef WIN32
int BytesSent;
int len = static_cast<int>(Data.size());
#else
int64_t BytesSent;
size_t len = Data.size();
#endif // WIN32
BytesSent = send(c->GetTCPSock(), Data.c_str(), len, 0);
Data.clear();
if (BytesSent == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
} else if (BytesSent < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket, BytesSent < 0"));
CloseSocketProper(c->GetTCPSock());
}
}
void SendFile(Client* c, const std::string& Name) {
Assert(c);
info(c->GetName() + Sec(" requesting : ") + Name.substr(Name.find_last_of('/')));
info(c->GetName() + " requesting : " + Name.substr(Name.find_last_of('/')));
struct stat Info { };
if (stat(Name.c_str(), &Info) != 0) {
STCPSend(c, Sec("Cannot Open"));
TCPSend(c, "Cannot Open");
return;
}
std::ifstream f(Name.c_str(), std::ios::binary);
f.seekg(0, std::ios_base::end);
std::streampos fileSize = f.tellg();
size_t Size = size_t(fileSize);
auto Size = size_t(fileSize);
size_t Sent = 0;
size_t Diff;
int64_t Split = 64000;
@@ -57,13 +34,13 @@ void SendFile(Client* c, const std::string& Name) {
std::string Data(size_t(Split), 0);
f.seekg(int64_t(Sent), std::ios_base::beg);
f.read(&Data[0], Split);
STCPSend(c, Data);
TCPSend(c, Data);
Sent += size_t(Split);
} else {
std::string Data(Diff, 0);
f.seekg(int64_t(Sent), std::ios_base::beg);
f.read(&Data[0], int64_t(Diff));
STCPSend(c, Data);
TCPSend(c, Data);
Sent += Diff;
}
}
@@ -87,7 +64,7 @@ void Parse(Client* c, const std::string& Packet) {
std::string ToSend = FileList + FileSizes;
if (ToSend.empty())
ToSend = "-";
STCPSend(c, ToSend);
TCPSend(c, ToSend);
}
return;
default:
@@ -95,45 +72,19 @@ void Parse(Client* c, const std::string& Packet) {
}
}
bool STCPRecv(Client* c) {
Assert(c);
if (c == nullptr)
return false;
#define len 200
char buf[len];
ZeroMemory(buf, len);
int64_t BytesRcv = recv(c->GetTCPSock(), buf, len, 0);
#undef len
if (BytesRcv == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket in STCP receive, BytesRcv == 0"));
CloseSocketProper(c->GetTCPSock());
return false;
} else if (BytesRcv < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket in STCP receive, BytesRcv < 0"));
CloseSocketProper(c->GetTCPSock());
return false;
}
if (strcmp(buf, "Done") == 0)
return false;
std::string Ret(buf, size_t(BytesRcv));
Parse(c, Ret);
return true;
}
void SyncResources(Client* c) {
Assert(c);
if (c == nullptr)
return;
if (c == nullptr)return;
try {
STCPSend(c, Sec("WS"));
while (c->GetStatus() > -1 && STCPRecv(c))
;
TCPSend(c, "WS");
std::string Data;
while (c->GetStatus() > -1){
Data = TCPRcv(c);
if(Data == "Done")break;
Parse(c, Data);
}
} catch (std::exception& e) {
except(Sec("Exception! : ") + std::string(e.what()));
except("Exception! : " + std::string(e.what()));
c->SetStatus(-1);
}
}

View File

@@ -8,10 +8,10 @@
#include "UnixCompat.h"
#include <thread>
void TCPSend(Client* c, const std::string& Data) {
bool TCPSend(Client* c, const std::string& Data) {
Assert(c);
if (c == nullptr)
return;
return false;
// Size is BIG ENDIAN now, use only for header!
//auto Size = htonl(int32_t(Data.size()));
///TODO : BIG ENDIAN for other OS
@@ -27,16 +27,17 @@ void TCPSend(Client* c, const std::string& Data) {
if (Temp == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
return;
return false;
} else if (Temp < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
// info(Sec("Closing socket, Temp < 0"));
CloseSocketProper(c->GetTCPSock());
return;
return false;
}
Sent += Temp;
} while (Sent < Size);
return true;
}
bool CheckBytes(Client* c, int32_t BytesRcv) {
@@ -61,11 +62,11 @@ bool CheckBytes(Client* c, int32_t BytesRcv) {
return true;
}
void TCPRcv(Client* c) {
std::string TCPRcv(Client* c) {
Assert(c);
int32_t Header, BytesRcv = 0, Temp;
if (c == nullptr || c->GetStatus() < 0)
return;
return "";
std::vector<char> Data(sizeof(Header));
do {
@@ -74,7 +75,7 @@ void TCPRcv(Client* c) {
#ifdef DEBUG
error(std::string(__func__) + Sec(": failed on CheckBytes in while(BytesRcv < 4)"));
#endif // DEBUG
return;
return "";
}
BytesRcv += Temp;
} while (size_t(BytesRcv) < sizeof(Header));
@@ -87,7 +88,7 @@ void TCPRcv(Client* c) {
#ifdef DEBUG
error(std::string(__func__) + Sec(": failed on CheckBytes"));
#endif // DEBUG
return;
return "";
}
Data.resize(Header);
BytesRcv = 0;
@@ -98,7 +99,7 @@ void TCPRcv(Client* c) {
error(std::string(__func__) + Sec(": failed on CheckBytes in while(BytesRcv < Header)"));
#endif // DEBUG
return;
return "";
}
#ifdef DEBUG
//debug(std::string(__func__) + Sec(": Temp: ") + std::to_string(Temp) + Sec(", BytesRcv: ") + std::to_string(BytesRcv));
@@ -116,7 +117,8 @@ void TCPRcv(Client* c) {
#ifdef DEBUG
//debug("Parsing from " + c->GetName() + " -> " +std::to_string(Ret.size()));
#endif
GParser(c, Ret);
return Ret;
}
void TCPClient(Client* c) {
@@ -127,8 +129,9 @@ void TCPClient(Client* c) {
return;
}
OnConnect(c);
while (c->GetStatus() > -1)
TCPRcv(c);
while (c->GetStatus() > -1){
GParser(c, TCPRcv(c));
}
OnDisconnect(c, c->GetStatus() == -2);
}
void InitClient(Client* c) {

View File

@@ -5,11 +5,11 @@
#include "Logger.h"
#include "Security/Enc.h"
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>*/
#include <boost/asio/ip/tcp.hpp>
#include <boost/beast/websocket.hpp>
#include <iostream>
#include <string>
#include <thread>
#include <thread>*/
/*namespace beast = boost::beast;
namespace http = beast::http;