mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-01 23:35:41 +00:00
fix vehicle copy on GetAllCars, TSetOfVehicleData is now vector<>
This commit is contained in:
parent
7231c69e10
commit
56a02f0215
@ -14,10 +14,10 @@ class TServer;
|
||||
|
||||
class TClient final {
|
||||
public:
|
||||
using TSetOfVehicleData = std::unordered_set<TVehicleData>;
|
||||
using TSetOfVehicleData = std::vector<TVehicleData>;
|
||||
|
||||
struct TVehicleDataLockPair {
|
||||
TSetOfVehicleData& VehicleData;
|
||||
TSetOfVehicleData* VehicleData;
|
||||
std::unique_lock<std::mutex> Lock;
|
||||
};
|
||||
|
||||
@ -31,6 +31,7 @@ public:
|
||||
void SetName(const std::string& Name) { mName = Name; }
|
||||
void SetRoles(const std::string& Role) { mRole = Role; }
|
||||
void AddIdentifier(const std::string& ID) { mIdentifiers.insert(ID); };
|
||||
void EraseVehicle(TVehicleData& VehicleData);
|
||||
std::string GetCarData(int Ident);
|
||||
void SetUDPAddr(sockaddr_in Addr) { mUDPAddress = Addr; }
|
||||
void SetDownSock(SOCKET CSock) { mSocket[1] = CSock; }
|
||||
@ -67,6 +68,8 @@ public:
|
||||
int SecondsSinceLastPing();
|
||||
|
||||
private:
|
||||
void InsertVehicle(int ID, const std::string& Data);
|
||||
|
||||
TServer& mServer;
|
||||
bool mIsConnected = false;
|
||||
bool mIsSynced = false;
|
||||
|
@ -6,20 +6,25 @@ class TVehicleData final {
|
||||
public:
|
||||
TVehicleData(int ID, std::string Data);
|
||||
~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]] int ID() const { return mID; }
|
||||
|
||||
[[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; }
|
||||
|
||||
private:
|
||||
int mID { -1 };
|
||||
mutable std::string mData;
|
||||
std::string mData;
|
||||
};
|
||||
|
||||
// TODO: unused now, remove?
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<TVehicleData> {
|
||||
|
@ -9,12 +9,24 @@ void TClient::DeleteCar(int Ident) {
|
||||
std::unique_lock lock(mVehicleDataMutex);
|
||||
for (auto& v : mVehicleData) {
|
||||
if (v.ID() == Ident) {
|
||||
mVehicleData.erase(v);
|
||||
EraseVehicle(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TClient::EraseVehicle(TVehicleData& VehicleData) {
|
||||
std::unique_lock lock(mVehicleDataMutex);
|
||||
auto iter = std::find_if(mVehicleData.begin(), mVehicleData.end(), [&](auto& elem) {
|
||||
return VehicleData.ID() == elem.ID();
|
||||
});
|
||||
if (iter != mVehicleData.end()) {
|
||||
mVehicleData.erase(iter);
|
||||
} else {
|
||||
debug("tried to erase a vehicle that doesn't exist!");
|
||||
}
|
||||
}
|
||||
|
||||
void TClient::ClearCars() {
|
||||
std::unique_lock lock(mVehicleDataMutex);
|
||||
mVehicleData.clear();
|
||||
@ -37,11 +49,11 @@ int TClient::GetOpenCarID() const {
|
||||
|
||||
void TClient::AddNewCar(int Ident, const std::string& Data) {
|
||||
std::unique_lock lock(mVehicleDataMutex);
|
||||
mVehicleData.emplace(Ident, Data);
|
||||
mVehicleData.emplace_back(Ident, Data);
|
||||
}
|
||||
|
||||
TClient::TVehicleDataLockPair TClient::GetAllCars() {
|
||||
return { mVehicleData, std::unique_lock(mVehicleDataMutex) };
|
||||
return { &mVehicleData, std::unique_lock(mVehicleDataMutex) };
|
||||
}
|
||||
|
||||
std::string TClient::GetCarData(int Ident) {
|
||||
|
@ -339,15 +339,15 @@ int lua_GetCars(lua_State* L) {
|
||||
auto MaybeClient = GetClient(Engine().Server(), ID);
|
||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
||||
auto Client = MaybeClient.value().lock();
|
||||
TClient::TSetOfVehicleData VehicleData;
|
||||
TClient::TSetOfVehicleData* VehicleData;
|
||||
{ // Vehicle Data Lock Scope
|
||||
auto LockedData = Client->GetAllCars();
|
||||
VehicleData = LockedData.VehicleData;
|
||||
} // End Vehicle Data Lock Scope
|
||||
if (VehicleData.empty())
|
||||
if (VehicleData->empty())
|
||||
return 0;
|
||||
lua_newtable(L);
|
||||
for (const auto& v : VehicleData) {
|
||||
for (const auto& v : *VehicleData) {
|
||||
lua_pushinteger(L, v.ID());
|
||||
lua_pushstring(L, v.Data().substr(3).c_str());
|
||||
lua_settable(L, -3);
|
||||
|
@ -88,7 +88,8 @@ void TNetwork::UDPServerMain() {
|
||||
ReadLock Lock(mServer.GetClientMutex());
|
||||
if (!ClientPtr.expired()) {
|
||||
Client = ClientPtr.lock();
|
||||
}else return true;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Client->GetID() == ID) {
|
||||
@ -312,7 +313,8 @@ void TNetwork::Authentication(SOCKET TCPSock) {
|
||||
ReadLock Lock(mServer.GetClientMutex());
|
||||
if (!ClientPtr.expired()) {
|
||||
Cl = ClientPtr.lock();
|
||||
} else return true;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
info("Client Iteration: Name -> " + Cl->GetName() + ", Guest -> " + std::to_string(Cl->IsGuest()) + ", Roles -> " + Cl->GetRoles());
|
||||
if (Cl->GetName() == Client->GetName() && Cl->IsGuest() == Client->IsGuest()) {
|
||||
@ -355,7 +357,7 @@ bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
||||
if (!IsSync) {
|
||||
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') {
|
||||
c.EnqueuePacket(Data);
|
||||
}
|
||||
@ -364,7 +366,6 @@ bool TNetwork::TCPSend(TClient& c, const std::string& Data, bool IsSync) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t Size, Sent;
|
||||
std::string Send(4, 0);
|
||||
Size = int32_t(Data.size());
|
||||
@ -488,8 +489,8 @@ void TNetwork::ClientKick(TClient& c, const std::string& R) {
|
||||
c.SetStatus(-2);
|
||||
CloseSocketProper(c.GetTCPSock());
|
||||
}
|
||||
void TNetwork::Looper(const std::weak_ptr<TClient>& c){
|
||||
while(!c.expired()) {
|
||||
void TNetwork::Looper(const std::weak_ptr<TClient>& c) {
|
||||
while (!c.expired()) {
|
||||
auto Client = c.lock();
|
||||
if (Client->GetStatus() < 0) {
|
||||
debug("client status < 0, breaking client loop");
|
||||
@ -521,7 +522,7 @@ void TNetwork::Looper(const std::weak_ptr<TClient>& c){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
@ -535,7 +536,7 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
|
||||
OnConnect(c);
|
||||
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) {
|
||||
if (c.expired())
|
||||
@ -553,7 +554,8 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
|
||||
}
|
||||
TServer::GlobalParser(c, res, mPPSMonitor, *this);
|
||||
}
|
||||
if(QueueSync.joinable())QueueSync.join();
|
||||
if (QueueSync.joinable())
|
||||
QueueSync.join();
|
||||
|
||||
if (!c.expired()) {
|
||||
auto Client = c.lock();
|
||||
@ -583,12 +585,12 @@ void TNetwork::OnDisconnect(const std::weak_ptr<TClient>& ClientPtr, bool kicked
|
||||
TClient& c = *LockedClientPtr;
|
||||
info(c.GetName() + (" Connection Terminated"));
|
||||
std::string Packet;
|
||||
TClient::TSetOfVehicleData VehicleData;
|
||||
TClient::TSetOfVehicleData* VehicleData;
|
||||
{ // Vehicle Data Lock Scope
|
||||
auto LockedData = c.GetAllCars();
|
||||
VehicleData = LockedData.VehicleData;
|
||||
} // 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());
|
||||
SendToAll(&c, Packet, false, true);
|
||||
}
|
||||
@ -836,15 +838,16 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& c) {
|
||||
ReadLock Lock(mServer.GetClientMutex());
|
||||
if (!ClientPtr.expired()) {
|
||||
client = ClientPtr.lock();
|
||||
} else return true;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
TClient::TSetOfVehicleData VehicleData;
|
||||
TClient::TSetOfVehicleData* VehicleData;
|
||||
{ // Vehicle Data Lock Scope
|
||||
auto LockedData = client->GetAllCars();
|
||||
VehicleData = LockedData.VehicleData;
|
||||
} // End Vehicle Data Lock Scope
|
||||
if (client != LockedClient) {
|
||||
for (auto& v : VehicleData) {
|
||||
for (auto& v : *VehicleData) {
|
||||
if (LockedClient->GetStatus() < 0) {
|
||||
Return = true;
|
||||
res = false;
|
||||
@ -877,7 +880,8 @@ void TNetwork::SendToAll(TClient* c, const std::string& Data, bool Self, bool Re
|
||||
ReadLock Lock(mServer.GetClientMutex());
|
||||
if (!ClientPtr.expired()) {
|
||||
Client = ClientPtr.lock();
|
||||
}else return true;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
if (Self || Client.get() != c) {
|
||||
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) {
|
||||
std::string CMP(Comp(Data));
|
||||
Client->EnqueuePacket("ABG:" + CMP);
|
||||
}else{
|
||||
} else {
|
||||
Client->EnqueuePacket(Data);
|
||||
}
|
||||
//ret = SendLarge(*Client, Data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user