Major rewrite, speed, and stability improvements

This commit is contained in:
Anonymous275 2020-06-04 01:52:33 +03:00
parent ff2d5d74ae
commit 80c3280e4e
8 changed files with 183 additions and 56 deletions

View File

@ -23,20 +23,21 @@ int OpenID(){
}while (!found);
return ID;
}
void TCPSendLarge(Client*c,const std::string&Data);
void SendLarge(Client*c,const std::string&Data);
void Respond(Client*c, const std::string& MSG, bool Rel){
char C = MSG.at(0);
if(Rel){
if(MSG.length() > 1000)TCPSendLarge(c,MSG);
if(C == 'O' || C == 'T' || MSG.length() > 1000)SendLarge(c,MSG);
else TCPSend(c,MSG);
}
else UDPSend(c,MSG);
}else UDPSend(c,MSG);
}
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
char C = Data.at(0);
for(Client*client : Clients){
if(Self || client != c){
if(Rel){
if(Data.length() > 1000 || Data.substr(0,2) == "Od")TCPSendLarge(client,Data);
if(C == 'O' || C == 'T' || Data.length() > 1000)SendLarge(client,Data);
else TCPSend(client,Data);
}
else UDPSend(client,Data);
@ -55,17 +56,15 @@ void UpdatePlayers(){
void OnDisconnect(Client*c,bool kicked){
std::string Packet;
for(const std::pair<int,std::string>&a : c->GetAllCars()){
Packet = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(a.first);
SendToAll(c, Packet,false,true);
}
if(kicked)Packet = "L"+c->GetName()+" was kicked!";
Packet = "L"+c->GetName()+" Left the server!";
SendToAll(c, Packet,false,true);
Packet.clear();
Clients.erase(c); ///Removes the Client from the existence
Clients.erase(c); ///Removes the Client from existence
}
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller);
void OnConnect(Client*c){

View File

@ -14,17 +14,6 @@ void Respond(Client*c, const std::string& MSG, bool Rel);
void UpdatePlayers();
/*void FindAndSync(Client*c,int ClientID){
for (Client*client : Clients) {
if (client != c){
if(client->GetID() == ClientID){ /////mark
Respond(client,c->GetCarData(ClientID),true);
}
}
}
}*/
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller);
void VehicleParser(Client*c, std::string Packet){
char Code = Packet.at(1);
@ -62,12 +51,6 @@ void VehicleParser(Client*c, std::string Packet){
break;
case 'm':
break;
/*case 'n':
if(Packet.substr(3).find_first_not_of("0123456789") == std::string::npos){
PID = stoi(Packet.substr(3));
}
FindAndSync(c,PID); //ACK System
break;*/
case 'r':
SendToAll(c,Packet,false,true);
break;

View File

@ -6,13 +6,25 @@
#include "Client.hpp"
#include <iostream>
#include <vector>
#include <tuple>
#include <array>
#include "../logger.h"
#include "../Settings.hpp"
SOCKET UDPSock;
struct PacketData{
int ID;
Client* Client;
std::string Data;
int Tries;
};
struct SplitData{
int Total;
int ID;
std::set<std::pair<int,std::string>> Fragments;
};
std::set<std::tuple<int,Client*,std::string>> BigDataAcks;
SOCKET UDPSock;
std::set<PacketData*> DataAcks;
std::set<SplitData*> SplitPackets;
void UDPSend(Client*c,const std::string&Data){
if(!c->isConnected())return;
sockaddr_in Addr = c->GetUDPAddr();
@ -22,22 +34,103 @@ void UDPSend(Client*c,const std::string&Data){
}
void AckID(int ID){
for(std::tuple<int,Client*,std::string> a : BigDataAcks){
if(get<0>(a) == ID){
BigDataAcks.erase(a);
for(PacketData* p : DataAcks){
if(p->ID == ID){
DataAcks.erase(p);
break;
}
}
}
void TCPSendLarge(Client*c,const std::string&Data){
static int ID = 0;
std::string Header = "BD:" + std::to_string(ID) + ":";
BigDataAcks.insert(std::make_tuple(ID,c,Header+Data));
if(ID > 483647)ID = 0;
int PacktID(){
static int ID = -1;
if(ID > 999999)ID = 0;
else ID++;
return ID;
}
int SplitID(){
static int SID = -1;
if(SID > 999999)SID = 0;
else SID++;
return SID;
}
void SendLarge(Client*c,const std::string&Data){
int ID = PacktID();
std::string Packet;
if(Data.length() > 1000){
std::string pckt = Data;
int S = 1,Split = ceil(float(pckt.length()) / 1000);
int SID = SplitID();
while(pckt.length() > 1000){
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+std::to_string(ID)+"|"+
std::to_string(SID)+":"+pckt.substr(0,1000);
DataAcks.insert(new PacketData{ID,c,Packet,1});
UDPSend(c,Packet);
pckt = pckt.substr(1000);
S++;
ID = PacktID();
}
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+
std::to_string(ID)+"|"+std::to_string(SID)+":"+pckt;
DataAcks.insert(new PacketData{ID,c,Packet,1});
UDPSend(c,Packet);
}else{
Packet = "BD:" + std::to_string(ID) + ":" + Data;
DataAcks.insert(new PacketData{ID,c,Packet,1});
UDPSend(c,Packet);
}
}
struct HandledC{
int Pos = 0;
Client *c;
std::array<int, 50> HandledIDs;
};
std::set<HandledC*> HandledIDs;
void ResetIDs(HandledC*H){
for(int C = 0;C < 50;C++){
H->HandledIDs.at(C) = -1;
}
}
HandledC*GetHandled(Client*c){
for(HandledC*h : HandledIDs){
if(h->c == c){
return h;
}
}
return new HandledC();
}
bool Handled(Client*c,int ID){
bool handle = false;
for(HandledC*h : HandledIDs){
if(h->c == c){
for(int id : h->HandledIDs){
if(id == ID)return true;
}
if(h->Pos > 49)h->Pos = 0;
h->HandledIDs.at(h->Pos) = ID;
h->Pos++;
handle = true;
}
}
for(HandledC*h : HandledIDs){
if(h->c == nullptr || !h->c->isConnected()){
HandledIDs.erase(h);
break;
}
}
if(!handle) {
HandledC *h = GetHandled(c);
ResetIDs(h);
if (h->Pos > 49)h->Pos = 0;
h->HandledIDs.at(h->Pos) = ID;
h->Pos++;
h->c = c;
HandledIDs.insert(h);
}
return false;
}
std::string UDPRcvFromClient(sockaddr_in& client){
char buf[10240];
int clientLength = sizeof(client);
@ -52,7 +145,39 @@ std::string UDPRcvFromClient(sockaddr_in& client){
return std::string(buf);
}
SplitData*GetSplit(int SplitID){
for(SplitData* a : SplitPackets){
if(a->ID == SplitID)return a;
}
SplitData* a = new SplitData();
SplitPackets.insert(a);
return a;
}
void GlobalParser(Client*c, const std::string&Packet);
void HandleChunk(Client*c,const std::string&Data){
int pos1 = Data.find(':')+1,pos2 = Data.find(':',pos1),pos3 = Data.find('/');
int pos4 = Data.find('|');
int Max = stoi(Data.substr(pos3+1,pos1-pos3-2));
int Current = stoi(Data.substr(2,pos3-2));
int ID = stoi(Data.substr(pos1,pos4-pos1));
int SplitID = stoi(Data.substr(pos4+1,pos2-pos4-1));
std::string ack = "ACK:" + Data.substr(pos1,pos4-pos1);
UDPSend(c,ack);
if(Handled(c,ID))return;
SplitData* SData = GetSplit(SplitID);
SData->Total = Max;
SData->ID = SplitID;
SData->Fragments.insert(std::make_pair(Current,Data.substr(pos2+1)));
if(SData->Fragments.size() == SData->Total){
std::string ToHandle;
for(std::pair<int,std::string> a : SData->Fragments){
ToHandle += a.second;
}
GlobalParser(c,ToHandle);
SplitPackets.erase(SData);
}
}
void UDPParser(Client*c, const std::string&Packet){
if(Packet.substr(0,4) == "ACK:"){
@ -61,10 +186,16 @@ void UDPParser(Client*c, const std::string&Packet){
return;
}else if(Packet.substr(0,3) == "BD:"){
int pos = Packet.find(':',4);
std::string pckt = "ACK:" + Packet.substr(3,pos-3);
int ID = stoi(Packet.substr(3,pos-3));
std::string pckt = "ACK:" + std::to_string(ID);
UDPSend(c,pckt);
pckt = Packet.substr(pos+1);
GlobalParser(c,pckt);
if(!Handled(c,ID)) {
pckt = Packet.substr(pos + 1);
GlobalParser(c, pckt);
}
return;
}else if(Packet.substr(0,2) == "SC"){
HandleChunk(c,Packet);
return;
}
GlobalParser(c,Packet);
@ -96,7 +227,7 @@ void StartLoop();
//return;
}
BigDataAcks.clear();
DataAcks.clear();
StartLoop();
info("Vehicle data network online on port "+std::to_string(Port)+" with a Max of "+std::to_string(MaxPlayers)+" Clients");
@ -109,7 +240,6 @@ void StartLoop();
/*char clientIp[256];
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
uint8_t ID = Data.at(0)-1;
for(Client*c : Clients){
if(c->GetID() == ID){
@ -127,14 +257,20 @@ void StartLoop();
#include <thread>
void LOOP(){
while(UDPSock != -1) {
for (std::tuple<int, Client *, std::string> a : BigDataAcks) {
if (get<1>(a)->GetTCPSock() == -1) {
BigDataAcks.erase(a);
for (PacketData* p : DataAcks){
if (p->Client == nullptr || p->Client->GetTCPSock() == -1) {
DataAcks.erase(p);
break;
}
if(p->Tries < 20){
UDPSend(p->Client,p->Data);
p->Tries++;
}else{
DataAcks.erase(p);
break;
}
UDPSend(get<1>(a), get<2>(a));
}
std::this_thread::sleep_for(std::chrono::seconds(2));
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
void StartLoop(){

View File

@ -15,3 +15,4 @@ extern std::string ClientVersion;
extern std::string FileList;
extern std::string FileSizes;
extern std::string Key;
extern std::string CustomIP;

View File

@ -6,7 +6,7 @@
#include <fstream>
#include <string>
#include "logger.h"
using namespace std; //nameSpace STD
void GenerateConfig();
string RemoveComments(const string& Line);
void SetValues(const string& Line, int Index);

View File

@ -9,8 +9,6 @@
#include "Settings.hpp"
#include "Network 2.0/Client.hpp"
using namespace std;
string HTTP_REQUEST(const std::string&,int);
std::string PostHTTP(const std::string& IP,const std::string& Fields);
std::string HTA(const std::string& hex)
@ -34,6 +32,7 @@ void Heartbeat()
R = "uuid="+Key+"&players="+to_string(Clients.size())+"&maxplayers="+to_string(MaxPlayers)+"&port="
+ to_string(Port) + "&map=" + MapName + "&private="+State+"&version="+ServerVersion+
"&clientversion="+ClientVersion+"&name="+ServerName;
if(!CustomIP.empty())R+="&ip="+CustomIP;
// https://beamng-mp.com/heartbeatv2
R = PostHTTP(HTA("68747470733a2f2f6265616d6e672d6d702e636f6d2f6865617274626561747632"),R);
if(R.find_first_not_of("20") != std::string::npos){

View File

@ -6,8 +6,6 @@
#include "curl/curl.h"
#include <iostream>
#include <string>
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
@ -42,6 +40,7 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

View File

@ -8,22 +8,32 @@
#include <chrono>
#include <thread>
#include "logger.h"
#include <algorithm>
#include "Settings.hpp"
using namespace std;
void DebugData();
void LogInit();
void ParseConfig();
void addToLog(const string& Data);
//void ServerMain(int Port, int MaxClients);
void HeartbeatInit();
string ServerVersion = "0.2";
string ClientVersion = "1.1+";
std::string ServerVersion = "0.2";
std::string ClientVersion = "1.1+";
std::string CustomIP;
void HandleResources(std::string path);
//void TCPMain(int Port);
void NetMain();
//Entry
int main() {
int main(int argc, char* argv[]) {
if(argc > 1){
CustomIP = argv[1];
size_t n = std::count(CustomIP.begin(), CustomIP.end(), '.');
int p = CustomIP.find_first_not_of(".0123456789");
if(p != std::string::npos || n != 3 || CustomIP.substr(0,3) == "127"){
CustomIP.clear();
warn("IP Specified is invalid!");
}else info("Started with custom ip : " + CustomIP);
}
LogInit();
ParseConfig();
info("BeamMP Server Running version " + ServerVersion);