mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-04-12 18:56:20 +00:00
major refactor of Client and Server
this refactor includes changes to TClient: - all member fields are now public, but protected with Sync (an alias for boost::synchronized_value - removed all (now) obsolete getters and setters changes to TServer and TNetwork: - thread-safe ID generation, previously it was possible for there to be ID duplicates. this is now solved by moving id generation and assignment into the same mutex locked context. - deprecated ForEachClientWeak and replaced some usages of it with ForEachClient, getting rid of the weak_ptr shit in most places - implemented a bunch of new functions for getting rid of more weak_ptr everywhere
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
#include "BoostAliases.h"
|
||||
#include "Common.h"
|
||||
#include "Compat.h"
|
||||
#include "RWMutex.h"
|
||||
#include "Sync.h"
|
||||
#include "VehicleData.h"
|
||||
|
||||
class TServer;
|
||||
@@ -41,76 +43,47 @@ public:
|
||||
void AddNewCar(int Ident, const std::string& Data);
|
||||
void SetCarData(int Ident, const std::string& Data);
|
||||
void SetCarPosition(int Ident, const std::string& Data);
|
||||
TVehicleDataLockPair GetAllCars();
|
||||
void SetName(const std::string& Name) { mName = Name; }
|
||||
void SetRoles(const std::string& Role) { mRole = Role; }
|
||||
void SetIdentifier(const std::string& key, const std::string& value) { mIdentifiers[key] = value; }
|
||||
|
||||
void SetName(const std::string& NewName) { Name = NewName; }
|
||||
void SetRoles(const std::string& NewRole) { Role = NewRole; }
|
||||
void SetIdentifier(const std::string& key, const std::string& value);
|
||||
std::string GetCarData(int Ident);
|
||||
std::string GetCarPositionRaw(int Ident);
|
||||
void SetUDPAddr(const ip::udp::endpoint& Addr) { mUDPAddress = Addr; }
|
||||
void SetDownSock(ip::tcp::socket&& CSock) { mDownSocket = std::move(CSock); }
|
||||
void SetTCPSock(ip::tcp::socket&& CSock) { mSocket = std::move(CSock); }
|
||||
void Disconnect(std::string_view Reason);
|
||||
bool IsDisconnected() const { return !mSocket.is_open(); }
|
||||
bool IsDisconnected() const { return !TCPSocket->is_open(); }
|
||||
// locks
|
||||
void DeleteCar(int Ident);
|
||||
[[nodiscard]] const std::unordered_map<std::string, std::string>& GetIdentifiers() const { return mIdentifiers; }
|
||||
[[nodiscard]] const ip::udp::endpoint& GetUDPAddr() const { return mUDPAddress; }
|
||||
[[nodiscard]] ip::udp::endpoint& GetUDPAddr() { return mUDPAddress; }
|
||||
[[nodiscard]] ip::tcp::socket& GetDownSock() { return mDownSocket; }
|
||||
[[nodiscard]] const ip::tcp::socket& GetDownSock() const { return mDownSocket; }
|
||||
[[nodiscard]] ip::tcp::socket& GetTCPSock() { return mSocket; }
|
||||
[[nodiscard]] const ip::tcp::socket& GetTCPSock() const { return mSocket; }
|
||||
[[nodiscard]] std::string GetRoles() const { return mRole; }
|
||||
[[nodiscard]] std::string GetName() const { return mName; }
|
||||
void SetUnicycleID(int ID) { mUnicycleID = ID; }
|
||||
void SetID(int ID) { mID = ID; }
|
||||
[[nodiscard]] int GetOpenCarID() const;
|
||||
[[nodiscard]] int GetCarCount() const;
|
||||
void ClearCars();
|
||||
[[nodiscard]] int GetID() const { return mID; }
|
||||
[[nodiscard]] int GetUnicycleID() const { return mUnicycleID; }
|
||||
[[nodiscard]] bool IsConnected() const { return mIsConnected; }
|
||||
[[nodiscard]] bool IsSynced() const { return mIsSynced; }
|
||||
[[nodiscard]] bool IsSyncing() const { return mIsSyncing; }
|
||||
[[nodiscard]] bool IsGuest() const { return mIsGuest; }
|
||||
void SetIsGuest(bool NewIsGuest) { mIsGuest = NewIsGuest; }
|
||||
void SetIsSynced(bool NewIsSynced) { mIsSynced = NewIsSynced; }
|
||||
void SetIsSyncing(bool NewIsSyncing) { mIsSyncing = NewIsSyncing; }
|
||||
void EnqueuePacket(const std::vector<uint8_t>& Packet);
|
||||
[[nodiscard]] std::queue<std::vector<uint8_t>>& MissedPacketQueue() { return mPacketsSync; }
|
||||
[[nodiscard]] const std::queue<std::vector<uint8_t>>& MissedPacketQueue() const { return mPacketsSync; }
|
||||
[[nodiscard]] size_t MissedPacketQueueSize() const { return mPacketsSync.size(); }
|
||||
[[nodiscard]] std::mutex& MissedPacketQueueMutex() const { return mMissedPacketsMutex; }
|
||||
void SetIsConnected(bool NewIsConnected) { mIsConnected = NewIsConnected; }
|
||||
void SetIsConnected(bool NewIsConnected) { IsConnected = NewIsConnected; }
|
||||
[[nodiscard]] TServer& Server() const;
|
||||
void UpdatePingTime();
|
||||
int SecondsSinceLastPing();
|
||||
|
||||
Sync<bool> IsConnected = false;
|
||||
Sync<bool> IsSynced = false;
|
||||
Sync<bool> IsSyncing = false;
|
||||
Sync<std::unordered_map<std::string, std::string>> Identifiers;
|
||||
Sync<ip::tcp::socket> TCPSocket;
|
||||
Sync<ip::tcp::socket> DownSocket;
|
||||
Sync<ip::udp::endpoint> UDPAddress {};
|
||||
Sync<int> UnicycleID = -1;
|
||||
Sync<std::string> Role;
|
||||
Sync<std::string> DID;
|
||||
Sync<int> ID = -1;
|
||||
Sync<bool> IsGuest = false;
|
||||
Sync<std::string> Name = std::string("Unknown Client");
|
||||
Sync<TSetOfVehicleData> VehicleData;
|
||||
Sync<SparseArray<std::string>> VehiclePosition;
|
||||
Sync<std::queue<std::vector<uint8_t>>> MissedPacketsQueue;
|
||||
Sync<std::chrono::time_point<std::chrono::high_resolution_clock>> LastPingTime;
|
||||
|
||||
private:
|
||||
void InsertVehicle(int ID, const std::string& Data);
|
||||
|
||||
TServer& mServer;
|
||||
bool mIsConnected = false;
|
||||
bool mIsSynced = false;
|
||||
bool mIsSyncing = false;
|
||||
mutable std::mutex mMissedPacketsMutex;
|
||||
std::queue<std::vector<uint8_t>> mPacketsSync;
|
||||
std::unordered_map<std::string, std::string> mIdentifiers;
|
||||
bool mIsGuest = false;
|
||||
mutable std::mutex mVehicleDataMutex;
|
||||
mutable std::mutex mVehiclePositionMutex;
|
||||
TSetOfVehicleData mVehicleData;
|
||||
SparseArray<std::string> mVehiclePosition;
|
||||
std::string mName = "Unknown Client";
|
||||
ip::tcp::socket mSocket;
|
||||
ip::tcp::socket mDownSocket;
|
||||
ip::udp::endpoint mUDPAddress {};
|
||||
int mUnicycleID = -1;
|
||||
std::string mRole;
|
||||
std::string mDID;
|
||||
int mID = -1;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> mLastPingTime;
|
||||
};
|
||||
|
||||
std::optional<std::weak_ptr<TClient>> GetClient(class TServer& Server, int ID);
|
||||
std::optional<std::shared_ptr<TClient>> GetClient(class TServer& Server, int ID);
|
||||
|
||||
9
include/Sync.h
Normal file
9
include/Sync.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/thread/synchronized_value.hpp>
|
||||
|
||||
/// This header provides convenience aliases for synchronization primitives.
|
||||
|
||||
template<typename T>
|
||||
using Sync = boost::synchronized_value<T>;
|
||||
|
||||
@@ -220,6 +220,8 @@ private:
|
||||
// Debug functions, slow
|
||||
std::queue<std::pair<TLuaChunk, std::shared_ptr<TLuaResult>>> Debug_GetStateExecuteQueue();
|
||||
std::vector<TLuaEngine::QueuedFunction> Debug_GetStateFunctionQueue();
|
||||
|
||||
sol::table Lua_JsonDecode(const std::string& str);
|
||||
|
||||
private:
|
||||
sol::table Lua_TriggerGlobalEvent(const std::string& EventName, sol::variadic_args EventArgs);
|
||||
@@ -230,7 +232,6 @@ private:
|
||||
sol::table Lua_GetPlayerVehicles(int ID);
|
||||
std::pair<sol::table, std::string> Lua_GetPositionRaw(int PID, int VID);
|
||||
sol::table Lua_HttpCreateConnection(const std::string& host, uint16_t port);
|
||||
sol::table Lua_JsonDecode(const std::string& str);
|
||||
int Lua_GetPlayerIDByName(const std::string& Name);
|
||||
sol::table Lua_FS_ListFiles(const std::string& Path);
|
||||
sol::table Lua_FS_ListDirectories(const std::string& Path);
|
||||
|
||||
@@ -43,8 +43,9 @@ private:
|
||||
void OnConnect(const std::weak_ptr<TClient>& c);
|
||||
void TCPClient(const std::weak_ptr<TClient>& c);
|
||||
void Looper(const std::weak_ptr<TClient>& c);
|
||||
int OpenID();
|
||||
void OnDisconnect(const std::shared_ptr<TClient>& ClientPtr);
|
||||
void OnDisconnect(const std::weak_ptr<TClient>& ClientPtr);
|
||||
void OnDisconnect(TClient& Client);
|
||||
void Parse(TClient& c, const std::vector<uint8_t>& Packet);
|
||||
void SendFile(TClient& c, const std::string& Name);
|
||||
static bool TCPSendRaw(TClient& C, ip::tcp::socket& socket, const uint8_t* Data, size_t Size);
|
||||
|
||||
@@ -22,14 +22,19 @@ public:
|
||||
|
||||
void InsertClient(const std::shared_ptr<TClient>& Ptr);
|
||||
void RemoveClient(const std::weak_ptr<TClient>&);
|
||||
void RemoveClient(TClient&);
|
||||
// in Fn, return true to continue, return false to break
|
||||
void ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn);
|
||||
[[deprecated("Use ForEachClient instead")]] void ForEachClientWeak(const std::function<bool(std::weak_ptr<TClient>)>& Fn);
|
||||
void ForEachClient(const std::function<bool(const std::shared_ptr<TClient>&)> Fn);
|
||||
size_t ClientCount() const;
|
||||
|
||||
void GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uint8_t>&& Packet, TPPSMonitor& PPSMonitor, TNetwork& Network);
|
||||
static void HandleEvent(TClient& c, const std::string& Data);
|
||||
RWMutex& GetClientMutex() const { return mClientsMutex; }
|
||||
|
||||
// thread-safe ID lookup & claim
|
||||
void ClaimFreeIDFor(TClient& Client);
|
||||
|
||||
const TScopedTimer UptimeTimer;
|
||||
|
||||
// asio io context
|
||||
|
||||
Reference in New Issue
Block a user