mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-07-16 11:43:53 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3da0af37e4 | |||
| baa41dd65a | |||
| 534b457f48 | |||
| 029cf94e68 | |||
| 15f7a6ba85 | |||
| 86b5d91579 | |||
| 31486bcb56 | |||
| 08660d83dc | |||
| 6d8f75a577 | |||
| 018246cea5 | |||
| a584e25bf3 | |||
| d4d773b769 | |||
| 56a02f0215 | |||
| 7231c69e10 | |||
| 3c68dfaeaf |
@@ -1 +1 @@
|
|||||||
Copyright (c) 2019-present Anonymous275. BeamMP Server code is not in the public domain and is not free software. One must be granted explicit permission by the copyright holder in order to modify or distribute any part of the source or binaries, the only permission that has been granted is to use the software in its compiled form as distributed from the BeamMP.com website. Anything else is prohibited. Modified works may not be published and have be upstreamed to the official repository.
|
Copyright (c) 2019-present Anonymous275 (@Anonymous-275), Lion Kortlepel (@lionkor). BeamMP-Server code is not in the public domain and is not free software. One must be granted explicit permission by the copyright holder(s) in order to modify or distribute any part of the source or binaries. Special permission to modify the source-code is implicitly granted only for the purpose of upstreaming those changes directly to github.com/BeamMP/BeamMP-Server via a GitHub pull-request.
|
||||||
|
|||||||
+12
-6
@@ -14,10 +14,10 @@ class TServer;
|
|||||||
|
|
||||||
class TClient final {
|
class TClient final {
|
||||||
public:
|
public:
|
||||||
using TSetOfVehicleData = std::unordered_set<TVehicleData>;
|
using TSetOfVehicleData = std::vector<TVehicleData>;
|
||||||
|
|
||||||
struct TVehicleDataLockPair {
|
struct TVehicleDataLockPair {
|
||||||
TSetOfVehicleData& VehicleData;
|
TSetOfVehicleData* VehicleData;
|
||||||
std::unique_lock<std::mutex> Lock;
|
std::unique_lock<std::mutex> Lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
void SetDownSock(SOCKET CSock) { mSocket[1] = CSock; }
|
void SetDownSock(SOCKET CSock) { mSocket[1] = CSock; }
|
||||||
void SetTCPSock(SOCKET CSock) { mSocket[0] = CSock; }
|
void SetTCPSock(SOCKET CSock) { mSocket[0] = CSock; }
|
||||||
void SetStatus(int Status) { mStatus = Status; }
|
void SetStatus(int Status) { mStatus = Status; }
|
||||||
|
// locks
|
||||||
void DeleteCar(int Ident);
|
void DeleteCar(int Ident);
|
||||||
[[nodiscard]] std::set<std::string> GetIdentifiers() const { return mIdentifiers; }
|
[[nodiscard]] std::set<std::string> GetIdentifiers() const { return mIdentifiers; }
|
||||||
[[nodiscard]] sockaddr_in GetUDPAddr() const { return mUDPAddress; }
|
[[nodiscard]] sockaddr_in GetUDPAddr() const { return mUDPAddress; }
|
||||||
@@ -43,12 +44,14 @@ public:
|
|||||||
[[nodiscard]] SOCKET GetTCPSock() const { return mSocket[0]; }
|
[[nodiscard]] SOCKET GetTCPSock() const { return mSocket[0]; }
|
||||||
[[nodiscard]] std::string GetRoles() const { return mRole; }
|
[[nodiscard]] std::string GetRoles() const { return mRole; }
|
||||||
[[nodiscard]] std::string GetName() const { return mName; }
|
[[nodiscard]] std::string GetName() const { return mName; }
|
||||||
|
void SetUnicycleID(int ID) { mUnicycleID = ID; }
|
||||||
void SetID(int ID) { mID = ID; }
|
void SetID(int ID) { mID = ID; }
|
||||||
[[nodiscard]] int GetOpenCarID() const;
|
[[nodiscard]] int GetOpenCarID() const;
|
||||||
[[nodiscard]] int GetCarCount() const;
|
[[nodiscard]] int GetCarCount() const;
|
||||||
void ClearCars();
|
void ClearCars();
|
||||||
[[nodiscard]] int GetStatus() const { return mStatus; }
|
[[nodiscard]] int GetStatus() const { return mStatus; }
|
||||||
[[nodiscard]] int GetID() const { return mID; }
|
[[nodiscard]] int GetID() const { return mID; }
|
||||||
|
[[nodiscard]] int GetUnicycleID() const { return mUnicycleID; }
|
||||||
[[nodiscard]] bool IsConnected() const { return mIsConnected; }
|
[[nodiscard]] bool IsConnected() const { return mIsConnected; }
|
||||||
[[nodiscard]] bool IsSynced() const { return mIsSynced; }
|
[[nodiscard]] bool IsSynced() const { return mIsSynced; }
|
||||||
[[nodiscard]] bool IsSyncing() const { return mIsSyncing; }
|
[[nodiscard]] bool IsSyncing() const { return mIsSyncing; }
|
||||||
@@ -57,9 +60,9 @@ public:
|
|||||||
void SetIsSynced(bool NewIsSynced) { mIsSynced = NewIsSynced; }
|
void SetIsSynced(bool NewIsSynced) { mIsSynced = NewIsSynced; }
|
||||||
void SetIsSyncing(bool NewIsSyncing) { mIsSyncing = NewIsSyncing; }
|
void SetIsSyncing(bool NewIsSyncing) { mIsSyncing = NewIsSyncing; }
|
||||||
void EnqueuePacket(const std::string& Packet);
|
void EnqueuePacket(const std::string& Packet);
|
||||||
[[nodiscard]] std::queue<std::string>& MissedPacketQueue() { return mMissedPacketsDuringSyncing; }
|
[[nodiscard]] std::queue<std::string>& MissedPacketQueue() { return mPacketsSync; }
|
||||||
[[nodiscard]] const std::queue<std::string>& MissedPacketQueue() const { return mMissedPacketsDuringSyncing; }
|
[[nodiscard]] const std::queue<std::string>& MissedPacketQueue() const { return mPacketsSync; }
|
||||||
[[nodiscard]] size_t MissedPacketQueueSize() const { return mMissedPacketsDuringSyncing.size(); }
|
[[nodiscard]] size_t MissedPacketQueueSize() const { return mPacketsSync.size(); }
|
||||||
[[nodiscard]] std::mutex& MissedPacketQueueMutex() const { return mMissedPacketsMutex; }
|
[[nodiscard]] std::mutex& MissedPacketQueueMutex() const { return mMissedPacketsMutex; }
|
||||||
void SetIsConnected(bool NewIsConnected) { mIsConnected = NewIsConnected; }
|
void SetIsConnected(bool NewIsConnected) { mIsConnected = NewIsConnected; }
|
||||||
[[nodiscard]] TServer& Server() const;
|
[[nodiscard]] TServer& Server() const;
|
||||||
@@ -67,12 +70,14 @@ public:
|
|||||||
int SecondsSinceLastPing();
|
int SecondsSinceLastPing();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void InsertVehicle(int ID, const std::string& Data);
|
||||||
|
|
||||||
TServer& mServer;
|
TServer& mServer;
|
||||||
bool mIsConnected = false;
|
bool mIsConnected = false;
|
||||||
bool mIsSynced = false;
|
bool mIsSynced = false;
|
||||||
bool mIsSyncing = false;
|
bool mIsSyncing = false;
|
||||||
mutable std::mutex mMissedPacketsMutex;
|
mutable std::mutex mMissedPacketsMutex;
|
||||||
std::queue<std::string> mMissedPacketsDuringSyncing;
|
std::queue<std::string> mPacketsSync;
|
||||||
std::set<std::string> mIdentifiers;
|
std::set<std::string> mIdentifiers;
|
||||||
bool mIsGuest = false;
|
bool mIsGuest = false;
|
||||||
std::mutex mVehicleDataMutex;
|
std::mutex mVehicleDataMutex;
|
||||||
@@ -80,6 +85,7 @@ private:
|
|||||||
std::string mName = "Unknown Client";
|
std::string mName = "Unknown Client";
|
||||||
SOCKET mSocket[2] { SOCKET(-1) };
|
SOCKET mSocket[2] { SOCKET(-1) };
|
||||||
sockaddr_in mUDPAddress {}; // is this initialization OK? yes it is
|
sockaddr_in mUDPAddress {}; // is this initialization OK? yes it is
|
||||||
|
int mUnicycleID = -1;
|
||||||
std::string mRole;
|
std::string mRole;
|
||||||
std::string mDID;
|
std::string mDID;
|
||||||
int mStatus = 0;
|
int mStatus = 0;
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public:
|
|||||||
// Causes all threads to finish up and exit gracefull gracefully
|
// Causes all threads to finish up and exit gracefull gracefully
|
||||||
static void GracefullyShutdown();
|
static void GracefullyShutdown();
|
||||||
static TConsole& Console() { return *mConsole; }
|
static TConsole& Console() { return *mConsole; }
|
||||||
static std::string ServerVersion() { return "2.0.1"; }
|
static std::string ServerVersion() { return "2.0.2"; }
|
||||||
static std::string ClientVersion() { return "2.0"; }
|
static std::string ClientVersion() { return "2.0"; }
|
||||||
static std::string PPS() { return mPPS; }
|
static std::string PPS() { return mPPS; }
|
||||||
static void SetPPS(std::string NewPPS) { mPPS = NewPPS; }
|
static void SetPPS(std::string NewPPS) { mPPS = NewPPS; }
|
||||||
|
|||||||
@@ -31,5 +31,7 @@ private:
|
|||||||
TClientSet mClients;
|
TClientSet mClients;
|
||||||
mutable RWMutex mClientsMutex;
|
mutable RWMutex mClientsMutex;
|
||||||
static void ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network);
|
static void ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network);
|
||||||
|
static bool ShouldSpawn(TClient& c, const std::string& CarJson, int ID);
|
||||||
|
static bool IsUnicycle(TClient& c, const std::string& CarJson);
|
||||||
static void Apply(TClient& c, int VID, const std::string& pckt);
|
static void Apply(TClient& c, int VID, const std::string& pckt);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,20 +6,25 @@ class TVehicleData final {
|
|||||||
public:
|
public:
|
||||||
TVehicleData(int ID, std::string Data);
|
TVehicleData(int ID, std::string Data);
|
||||||
~TVehicleData();
|
~TVehicleData();
|
||||||
|
// We cannot delete this, since vector needs to be able to copy when it resizes.
|
||||||
|
// Deleting this causes some wacky template errors which are hard to decipher,
|
||||||
|
// and end up making no sense, so let's just leave the copy ctor.
|
||||||
|
// TVehicleData(const TVehicleData&) = delete;
|
||||||
|
|
||||||
[[nodiscard]] bool IsInvalid() const { return mID == -1; }
|
[[nodiscard]] bool IsInvalid() const { return mID == -1; }
|
||||||
[[nodiscard]] int ID() const { return mID; }
|
[[nodiscard]] int ID() const { return mID; }
|
||||||
|
|
||||||
[[nodiscard]] std::string Data() const { return mData; }
|
[[nodiscard]] std::string Data() const { return mData; }
|
||||||
void SetData(const std::string& Data) const { mData = Data; }
|
void SetData(const std::string& Data) { mData = Data; }
|
||||||
|
|
||||||
bool operator==(const TVehicleData& v) const { return mID == v.mID; }
|
bool operator==(const TVehicleData& v) const { return mID == v.mID; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mID { -1 };
|
int mID { -1 };
|
||||||
mutable std::string mData;
|
std::string mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: unused now, remove?
|
||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
struct hash<TVehicleData> {
|
struct hash<TVehicleData> {
|
||||||
|
|||||||
+28
-17
@@ -6,15 +6,19 @@
|
|||||||
// FIXME: add debug prints
|
// FIXME: add debug prints
|
||||||
|
|
||||||
void TClient::DeleteCar(int Ident) {
|
void TClient::DeleteCar(int Ident) {
|
||||||
for (auto& v : mVehicleData) {
|
std::unique_lock lock(mVehicleDataMutex);
|
||||||
if (v.ID() == Ident) {
|
auto iter = std::find_if(mVehicleData.begin(), mVehicleData.end(), [&](auto& elem) {
|
||||||
mVehicleData.erase(v);
|
return Ident == elem.ID();
|
||||||
break;
|
});
|
||||||
}
|
if (iter != mVehicleData.end()) {
|
||||||
|
mVehicleData.erase(iter);
|
||||||
|
} else {
|
||||||
|
debug("tried to erase a vehicle that doesn't exist (not an error)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TClient::ClearCars() {
|
void TClient::ClearCars() {
|
||||||
|
std::unique_lock lock(mVehicleDataMutex);
|
||||||
mVehicleData.clear();
|
mVehicleData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,30 +38,37 @@ int TClient::GetOpenCarID() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TClient::AddNewCar(int Ident, const std::string& Data) {
|
void TClient::AddNewCar(int Ident, const std::string& Data) {
|
||||||
mVehicleData.emplace(Ident, Data);
|
std::unique_lock lock(mVehicleDataMutex);
|
||||||
|
mVehicleData.emplace_back(Ident, Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
TClient::TVehicleDataLockPair TClient::GetAllCars() {
|
TClient::TVehicleDataLockPair TClient::GetAllCars() {
|
||||||
return { mVehicleData, std::unique_lock(mVehicleDataMutex) };
|
return { &mVehicleData, std::unique_lock(mVehicleDataMutex) };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TClient::GetCarData(int Ident) {
|
std::string TClient::GetCarData(int Ident) {
|
||||||
for (auto& v : mVehicleData) {
|
{ // lock
|
||||||
if (v.ID() == Ident) {
|
std::unique_lock lock(mVehicleDataMutex);
|
||||||
return v.Data();
|
for (auto& v : mVehicleData) {
|
||||||
|
if (v.ID() == Ident) {
|
||||||
|
return v.Data();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} // unlock
|
||||||
DeleteCar(Ident);
|
DeleteCar(Ident);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void TClient::SetCarData(int Ident, const std::string& Data) {
|
void TClient::SetCarData(int Ident, const std::string& Data) {
|
||||||
for (auto& v : mVehicleData) {
|
{ // lock
|
||||||
if (v.ID() == Ident) {
|
std::unique_lock lock(mVehicleDataMutex);
|
||||||
v.SetData(Data);
|
for (auto& v : mVehicleData) {
|
||||||
return;
|
if (v.ID() == Ident) {
|
||||||
|
v.SetData(Data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} // unlock
|
||||||
DeleteCar(Ident);
|
DeleteCar(Ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +82,7 @@ TServer& TClient::Server() const {
|
|||||||
|
|
||||||
void TClient::EnqueuePacket(const std::string& Packet) {
|
void TClient::EnqueuePacket(const std::string& Packet) {
|
||||||
std::unique_lock Lock(mMissedPacketsMutex);
|
std::unique_lock Lock(mMissedPacketsMutex);
|
||||||
mMissedPacketsDuringSyncing.push(Packet);
|
mPacketsSync.push(Packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
TClient::TClient(TServer& Server)
|
TClient::TClient(TServer& Server)
|
||||||
|
|||||||
+1
-1
@@ -342,7 +342,7 @@ int lua_GetCars(lua_State* L) {
|
|||||||
TClient::TSetOfVehicleData VehicleData;
|
TClient::TSetOfVehicleData VehicleData;
|
||||||
{ // Vehicle Data Lock Scope
|
{ // Vehicle Data Lock Scope
|
||||||
auto LockedData = Client->GetAllCars();
|
auto LockedData = Client->GetAllCars();
|
||||||
VehicleData = LockedData.VehicleData;
|
VehicleData = *LockedData.VehicleData;
|
||||||
} // End Vehicle Data Lock Scope
|
} // End Vehicle Data Lock Scope
|
||||||
if (VehicleData.empty())
|
if (VehicleData.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+21
-17
@@ -88,11 +88,11 @@ void TNetwork::UDPServerMain() {
|
|||||||
ReadLock Lock(mServer.GetClientMutex());
|
ReadLock Lock(mServer.GetClientMutex());
|
||||||
if (!ClientPtr.expired()) {
|
if (!ClientPtr.expired()) {
|
||||||
Client = ClientPtr.lock();
|
Client = ClientPtr.lock();
|
||||||
}else return true;
|
} else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Client->GetID() == ID) {
|
if (Client->GetID() == ID) {
|
||||||
Client->UpdatePingTime();
|
|
||||||
Client->SetUDPAddr(client);
|
Client->SetUDPAddr(client);
|
||||||
Client->SetIsConnected(true);
|
Client->SetIsConnected(true);
|
||||||
TServer::GlobalParser(ClientPtr, Data.substr(2), mPPSMonitor, *this);
|
TServer::GlobalParser(ClientPtr, Data.substr(2), mPPSMonitor, *this);
|
||||||
@@ -312,7 +312,8 @@ void TNetwork::Authentication(SOCKET TCPSock) {
|
|||||||
ReadLock Lock(mServer.GetClientMutex());
|
ReadLock Lock(mServer.GetClientMutex());
|
||||||
if (!ClientPtr.expired()) {
|
if (!ClientPtr.expired()) {
|
||||||
Cl = ClientPtr.lock();
|
Cl = ClientPtr.lock();
|
||||||
} else return true;
|
} else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
info("Client Iteration: Name -> " + Cl->GetName() + ", Guest -> " + std::to_string(Cl->IsGuest()) + ", Roles -> " + Cl->GetRoles());
|
info("Client Iteration: Name -> " + Cl->GetName() + ", Guest -> " + std::to_string(Cl->IsGuest()) + ", Roles -> " + Cl->GetRoles());
|
||||||
if (Cl->GetName() == Client->GetName() && Cl->IsGuest() == Client->IsGuest()) {
|
if (Cl->GetName() == Client->GetName() && Cl->IsGuest() == Client->IsGuest()) {
|
||||||
@@ -354,8 +355,7 @@ std::shared_ptr<TClient> TNetwork::CreateClient(SOCKET TCPSock) {
|
|||||||
bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
||||||
if (!IsSync) {
|
if (!IsSync) {
|
||||||
if (c.IsSyncing()) {
|
if (c.IsSyncing()) {
|
||||||
//std::unique_lock Lock(c.MissedPacketQueueMutex());
|
if (!Data.empty()) {
|
||||||
if(!Data.empty()) {
|
|
||||||
if (Data.at(0) == 'O' || Data.at(0) == 'A' || Data.at(0) == 'C' || Data.at(0) == 'E') {
|
if (Data.at(0) == 'O' || Data.at(0) == 'A' || Data.at(0) == 'C' || Data.at(0) == 'E') {
|
||||||
c.EnqueuePacket(Data);
|
c.EnqueuePacket(Data);
|
||||||
}
|
}
|
||||||
@@ -364,7 +364,6 @@ bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t Size, Sent;
|
int32_t Size, Sent;
|
||||||
std::string Send(4, 0);
|
std::string Send(4, 0);
|
||||||
Size = int32_t(Data.size());
|
Size = int32_t(Data.size());
|
||||||
@@ -392,6 +391,7 @@ bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
|||||||
}
|
}
|
||||||
Sent += Temp;
|
Sent += Temp;
|
||||||
} while (Sent < Size);
|
} while (Sent < Size);
|
||||||
|
c.UpdatePingTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,8 +488,8 @@ void TNetwork::ClientKick(TClient& c, const std::string& R) {
|
|||||||
c.SetStatus(-2);
|
c.SetStatus(-2);
|
||||||
CloseSocketProper(c.GetTCPSock());
|
CloseSocketProper(c.GetTCPSock());
|
||||||
}
|
}
|
||||||
void TNetwork::Looper(const std::weak_ptr<TClient>& c){
|
void TNetwork::Looper(const std::weak_ptr<TClient>& c) {
|
||||||
while(!c.expired()) {
|
while (!c.expired()) {
|
||||||
auto Client = c.lock();
|
auto Client = c.lock();
|
||||||
if (Client->GetStatus() < 0) {
|
if (Client->GetStatus() < 0) {
|
||||||
debug("client status < 0, breaking client loop");
|
debug("client status < 0, breaking client loop");
|
||||||
@@ -521,7 +521,7 @@ void TNetwork::Looper(const std::weak_ptr<TClient>& c){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,7 +535,7 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
|
|||||||
OnConnect(c);
|
OnConnect(c);
|
||||||
RegisterThread("(" + std::to_string(c.lock()->GetID()) + ") \"" + c.lock()->GetName() + "\"");
|
RegisterThread("(" + std::to_string(c.lock()->GetID()) + ") \"" + c.lock()->GetName() + "\"");
|
||||||
|
|
||||||
std::thread QueueSync(&TNetwork::Looper, this ,c);
|
std::thread QueueSync(&TNetwork::Looper, this, c);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (c.expired())
|
if (c.expired())
|
||||||
@@ -553,7 +553,8 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
|
|||||||
}
|
}
|
||||||
TServer::GlobalParser(c, res, mPPSMonitor, *this);
|
TServer::GlobalParser(c, res, mPPSMonitor, *this);
|
||||||
}
|
}
|
||||||
if(QueueSync.joinable())QueueSync.join();
|
if (QueueSync.joinable())
|
||||||
|
QueueSync.join();
|
||||||
|
|
||||||
if (!c.expired()) {
|
if (!c.expired()) {
|
||||||
auto Client = c.lock();
|
auto Client = c.lock();
|
||||||
@@ -574,7 +575,8 @@ void TNetwork::UpdatePlayer(TClient& Client) {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
Packet = Packet.substr(0, Packet.length() - 1);
|
Packet = Packet.substr(0, Packet.length() - 1);
|
||||||
(void)Respond(Client, Packet, true);
|
Client.EnqueuePacket(Packet);
|
||||||
|
//(void)Respond(Client, Packet, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TNetwork::OnDisconnect(const std::weak_ptr<TClient>& ClientPtr, bool kicked) {
|
void TNetwork::OnDisconnect(const std::weak_ptr<TClient>& ClientPtr, bool kicked) {
|
||||||
@@ -586,7 +588,7 @@ void TNetwork::OnDisconnect(const std::weak_ptr<TClient>& ClientPtr, bool kicked
|
|||||||
TClient::TSetOfVehicleData VehicleData;
|
TClient::TSetOfVehicleData VehicleData;
|
||||||
{ // Vehicle Data Lock Scope
|
{ // Vehicle Data Lock Scope
|
||||||
auto LockedData = c.GetAllCars();
|
auto LockedData = c.GetAllCars();
|
||||||
VehicleData = LockedData.VehicleData;
|
VehicleData = *LockedData.VehicleData;
|
||||||
} // End Vehicle Data Lock Scope
|
} // End Vehicle Data Lock Scope
|
||||||
for (auto& v : VehicleData) {
|
for (auto& v : VehicleData) {
|
||||||
Packet = "Od:" + std::to_string(c.GetID()) + "-" + std::to_string(v.ID());
|
Packet = "Od:" + std::to_string(c.GetID()) + "-" + std::to_string(v.ID());
|
||||||
@@ -836,12 +838,13 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& c) {
|
|||||||
ReadLock Lock(mServer.GetClientMutex());
|
ReadLock Lock(mServer.GetClientMutex());
|
||||||
if (!ClientPtr.expired()) {
|
if (!ClientPtr.expired()) {
|
||||||
client = ClientPtr.lock();
|
client = ClientPtr.lock();
|
||||||
} else return true;
|
} else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
TClient::TSetOfVehicleData VehicleData;
|
TClient::TSetOfVehicleData VehicleData;
|
||||||
{ // Vehicle Data Lock Scope
|
{ // Vehicle Data Lock Scope
|
||||||
auto LockedData = client->GetAllCars();
|
auto LockedData = client->GetAllCars();
|
||||||
VehicleData = LockedData.VehicleData;
|
VehicleData = *LockedData.VehicleData;
|
||||||
} // End Vehicle Data Lock Scope
|
} // End Vehicle Data Lock Scope
|
||||||
if (client != LockedClient) {
|
if (client != LockedClient) {
|
||||||
for (auto& v : VehicleData) {
|
for (auto& v : VehicleData) {
|
||||||
@@ -877,7 +880,8 @@ void TNetwork::SendToAll(TClient* c, const std::string& Data, bool Self, bool Re
|
|||||||
ReadLock Lock(mServer.GetClientMutex());
|
ReadLock Lock(mServer.GetClientMutex());
|
||||||
if (!ClientPtr.expired()) {
|
if (!ClientPtr.expired()) {
|
||||||
Client = ClientPtr.lock();
|
Client = ClientPtr.lock();
|
||||||
}else return true;
|
} else
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (Self || Client.get() != c) {
|
if (Self || Client.get() != c) {
|
||||||
if (Client->IsSynced() || Client->IsSyncing()) {
|
if (Client->IsSynced() || Client->IsSyncing()) {
|
||||||
@@ -886,7 +890,7 @@ void TNetwork::SendToAll(TClient* c, const std::string& Data, bool Self, bool Re
|
|||||||
if (Data.length() > 400) {
|
if (Data.length() > 400) {
|
||||||
std::string CMP(Comp(Data));
|
std::string CMP(Comp(Data));
|
||||||
Client->EnqueuePacket("ABG:" + CMP);
|
Client->EnqueuePacket("ABG:" + CMP);
|
||||||
}else{
|
} else {
|
||||||
Client->EnqueuePacket(Data);
|
Client->EnqueuePacket(Data);
|
||||||
}
|
}
|
||||||
//ret = SendLarge(*Client, Data);
|
//ret = SendLarge(*Client, Data);
|
||||||
|
|||||||
+2
-2
@@ -46,7 +46,7 @@ void TPPSMonitor::operator()() {
|
|||||||
c->UpdatePingTime();
|
c->UpdatePingTime();
|
||||||
}
|
}
|
||||||
// kick on "no ping"
|
// kick on "no ping"
|
||||||
if (c->SecondsSinceLastPing() > 60 && c->IsSynced() && !c->IsSyncing()) {
|
if (c->SecondsSinceLastPing() > 30 && c->IsSynced() && !c->IsSyncing()) {
|
||||||
debug("client " + std::string("(") + std::to_string(c->GetID()) + ")" + c->GetName() + " timing out: " + std::to_string(c->SecondsSinceLastPing()) + ", pps: " + Application::PPS());
|
debug("client " + std::string("(") + std::to_string(c->GetID()) + ")" + c->GetName() + " timing out: " + std::to_string(c->SecondsSinceLastPing()) + ", pps: " + Application::PPS());
|
||||||
TimedOutClients.push_back(c);
|
TimedOutClients.push_back(c);
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ void TPPSMonitor::operator()() {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
for (auto& ClientToKick : TimedOutClients) {
|
for (auto& ClientToKick : TimedOutClients) {
|
||||||
Network().ClientKick(*ClientToKick, "Timeout (no ping for >60 seconds)");
|
Network().ClientKick(*ClientToKick, "Timeout (no ping for >30 seconds)");
|
||||||
}
|
}
|
||||||
TimedOutClients.clear();
|
TimedOutClients.clear();
|
||||||
if (C == 0 || mInternalPPS == 0) {
|
if (C == 0 || mInternalPPS == 0) {
|
||||||
|
|||||||
+41
-7
@@ -108,7 +108,6 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::string Pac
|
|||||||
} else {
|
} else {
|
||||||
Network.UpdatePlayer(*LockedClient);
|
Network.UpdatePlayer(*LockedClient);
|
||||||
}
|
}
|
||||||
LockedClient->UpdatePingTime();
|
|
||||||
return;
|
return;
|
||||||
case 'O':
|
case 'O':
|
||||||
if (Packet.length() > 1000) {
|
if (Packet.length() > 1000) {
|
||||||
@@ -164,6 +163,29 @@ void TServer::HandleEvent(TClient& c, const std::string& Data) {
|
|||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool TServer::IsUnicycle(TClient &c, const std::string &CarJson) {
|
||||||
|
rapidjson::Document Car;
|
||||||
|
Car.Parse(CarJson.c_str(), CarJson.size());
|
||||||
|
if(Car.HasParseError()){
|
||||||
|
error("Failed to parse vehicle data -> " + CarJson);
|
||||||
|
} else if (Car["jbm"].IsString() && std::string(Car["jbm"].GetString()) == "unicycle") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool TServer::ShouldSpawn(TClient& c, const std::string& CarJson, int ID) {
|
||||||
|
|
||||||
|
if(c.GetUnicycleID() > -1 && (c.GetCarCount() - 1) < Application::Settings.MaxCars){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsUnicycle(c,CarJson)){
|
||||||
|
c.SetUnicycleID(ID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Application::Settings.MaxCars > c.GetCarCount();
|
||||||
|
}
|
||||||
|
|
||||||
void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network) {
|
void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Network) {
|
||||||
if (Pckt.length() < 4)
|
if (Pckt.length() < 4)
|
||||||
@@ -181,9 +203,15 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
|||||||
if (Data.at(0) == '0') {
|
if (Data.at(0) == '0') {
|
||||||
int CarID = c.GetOpenCarID();
|
int CarID = c.GetOpenCarID();
|
||||||
debug(c.GetName() + (" created a car with ID ") + std::to_string(CarID));
|
debug(c.GetName() + (" created a car with ID ") + std::to_string(CarID));
|
||||||
Packet = "Os:" + c.GetRoles() + ":" + c.GetName() + ":" + std::to_string(c.GetID()) + "-" + std::to_string(CarID) + Packet.substr(4);
|
|
||||||
|
std::string CarJson = Packet.substr(5);
|
||||||
|
Packet = "Os:" + c.GetRoles() + ":" + c.GetName() + ":" + std::to_string(c.GetID()) + "-" + std::to_string(CarID) + ":" + CarJson;
|
||||||
auto Res = TriggerLuaEvent(("onVehicleSpawn"), false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), CarID, Packet.substr(3) } }), true);
|
auto Res = TriggerLuaEvent(("onVehicleSpawn"), false, nullptr, std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), CarID, Packet.substr(3) } }), true);
|
||||||
if (c.GetCarCount() >= Application::Settings.MaxCars || std::any_cast<int>(Res)) {
|
|
||||||
|
if (ShouldSpawn(c, CarJson, CarID) && std::any_cast<int>(Res) == 0) {
|
||||||
|
c.AddNewCar(CarID, Packet);
|
||||||
|
Network.SendToAll(nullptr, Packet, true, true);
|
||||||
|
} else {
|
||||||
if (!Network.Respond(c, Packet, true)) {
|
if (!Network.Respond(c, Packet, true)) {
|
||||||
// TODO: handle
|
// TODO: handle
|
||||||
}
|
}
|
||||||
@@ -192,9 +220,6 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
|||||||
// TODO: handle
|
// TODO: handle
|
||||||
}
|
}
|
||||||
debug(c.GetName() + (" (force : car limit/lua) removed ID ") + std::to_string(CarID));
|
debug(c.GetName() + (" (force : car limit/lua) removed ID ") + std::to_string(CarID));
|
||||||
} else {
|
|
||||||
c.AddNewCar(CarID, Packet);
|
|
||||||
Network.SendToAll(nullptr, Packet, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -212,10 +237,15 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
|||||||
auto Res = TriggerLuaEvent(("onVehicleEdited"), false, nullptr,
|
auto Res = TriggerLuaEvent(("onVehicleEdited"), false, nullptr,
|
||||||
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID, Packet.substr(3) } }),
|
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID, Packet.substr(3) } }),
|
||||||
true);
|
true);
|
||||||
if (!std::any_cast<int>(Res)) {
|
|
||||||
|
if ((c.GetUnicycleID() != VID || IsUnicycle(c,Packet.substr(Packet.find('{'))))
|
||||||
|
&& std::any_cast<int>(Res) == 0) {
|
||||||
Network.SendToAll(&c, Packet, false, true);
|
Network.SendToAll(&c, Packet, false, true);
|
||||||
Apply(c, VID, Packet);
|
Apply(c, VID, Packet);
|
||||||
} else {
|
} else {
|
||||||
|
if(c.GetUnicycleID() == VID){
|
||||||
|
c.SetUnicycleID(-1);
|
||||||
|
}
|
||||||
std::string Destroy = "Od:" + std::to_string(c.GetID()) + "-" + std::to_string(VID);
|
std::string Destroy = "Od:" + std::to_string(c.GetID()) + "-" + std::to_string(VID);
|
||||||
if (!Network.Respond(c, Destroy, true)) {
|
if (!Network.Respond(c, Destroy, true)) {
|
||||||
// TODO: handle
|
// TODO: handle
|
||||||
@@ -235,6 +265,9 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
|||||||
VID = stoi(vid);
|
VID = stoi(vid);
|
||||||
}
|
}
|
||||||
if (PID != -1 && VID != -1 && PID == c.GetID()) {
|
if (PID != -1 && VID != -1 && PID == c.GetID()) {
|
||||||
|
if(c.GetUnicycleID() == VID){
|
||||||
|
c.SetUnicycleID(-1);
|
||||||
|
}
|
||||||
Network.SendToAll(nullptr, Packet, true, true);
|
Network.SendToAll(nullptr, Packet, true, true);
|
||||||
TriggerLuaEvent(("onVehicleDeleted"), false, nullptr,
|
TriggerLuaEvent(("onVehicleDeleted"), false, nullptr,
|
||||||
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID } }), false);
|
std::make_unique<TLuaArg>(TLuaArg { { c.GetID(), VID } }), false);
|
||||||
@@ -280,6 +313,7 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ
|
|||||||
void TServer::Apply(TClient& c, int VID, const std::string& pckt) {
|
void TServer::Apply(TClient& c, int VID, const std::string& pckt) {
|
||||||
std::string Packet = pckt.substr(pckt.find('{')), VD = c.GetCarData(VID);
|
std::string Packet = pckt.substr(pckt.find('{')), VD = c.GetCarData(VID);
|
||||||
std::string Header = VD.substr(0, VD.find('{'));
|
std::string Header = VD.substr(0, VD.find('{'));
|
||||||
|
|
||||||
VD = VD.substr(VD.find('{'));
|
VD = VD.substr(VD.find('{'));
|
||||||
rapidjson::Document Veh, Pack;
|
rapidjson::Document Veh, Pack;
|
||||||
Veh.Parse(VD.c_str());
|
Veh.Parse(VD.c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user