mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-04-17 13:49:57 +00:00
Major rewrite of the network
This commit is contained in:
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
5911
src/Network/enet.hpp
5911
src/Network/enet.hpp
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 4/1/2020
|
||||
///
|
||||
|
||||
#include <vector>
|
||||
std::vector<std::string> Split(const std::string& String,const std::string& delimiter){
|
||||
std::vector<std::string> Val;
|
||||
size_t pos = 0;
|
||||
std::string token,s = String;
|
||||
while ((pos = s.find(delimiter)) != std::string::npos) {
|
||||
token = s.substr(0, pos);
|
||||
Val.push_back(token);
|
||||
s.erase(0, pos + delimiter.length());
|
||||
}
|
||||
Val.push_back(s);
|
||||
return Val;
|
||||
}
|
||||
Reference in New Issue
Block a user