Major rewrite of the network

This commit is contained in:
Anonymous275 2020-05-10 23:37:45 +03:00
parent b0c6c2bac4
commit 131e64b706
18 changed files with 549 additions and 6400 deletions

View File

@ -6,8 +6,10 @@ include_directories(${PROJECT_SOURCE_DIR}/curl)
set(CMAKE_CXX_STANDARD 14)
add_executable(BeamMP-Server src/main.cpp src/http.cpp src/logger.cpp src/config.cpp src/Network/Server.cpp
src/Network/enet.hpp src/Network/DataParser.cpp src/heartbeat.cpp
src/Network/ClientHandler.cpp src/Network/functions.cpp src/Settings.hpp
src/Resources.cpp src/Network/TCPClientHandler.cpp)
target_link_libraries(BeamMP-Server winmm ws2_32 libcurl_a)
file(GLOB source_files
"src/*.h" "src/*.hpp" "src/*.cpp"
"src/Network 2.0/*.hpp" "src/Network 2.0/*.cpp"
"src/curl/*.h")
add_executable(BeamMP-Server ${source_files})
target_link_libraries(BeamMP-Server libcurl_a ws2_32)

View File

@ -0,0 +1,70 @@
///
/// Created by Anonymous275 on 5/8/2020
///
#include "Client.hpp"
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){
Role = role;
}
std::string Client::GetRole(){
return Role;
}
int Client::GetID(){
return ID;
}
void Client::SetID(int id){
ID = id;
}
void Client::SetStatus(int state){
Status = state;
}
int Client::GetStatus(){
return Status;
}
void Client::SetUDPAddr(sockaddr_in Addr){
UDPADDR = Addr;
}
sockaddr_in Client::GetUDPAddr(){
return UDPADDR;
}
void Client::SetTCPSock(SOCKET CSock) {
TCPSOCK = CSock;
}
SOCKET Client::GetTCPSock(){
return TCPSOCK;
}
void Client::DeleteCar(int ident){
for(const std::pair<int,std::string>& a : VehicleData){
if(a.first == ident){
VehicleData.erase(a);
break;
}
}
}
void Client::AddNewCar(int ident,const std::string& Data){
VehicleData.insert(std::make_pair(ident,Data));
}
std::string Client::GetCarData(int ident){
for(const std::pair<int,std::string>& a : VehicleData){
if(a.first == ident){
return a.second;
}
}
DeleteCar(ident);
return "";
}
int Client::GetCarCount(){
return VehicleData.size();
}

View File

@ -0,0 +1,43 @@
///
/// Created by Anonymous275 on 5/8/2020
///
#pragma once
#include <WS2tcpip.h>
#include <string>
#include <vector>
#include <set>
class Client {
private:
std::set<std::pair<int,std::string>> VehicleData; //ID and Data;
std::string Name = "Unknown Client";
sockaddr_in UDPADDR;
std::string Role;
std::string DID; //Discord ID
SOCKET TCPSOCK;
int Status = 0;
int ID = -1; //PlayerID
public:
void AddNewCar(int ident,const std::string& Data);
void SetName(const std::string& name);
void SetRole(const std::string& role);
void SetDID(const std::string& did);
std::string GetCarData(int ident);
void SetUDPAddr(sockaddr_in Addr);
void SetTCPSock(SOCKET CSock);
void SetStatus(int status);
void DeleteCar(int ident);
sockaddr_in GetUDPAddr();
std::string GetRole();
std::string GetName();
std::string GetDID();
SOCKET GetTCPSock();
void SetID(int ID);
int GetCarCount();
int GetStatus();
int GetID();
};
extern std::set<Client*> Clients;

View File

@ -0,0 +1,64 @@
///
/// Created by Anonymous275 on 2/4/2020.
///
#include "Client.hpp"
#include "../logger.h"
#include "../Settings.hpp"
void UDPSend(Client*c,const std::string&Data);
void TCPSend(Client*c,const std::string&Data);
int OpenID(){
int ID = 0;
bool found;
do {
found = true;
for (Client *c : Clients) {
if(c->GetID() == ID){
found = false;
ID++;
}
}
}while (!found);
return ID;
}
void Respond(Client*c, const std::string& MSG, bool Rel){
if(Rel)TCPSend(c,MSG);
else UDPSend(c,MSG);
}
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
for(Client*client : Clients){
if(Self || client != c){
if(Rel)TCPSend(client,Data);
else UDPSend(client,Data);
}
}
}
void UpdatePlayers(){
std::string Packet = "Ss" + std::to_string(Clients.size())+"/"+std::to_string(MaxPlayers) + ":";
for (Client*c : Clients) {
Packet += c->GetName() + ",";
}
Packet = Packet.substr(0,Packet.length()-1);
SendToAll(nullptr, Packet,true,true);
}
void OnDisconnect(Client*c,bool Timed){
std::string Packet = "Od:" + std::to_string(c->GetID());
SendToAll(c, Packet,false,true);
//if(Timed)Packet = "L"+c->GetName()+" Timed out!";
Packet = "L"+c->GetName()+" Left the server!";
SendToAll(c, Packet,false,true);
Packet.clear();
Clients.erase(c); ///Removes the Client from the list
}
void OnConnect(Client*c){
c->SetID(OpenID());
std::cout << "New Client Created! ID : " << c->GetID() << std::endl;
Respond(c,"NR",true);
Respond(c,"M"+MapName,true); //Send the Map on connect
}

View File

@ -0,0 +1,135 @@
///
/// Created by Anonymous275 on 4/2/2020
///
#include <thread>
#include <iostream>
#include "Client.hpp"
#include "../logger.h"
#include "../Settings.hpp"
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel);
std::string HTTP_REQUEST(const std::string& IP,int port);
void Respond(Client*c, const std::string& MSG, bool Rel);
void UpdatePlayers();
void FindAndSync(Client*c,int VehID){
for (Client*client : Clients) {
if (client != c){
if(client->GetID() == VehID){ /////mark
Respond(client,c->GetCarData(VehID),true);
}
}
}
}
void VehicleParser(Client*c, std::string Packet){
char Code = Packet.at(1);
int ID = -1;
std::string Data = Packet.substr(3);
switch(Code){ //Spawned Destroyed Switched/Moved NotFound Reset
case 's':
if(Data.at(0) == '0'){
if(c->GetCarCount() >= MaxCars){
std::string Destroy = "Od:" + std::to_string(c->GetID()); ///to revise
SendToAll(c,Destroy,true,true);
c->DeleteCar(c->GetID());
}
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+Packet.substr(4);
c->AddNewCar(c->GetID(),Packet); ///revise later
}
SendToAll(nullptr,Packet,true,true);
break;
case 'd':
if(Data.find_first_not_of("0123456789") == std::string::npos){
ID = stoi(Data);
}
if(ID != -1 && ID == c->GetID()){
SendToAll(nullptr,Packet,true,true);
c->DeleteCar(c->GetID());
///std::cout << "Delete Requested from " << c->GetName() << std::endl;
}
break;
case 'm':
break;
case 'n':
if(Packet.substr(3).find_first_not_of("0123456789") == std::string::npos){
ID = stoi(Packet.substr(3));
}
FindAndSync(c,ID);
break;
case 'r':
SendToAll(c,Packet,false,true);
break;
}
}
void SyncVehicles(Client*c){
Respond(c,"Sn"+c->GetName(),true);
SendToAll(c,"JWelcome "+c->GetName()+"!",false,true);
for (Client*client : Clients) {
if (client != c) {
Respond(c,client->GetCarData(client->GetID()),true); ///revise later
}
}
}
void HTTP(Client*c){
if(!c->GetDID().empty()){
std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+c->GetDID(),443);
if(!a.empty()){
int pos = a.find('"');
c->SetRole(a.substr(pos+1,a.find('"',pos+1)-2));
if(Debug)debug("ROLE -> " + c->GetRole() + " ID -> " + c->GetDID());
}
}
}
void GrabRole(Client*c){
std::thread t1(HTTP,c);
t1.detach();
}
void GlobalParser(Client*c, const std::string&Packet){
if(Packet.empty())return;
if(Packet.find("TEST")!=std::string::npos)SyncVehicles(c);
char Code = Packet.at(0),SubCode = 0;
if(Packet.length() > 1)SubCode = Packet.at(1);
switch (Code) {
case 'P':
Respond(c, "P" + std::to_string(c->GetID()),true);
return;
case 'p':
Respond(c,"p",false);
UpdatePlayers();
return;
case 'N':
if(SubCode == 'R'){
c->SetName(Packet.substr(2,Packet.find(':')-2));
c->SetDID(Packet.substr(Packet.find(':')+1));
GrabRole(c);
}
std::cout << "Name : " << c->GetName() << std::endl;
return;
case 'O':
if(Packet.length() > 1000) {
std::cout << "Received data from: " << c->GetName() << " Size: " << Packet.length() << std::endl;
}
VehicleParser(c,Packet);
return;
case 'J':
SendToAll(c,Packet,false,true);
break;
case 'C':
SendToAll(nullptr,Packet,true,true);
break;
case 'E':
SendToAll(nullptr,Packet,true,true);
break;
}
//V to Z
if(Packet.length() > 1000){
std::cout << "Received data from: " << c->GetName() << " Size: " << Packet.length() << std::endl;
}
if(Code <= 90 && Code >= 86)SendToAll(c,Packet,false,false);
if(Debug)debug("Data : " + Packet);
}

View File

@ -0,0 +1,58 @@
///
/// Created by Anonymous275 on 5/9/2020
///
///TCP
#include "Client.hpp"
#include <iostream>
#include <thread>
void TCPSend(Client*c,const std::string&Data){
int BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.length())+1, 0);
if (BytesSent == 0){
std::cout << "(TCP) Connection closing..." << std::endl;
c->SetStatus(-1);
}
else if (BytesSent < 0) {
std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl;
closesocket(c->GetTCPSock());
c->SetStatus(-2);
}
}
void GlobalParser(Client*c, const std::string&Packet);
void TCPRcv(Client*c){
char buf[10240];
int len = 10240;
ZeroMemory(buf, len);
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
if (BytesRcv == 0){
std::cout << "(TCP) Connection closing..." << std::endl;
c->SetStatus(-1);
}
else if (BytesRcv < 0) {
std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl;
closesocket(c->GetTCPSock());
c->SetStatus(-2);
}
GlobalParser(c, std::string(buf));
}
void OnConnect(Client*c);
void OnDisconnect(Client*c,bool Timed);
void TCPClient(Client*client){
if(client->GetTCPSock() == -1)return;
std::cout << "Client connected" << std::endl;
OnConnect(client);
while (client->GetStatus() > -1){
TCPRcv(client);
}
//OnDisconnect
OnDisconnect(client, client->GetStatus() == -2);
std::cout << "Client Terminated" << std::endl;
}
void CreateNewThread(Client*client){
std::thread NewClient(TCPClient,client);
NewClient.detach();
}

View File

@ -0,0 +1,13 @@
#include "Client.hpp"
#include <thread>
void TCPServerMain();
void UDPServerMain();
std::set<Client*> Clients;
void NetMain() {
std::thread TCP(TCPServerMain);
TCP.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
UDPServerMain();
}

View File

@ -0,0 +1,85 @@
///
/// Created by Anonymous275 on 5/8/2020
///
///UDP
#include "Client.hpp"
#include <iostream>
#include <vector>
#include "../logger.h"
#include "../Settings.hpp"
SOCKET UDPSock;
void UDPSend(Client*c,const std::string&Data){
sockaddr_in Addr = c->GetUDPAddr();
int AddrSize = sizeof(c->GetUDPAddr());
int sendOk = sendto(UDPSock, Data.c_str(), int(Data.length()) + 1, 0, (sockaddr*)&Addr, AddrSize);
if (sendOk == SOCKET_ERROR)error("(UDP) Send Error! Code : " + std::to_string(WSAGetLastError()));
}
std::string UDPRcvFromClient(sockaddr_in& client){
char buf[4096];
int clientLength = sizeof(client);
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 4096);
int bytesIn = recvfrom(UDPSock, buf, 4096, 0, (sockaddr*)&client, &clientLength);
if (bytesIn == -1)
{
error("(UDP) Error receiving from Client! Code : " + std::to_string(WSAGetLastError()));
return "";
}
return std::string(buf);
}
void GlobalParser(Client*c, const std::string&Packet);
[[noreturn]] void UDPServerMain(){
WSADATA data;
if (WSAStartup(514, &data)) //2.2
{
std::cout << "Can't start Winsock!" << std::endl;
//return;
}
UDPSock = socket(AF_INET, SOCK_DGRAM, 0);
// Create a server hint structure for the server
sockaddr_in serverAddr{};
serverAddr.sin_addr.S_un.S_addr = ADDR_ANY; //Any Local
serverAddr.sin_family = AF_INET; // Address format is IPv4
serverAddr.sin_port = htons(Port); // Convert from little to big endian
// Try and bind the socket to the IP and port
if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cout << "Can't bind socket! " << WSAGetLastError() << std::endl;
//return;
}
info("Vehicle data network online on port "+std::to_string(Port)+" with a Max of "+std::to_string(MaxPlayers)+" Clients");
while (true)
{
sockaddr_in client{};
std::string Data = UDPRcvFromClient(client); //Receives any data from Socket
int Pos = Data.find(':');
if(Data.empty() || Pos < 0 || Pos > 2)continue;
/*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){
c->SetUDPAddr(client);
GlobalParser(c,Data.substr(2));
}
}
}
///UDPSendToClient(c->GetUDPAddr(), sizeof(c->GetUDPAddr()), Data);
/*closesocket(UDPSock);
WSACleanup();
return;*/
}

View File

@ -0,0 +1,64 @@
///
/// Created by Anonymous275 on 5/9/2020
///
///TCP
#include "Client.hpp"
#include <iostream>
#include <WS2tcpip.h>
#include "../logger.h"
#include "../Settings.hpp"
void CreateNewThread(Client*client);
void CreateClient(SOCKET TCPSock){
auto *client = new Client;
client->SetTCPSock(TCPSock);
Clients.insert(client);
CreateNewThread(client);
}
void TCPServerMain(){
WSADATA wsaData;
if (WSAStartup(514, &wsaData)) //2.2
{
std::cout << "Can't start Winsock!" << std::endl;
return;
}
SOCKET client,Listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in addr{};
addr.sin_addr.S_un.S_addr = ADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(Port);
if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "Can't bind socket! " << WSAGetLastError() << std::endl;
return;
}
if(Listener == -1)
{
printf("Invalid socket");
return;
}
if(listen(Listener,SOMAXCONN))
{
std::cout << "listener failed " << GetLastError();
return;
}
info("Vehicle event network online");
do{
client = accept(Listener, nullptr, nullptr);
if(client == -1)
{
std::cout << "invalid client socket" << std::endl;
continue;
}
if(Clients.size() < MaxPlayers)CreateClient(client);
}while(client);
closesocket(client);
WSACleanup();
}

View File

@ -1,54 +0,0 @@
///
/// Created by Anonymous275 on 2/4/2020.
///
#include <string>
#include "enet.hpp"
#include <thread>
#include "../logger.h"
#include "../Settings.hpp"
int FindID(ENetHost *server,ENetPeer*peer);
void Respond(const std::string& MSG, ENetPeer*peer){
enet_peer_send(peer, 0, enet_packet_create(MSG.c_str(), MSG.length() + 1, ENET_PACKET_FLAG_RELIABLE));
}
void SendToAll(ENetHost *server, ENetPeer*peer,const std::string& Data, bool All, bool Rel){
//std::cout << "Sending Code " << Data.at(0) << " length:" << Data.length() << " to all with the self switch : " << All << std::endl;
for (int i = 0; i < server->connectedPeers; i++) {
if (All || &server->peers[i] != peer) {
//reliable is 1 unreliable is 8
enet_peer_send(&server->peers[i], 0, enet_packet_create(Data.c_str(),Data.length()+1,Rel?1:8));
enet_host_flush(server);
}
}
}
void UpdatePlayers(ENetHost *server, ENetPeer*peer){
std::string Packet = "Ss" + std::to_string(server->connectedPeers)+"/"+std::to_string(MaxPlayers) + ":";
for (int i = 0; i < server->connectedPeers; i++) {
ENetPeer*SPeer = &server->peers[i];
Packet += SPeer->Name + ",";
}
Packet = Packet.substr(0,Packet.length()-1);
SendToAll(server,peer, Packet,true,true);
}
void OnDisconnect(ENetHost *server,ENetPeer*peer,bool Timed){
std::string Packet = "Od:" + std::to_string(peer->PlayerID);
SendToAll(server,peer, Packet,false,true);
if(Timed)Packet = "L"+peer->Name+" Timed out!";
else Packet = "L"+peer->Name+" Left the server!";
SendToAll(server,peer, Packet,false,true);
Packet.clear();
peer->DID.clear();
peer->Name.clear();
peer->VehicleData.clear();
}
void OnConnect(ENetHost *server,ENetPeer*peer){
Respond("NR",peer);
peer->PlayerID = FindID(server,peer); ///TODO: WHAT IF IT IS THE SECOND VEHICLE?
std::string ID = "P" + std::to_string(peer->PlayerID);
Respond(ID,peer);
if(Debug)debug(peer->Name + " ID : " + std::to_string(peer->PlayerID));
}

View File

@ -1,137 +0,0 @@
///
/// Created by Anonymous275 on 4/2/2020
///
#include <set>
#include <string>
#include <thread>
#include <iostream>
#include "enet.hpp"
#include "../logger.h"
#include "../Settings.hpp"
void SendToAll(ENetHost *server, ENetPeer*peer,const std::string& Data,bool All, bool Reliable);
std::string HTTP_REQUEST(const std::string& IP,int port);
void Respond(const std::string& MSG, ENetPeer*peer);
void UpdatePlayers(ENetHost *server, ENetPeer*peer);
void FindAndSync(ENetPeer*peer,ENetHost*server,int VehID){
ENetPeer*ENetClient;
for (int i = 0; i < server->connectedPeers; i++) {
ENetClient = &server->peers[i];
if (ENetClient != peer){
if(ENetClient->PlayerID == VehID){ /////mark
Respond(ENetClient->VehicleData,peer);
}
}
}
}
void VehicleParser(std::string Packet,ENetPeer*peer,ENetHost*server){
char Code = Packet.at(1);
int ID = -1;
std::string Data = Packet.substr(3);
switch(Code){ //Spawned Destroyed Switched/Moved NotFound Reset
case 's':
if(Data.at(0) == '0'){
Packet = "Os:"+peer->Role+":"+peer->Name+":"+std::to_string(peer->PlayerID)+Packet.substr(4);
peer->VehicleData = Packet;
}
SendToAll(server,peer,Packet,true,true);
break;
case 'd':
if(Packet.substr(3).find_first_not_of("0123456789") == std::string::npos){
ID = stoi(Packet.substr(3));
}
peer->VehicleData.clear();
if(ID != -1 && ID == peer->PlayerID){
SendToAll(server,peer,Packet,true,true);
}
break;
case 'm':
break;
case 'n':
if(Packet.substr(3).find_first_not_of("0123456789") == std::string::npos){
ID = stoi(Packet.substr(3));
}
FindAndSync(peer,server,ID);
break;
case 'r':
SendToAll(server,peer,Packet,false,true);
break;
}
}
void SyncVehicles(ENetHost*server,ENetPeer*peer){
ENetPeer*ENetClient;
for (int i = 0; i < server->connectedPeers; i++) {
ENetClient = &server->peers[i];
if (ENetClient != peer) {
if(!ENetClient->VehicleData.empty()){
enet_peer_send(peer, 0, enet_packet_create(ENetClient->VehicleData.c_str(),ENetClient->VehicleData.length()+1,1));
enet_host_flush(server);
}
}
}
}
void HTTP(ENetPeer*peer){
if(peer != nullptr && !peer->DID.empty()){
std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+peer->DID,443);
if(!a.empty()){
int pos = a.find('"');
peer->Role = a.substr(pos+1,a.find('"',pos+1)-2);
if(Debug)debug("ROLE -> " + peer->Role + " ID -> " + peer->DID);
}
}
}
void GrabRole(ENetPeer*peer){
std::thread t1(HTTP,peer);
t1.detach();
}
void ParseData(ENetPacket*packet, ENetPeer*peer, ENetHost*server){
std::string Packet = (char*)packet->data;
if(Packet.empty())return;
if(Packet.find("TEST")!=std::string::npos)SyncVehicles(server,peer);
char Code = Packet.at(0),SubCode = 0;
if(Packet.length() > 1)SubCode = Packet.at(1);
switch (Code) {
case 'p':
Respond("p",peer);
UpdatePlayers(server,peer);
return;
case 'N':
if(SubCode == 'R'){
peer->Name = Packet.substr(2,Packet.find(':')-2);
peer->DID = Packet.substr(Packet.find(':')+1);
Respond("Sn"+peer->Name,peer);
SendToAll(server,peer,"JWelcome "+peer->Name+"!",false,true);
GrabRole(peer);
}
std::cout << "Name : " << peer->Name << std::endl;
return;
case 'O':
if(Packet.length() > 1000) {
std::cout << "Received data from: " << peer->Name << " Size: " << Packet.length() << std::endl;
}
VehicleParser(Packet,peer,server);
return;
case 'J':
SendToAll(server,peer,Packet,false,true);
break;
case 'C':
SendToAll(server,peer,Packet, true,true);
break;
case 'E':
SendToAll(server,peer,Packet, true,true);
break;
}
//V to Z
if(Packet.length() > 1000){
std::cout << "Received data from: " << peer->Name << " Size: " << Packet.length() << std::endl;
}
if(Code <= 90 && Code >= 86)SendToAll(server,peer,Packet,false,false);
if(Debug)debug("Data : " + Packet);
}

View File

@ -1,161 +0,0 @@
///
/// Created by Anonymous275 on 4/2/2020
///
#define ENET_IMPLEMENTATION
#include <string>
#include "enet.hpp"
#include <cstdio>
#include "../logger.h"
#include "../Settings.hpp"
void ParseData(ENetPacket*packet,ENetPeer*peer,ENetHost *server);
void OnDisconnect(ENetHost *server,ENetPeer*peer,bool Timed);
void OnConnect(ENetHost *server,ENetPeer*peer);
ENetPacket* packet;
int PlayerCount = 0;
int FindID(ENetHost *server,ENetPeer*peer){
int OpenID = 1;
bool Found;
do {
Found = true;
for (int i = 0; i < server->connectedPeers; i++) {
if (&server->peers[i] != peer) {
if(server->peers[i].PlayerID == OpenID) {
Found = false;
OpenID++;
break;
}
}
}
}while (!Found);
return OpenID;
}
void host_server(ENetHost *server) {
ENetEvent event;
PlayerCount = server->connectedPeers;
while (enet_host_service(server, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT:
printf("A new client connected from %x:%u.\n", event.peer->address.host, event.peer->address.port);
//the data should be the client info could be name for now it's Client information
event.peer->Name = "Client information";
/*event.peer->gameVehicleID[0] = 0;
event.peer->serverVehicleID[0] = FindID(server, event.peer);*/
OnConnect(server,event.peer);
break;
case ENET_EVENT_TYPE_RECEIVE:
ParseData(event.packet,event.peer,server);
/*->dataLength,event.packet->data, (char *)event.peer->data, event.channelID*/ //We grab and Parse the Data
/* Clean up the packet now that we're done using it. */
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
std::cout << event.peer->Name << " disconnected." << std::endl;
OnDisconnect(server,event.peer,false);
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
std::cout << event.peer->Name << " timed out." << std::endl;
OnDisconnect(server,event.peer,true);
break;
case ENET_EVENT_TYPE_NONE: break;
}
}
}
void ServerMain(int Port, int MaxClients) {
if (enet_initialize() != 0) {
printf("An error occurred while initializing.\n");
return;
}
ENetHost *server;
ENetAddress address = {0};
address.host = ENET_HOST_ANY; //Bind the server to the default localhost.
address.port = Port; // Sets the port
//create a server
info("starting server with a maximum of " + to_string(MaxClients) + " Clients...");
server = enet_host_create(&address, MaxClients, 2, 0, 0);
if (server == nullptr) {
error("An error occurred while trying to create a server host.");
return;
}
info("Waiting for clients on port "+to_string(Port)+"...");
while (true) {
host_server(server);
}
enet_host_destroy(server);
enet_deinitialize();
return;
}
void CreateNewThread(void*);
void TCPMain(int Port){
info("Starting TCP Server on port " + to_string(Port));
WSADATA wsaData;
int iResult;
sockaddr_in addr{};
SOCKET sock,client;
addr.sin_family = AF_INET;
addr.sin_port = htons(Port);
iResult = WSAStartup(MAKEWORD(2,2),&wsaData);
if(iResult)
{
printf("WSA startup failed");
return;
}
sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock == INVALID_SOCKET)
{
printf("Invalid socket");
return;
}
iResult = bind(sock,(sockaddr*)&addr,sizeof(sockaddr_in ));
if(iResult)
{
printf("bind failed %lu",GetLastError());
return;
}
iResult = listen(sock,SOMAXCONN);
if(iResult)
{
printf("iResult failed %lu",GetLastError());
return;
}
while(client = accept(sock,nullptr,nullptr))
{
if(client == INVALID_SOCKET)
{
printf("invalid client socket\n");
continue;
}
CreateNewThread((void*)&client);
}
}

View File

@ -1,124 +0,0 @@
///
/// Created by Anonymous275 on 4/11/2020
///
#include <thread>
#include <string>
#include <fstream>
#include <iostream>
#include <WinSock2.h>
#include "../Settings.hpp"
int ParseAndSend(SOCKET Client, std::string Data){
std::string Response, Packet;
char ID = Data.at(0);
int Prev = 0,DataSent = 0, Size = 0;
bool FileSent = true;
switch (ID){
case 'a' :
Response = FileList+FileSizes;
if(Response.empty())Response = " ";
break;
case 'b' :
FileSent = false;
break;
case 'M' :
Response = MapName;
break;
}
std::string FLocation = Data.substr(1);
if(FileList.find(FLocation) == std::string::npos)return -1;
do {
if(!FileSent){
std::ifstream f;
f.open(FLocation.c_str(), std::ios::binary);
if(f.good()){
if(!Size){
Size = f.seekg(0, std::ios_base::end).tellg();
Response.resize(Size);
f.seekg(0, std::ios_base::beg);
f.read(&Response[0], Size);
f.close();
}else f.close();
if(DataSent != Size){
Packet.clear();
if((Size-DataSent) < 65535){
Packet = Response.substr(Prev,(Size-DataSent));
DataSent += (Size-DataSent);
Response.clear();
}else{
DataSent += 65535;
Packet = Response.substr(Prev,65535);
}
Prev = DataSent;
}else{
Size = 0;
DataSent = 0;
Prev = 0;
FileSent = true;
Packet.clear();
}
}else{
FileSent = true;
Response = "Cannot Open";
}
}
int iSendResult;
if(!Packet.empty())iSendResult = send(Client, Packet.c_str(), Packet.length(), 0);
else iSendResult = send(Client, Response.c_str(), Response.length(), 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(Client);
return -1;
}
}while(!FileSent);
return 0;
}
void Client(void* ClientData){
SOCKET Client = *(SOCKET*)ClientData;
printf("Client connected\n");
int iResult, iSendResult;
char recvbuf[65535];
int recvbuflen = 65535;
do {
iResult = recv(Client, recvbuf, recvbuflen, 0);
if (iResult > 0) {
//printf("Bytes received: %d\n", iResult);
std::string Data = recvbuf,Response;
Data.resize(iResult);
if(ParseAndSend(Client,Data) == -1)break;
// Echo the buffer back to the sender
/*iSendResult = send(Client, Response.c_str(), Response.length(), 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(Client);
return;
}
printf("Bytes sent: %d\n", iSendResult);*/
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(Client);
break;
}
} while (iResult > 0);
std::cout << "Client Closed" << std::endl;
}
void CreateNewThread(void* ClientData){
std::cout << "New Client" << std::endl;
std::thread NewClient(Client,ClientData);
NewClient.detach();
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,6 @@ extern bool Debug;
extern int MaxPlayers;
extern int Port;
extern int MaxCars;
extern int PlayerCount;
extern std::string MapName;
extern std::string ServerName;
extern std::string Resource;

View File

@ -4,10 +4,10 @@
#include <thread>
#include <iostream>
#include <string>
#include <chrono>
#include "logger.h"
#include "Settings.hpp"
#include "Network 2.0/Client.hpp"
using namespace std;
@ -16,11 +16,12 @@ void PostHTTP(const std::string& IP,const std::string& Fields);
void Heartbeat()
{
string UUID = HTTP_REQUEST("https://beamng-mp.com/new-server-startup",443);
std::string State = Private ? "true" : "false";
while(true)
{
PostHTTP("https://beamng-mp.com/heartbeat","uuid="+UUID+"&players="+to_string(PlayerCount)+"&maxplayers="+to_string(MaxPlayers)+"&port="
PostHTTP("https://beamng-mp.com/heartbeat","uuid="+UUID+"&players="+to_string(Clients.size())+"&maxplayers="+to_string(MaxPlayers)+"&port="
+ to_string(Port) + "&map=" + MapName + "&private="+State+"&version="+ServerVersion+"&clientversion="+ClientVersion+"&name="+ServerName);
std::this_thread::sleep_for (std::chrono::seconds(5));
}

View File

@ -15,12 +15,13 @@ void DebugData();
void LogInit();
void ParseConfig();
void addToLog(const string& Data);
void ServerMain(int Port, int MaxClients);
//void ServerMain(int Port, int MaxClients);
void HeartbeatInit();
string ServerVersion = "0.1";
string ClientVersion = "0.21";
void HandleResources(const std::string& path);
void TCPMain(int Port);
//void TCPMain(int Port);
void NetMain();
//Entry
int main() {
LogInit();
@ -29,9 +30,10 @@ int main() {
HeartbeatInit();
if(Debug)DebugData();
setLoggerLevel(0); //0 for all
std::thread TCPThread(TCPMain,Port);
TCPThread.detach();
ServerMain(Port, MaxPlayers);
/*std::thread TCPThread(TCPMain,Port);
TCPThread.detach();*/
//ServerMain(Port, MaxPlayers);
NetMain();
}