From 2f577a2358f2fd880259271c0be4beee471d1217 Mon Sep 17 00:00:00 2001 From: Tixx <83774803+WiserTixx@users.noreply.github.com> Date: Sat, 18 Jan 2025 22:05:56 +0100 Subject: [PATCH 1/2] Store vehicles in parsed json --- include/Client.h | 6 ++-- include/VehicleData.h | 11 ++++--- src/Client.cpp | 8 +++--- src/LuaAPI.cpp | 2 +- src/TLuaEngine.cpp | 2 +- src/TNetwork.cpp | 2 +- src/TServer.cpp | 67 ++++++++++++++++++++++++------------------- src/VehicleData.cpp | 6 +++- 8 files changed, 59 insertions(+), 45 deletions(-) diff --git a/include/Client.h b/include/Client.h index 894310f..860bcbc 100644 --- a/include/Client.h +++ b/include/Client.h @@ -56,14 +56,14 @@ public: ~TClient(); TClient& operator=(const TClient&) = delete; - void AddNewCar(int Ident, const std::string& Data); - void SetCarData(int Ident, const std::string& Data); + void AddNewCar(int Ident, const nlohmann::json& Data); + void SetCarData(int Ident, const nlohmann::json& 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; } - std::string GetCarData(int Ident); + nlohmann::json GetCarData(int Ident); std::string GetCarPositionRaw(int Ident); void SetUDPAddr(const ip::udp::endpoint& Addr) { mUDPAddress = Addr; } void SetTCPSock(ip::tcp::socket&& CSock) { mSocket = std::move(CSock); } diff --git a/include/VehicleData.h b/include/VehicleData.h index e8623bb..13c4e38 100644 --- a/include/VehicleData.h +++ b/include/VehicleData.h @@ -18,11 +18,12 @@ #pragma once +#include #include class TVehicleData final { public: - TVehicleData(int ID, std::string Data); + TVehicleData(int ID, nlohmann::json 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, @@ -32,14 +33,16 @@ public: [[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) { mData = Data; } + [[nodiscard]] nlohmann::json Data() const { return mData; } + [[nodiscard]] std::string DataAsPacket(const std::string& Role, const std::string& Name, int ID) const; + + void SetData(const nlohmann::json& Data) { mData = Data; } bool operator==(const TVehicleData& v) const { return mID == v.mID; } private: int mID { -1 }; - std::string mData; + nlohmann::json mData; }; // TODO: unused now, remove? diff --git a/src/Client.cpp b/src/Client.cpp index 6311e2e..ed67945 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -57,7 +57,7 @@ int TClient::GetOpenCarID() const { return OpenID; } -void TClient::AddNewCar(int Ident, const std::string& Data) { +void TClient::AddNewCar(int Ident, const nlohmann::json& Data) { std::unique_lock lock(mVehicleDataMutex); mVehicleData.emplace_back(Ident, Data); } @@ -98,7 +98,7 @@ void TClient::SetCarPosition(int Ident, const std::string& Data) { mVehiclePosition[size_t(Ident)] = Data; } -std::string TClient::GetCarData(int Ident) { +nlohmann::json TClient::GetCarData(int Ident) { { // lock std::unique_lock lock(mVehicleDataMutex); for (auto& v : mVehicleData) { @@ -108,10 +108,10 @@ std::string TClient::GetCarData(int Ident) { } } // unlock DeleteCar(Ident); - return ""; + return nlohmann::detail::value_t::null; } -void TClient::SetCarData(int Ident, const std::string& Data) { +void TClient::SetCarData(int Ident, const nlohmann::json& Data) { { // lock std::unique_lock lock(mVehicleDataMutex); for (auto& v : mVehicleData) { diff --git a/src/LuaAPI.cpp b/src/LuaAPI.cpp index fe16fe7..47b7235 100644 --- a/src/LuaAPI.cpp +++ b/src/LuaAPI.cpp @@ -246,7 +246,7 @@ std::pair LuaAPI::MP::RemoveVehicle(int PID, int VID) { return Result; } auto c = MaybeClient.value().lock(); - if (!c->GetCarData(VID).empty()) { + if (c->GetCarData(VID) != nlohmann::detail::value_t::null) { std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID); LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent("onVehicleDeleted", "", PID, VID)); Engine->Network().SendToAll(nullptr, StringToVector(Destroy), true, true); diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index fbd5758..ad67421 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -682,7 +682,7 @@ sol::table TLuaEngine::StateThreadData::Lua_GetPlayerVehicles(int ID) { sol::state_view StateView(mState); sol::table Result = StateView.create_table(); for (const auto& v : VehicleData) { - Result[v.ID()] = v.Data().substr(3); + Result[v.ID()] = v.DataAsPacket(Client->GetRoles(), Client->GetName(), Client->GetID()).substr(3); } return Result; } else diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index 24fc37c..01c9567 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -946,7 +946,7 @@ bool TNetwork::SyncClient(const std::weak_ptr& c) { res = false; return false; } - res = Respond(*LockedClient, StringToVector(v.Data()), true, true); + res = Respond(*LockedClient, StringToVector(v.DataAsPacket(client->GetRoles(), client->GetName(), client->GetID())), true, true); } } diff --git a/src/TServer.cpp b/src/TServer.cpp index 6020662..51b3377 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -195,6 +195,18 @@ void TServer::GlobalParser(const std::weak_ptr& Client, std::vector= 86) { + int PID = -1; + int VID = -1; + + auto MaybePidVid = GetPidVid(StringPacket.substr(3).substr(0, StringPacket.substr(3).find(':', 1))); + if (MaybePidVid) { + std::tie(PID, VID) = MaybePidVid.value(); + } + + if (PID == -1 || VID == -1 || PID != LockedClient->GetID()) { + return; + } + PPSMonitor.IncrementInternalPPS(); Network.SendToAll(LockedClient.get(), Packet, false, false); return; @@ -255,11 +267,25 @@ void TServer::GlobalParser(const std::weak_ptr& Client, std::vectorGetID()) { + return; + } + Network.SendToAll(LockedClient.get(), Packet, false, false); HandlePosition(*LockedClient, StringPacket); return; + } default: return; } @@ -328,8 +354,9 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ }); bool SpawnConfirmed = false; - if (ShouldSpawn(c, CarJson, CarID) && !ShouldntSpawn) { - c.AddNewCar(CarID, Packet); + auto CarJsonDoc = nlohmann::json::parse(CarJson, nullptr, false); + if (ShouldSpawn(c, CarJson, CarID) && !ShouldntSpawn && !CarJsonDoc.is_discarded()) { + c.AddNewCar(CarID, CarJsonDoc); Network.SendToAll(nullptr, StringToVector(Packet), true, true); SpawnConfirmed = true; } else { @@ -461,42 +488,22 @@ void TServer::Apply(TClient& c, int VID, const std::string& pckt) { beammp_error("Malformed packet received, no '{' found"); return; } + std::string Packet = pckt.substr(FoundPos); - std::string VD = c.GetCarData(VID); - if (VD.empty()) { + nlohmann::json VD = c.GetCarData(VID); + if (VD == nlohmann::detail::value_t::null) { beammp_error("Tried to apply change to vehicle that does not exist"); return; } - std::string Header = VD.substr(0, VD.find('{')); - FoundPos = VD.find('{'); - if (FoundPos == std::string::npos) { - return; - } - VD = VD.substr(FoundPos); - rapidjson::Document Veh, Pack; - Veh.Parse(VD.c_str()); - if (Veh.HasParseError()) { - beammp_error("Could not get vehicle config!"); - return; - } - Pack.Parse(Packet.c_str()); - if (Pack.HasParseError() || Pack.IsNull()) { + nlohmann::json Pack = nlohmann::json::parse(Packet, nullptr, false); + + if (Pack.is_discarded()) { beammp_error("Could not get active vehicle config!"); return; } - for (auto& M : Pack.GetObject()) { - if (Veh[M.name].IsNull()) { - Veh.AddMember(M.name, M.value, Veh.GetAllocator()); - } else { - Veh[M.name] = Pack[M.name]; - } - } - rapidjson::StringBuffer Buffer; - rapidjson::Writer writer(Buffer); - Veh.Accept(writer); - c.SetCarData(VID, Header + Buffer.GetString()); + c.SetCarData(VID, Pack); } void TServer::InsertClient(const std::shared_ptr& NewClient) { diff --git a/src/VehicleData.cpp b/src/VehicleData.cpp index 0e17f64..f1246c3 100644 --- a/src/VehicleData.cpp +++ b/src/VehicleData.cpp @@ -21,7 +21,7 @@ #include "Common.h" #include -TVehicleData::TVehicleData(int ID, std::string Data) +TVehicleData::TVehicleData(int ID, nlohmann::json Data) : mID(ID) , mData(std::move(Data)) { beammp_trace("vehicle " + std::to_string(mID) + " constructed"); @@ -30,3 +30,7 @@ TVehicleData::TVehicleData(int ID, std::string Data) TVehicleData::~TVehicleData() { beammp_trace("vehicle " + std::to_string(mID) + " destroyed"); } + +std::string TVehicleData::DataAsPacket(const std::string& Role, const std::string& Name, const int ID) const { + return "Os:" + Role + ":" + Name + ":" + std::to_string(ID) + "-" + std::to_string(this->mID) + ":" + this->mData.dump(); +} \ No newline at end of file From 52a1d9a99e86a45b02ec89a2e1140140fd2993e8 Mon Sep 17 00:00:00 2001 From: Tixx <83774803+WiserTixx@users.noreply.github.com> Date: Sat, 18 Jan 2025 22:06:11 +0100 Subject: [PATCH 2/2] Update vehicle state after paint packet --- src/TServer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/TServer.cpp b/src/TServer.cpp index 51b3377..c47da67 100644 --- a/src/TServer.cpp +++ b/src/TServer.cpp @@ -473,6 +473,17 @@ void TServer::ParseVehicle(TClient& c, const std::string& Pckt, TNetwork& Networ Data = Data.substr(Data.find('[')); LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent("onVehiclePaintChanged", "", c.GetID(), VID, Data)); Network.SendToAll(&c, StringToVector(Packet), false, true); + + auto CarData = c.GetCarData(VID); + if (CarData == nlohmann::detail::value_t::null) + return; + + if (CarData.contains("vcf") && CarData.at("vcf").is_object()) + if (CarData.at("vcf").contains("paints") && CarData.at("vcf").at("paints").is_array()) { + CarData.at("vcf")["paints"] = nlohmann::json::parse(Data); + c.SetCarData(VID, CarData); + } + } return; }