Store vehicles in parsed json

This commit is contained in:
Tixx 2025-01-18 22:05:56 +01:00
parent fbce8a946e
commit 2f577a2358
No known key found for this signature in database
GPG Key ID: EC6E7A2BAABF0B8C
8 changed files with 59 additions and 45 deletions

View File

@ -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); }

View File

@ -18,11 +18,12 @@
#pragma once
#include <nlohmann/json.hpp>
#include <string>
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?

View File

@ -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) {

View File

@ -246,7 +246,7 @@ std::pair<bool, std::string> 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);

View File

@ -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

View File

@ -946,7 +946,7 @@ bool TNetwork::SyncClient(const std::weak_ptr<TClient>& 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);
}
}

View File

@ -195,6 +195,18 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uin
// V to Y
if (Code <= 89 && Code >= 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<TClient>& Client, std::vector<uin
case 'N':
Network.SendToAll(LockedClient.get(), Packet, false, true);
return;
case 'Z': // position packet
case 'Z': { // position packet
PPSMonitor.IncrementInternalPPS();
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;
}
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<rapidjson::StringBuffer> writer(Buffer);
Veh.Accept(writer);
c.SetCarData(VID, Header + Buffer.GetString());
c.SetCarData(VID, Pack);
}
void TServer::InsertClient(const std::shared_ptr<TClient>& NewClient) {

View File

@ -21,7 +21,7 @@
#include "Common.h"
#include <utility>
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();
}