chore: cleanup pointer management for LDF data (#1995)

* change network settings from vector to LwoNameValue

* move settings on Entity to managed memory

* Migrate more members

* chore: remove pointer leakage from raw ldf pointers

* feedback

* fix ci
This commit is contained in:
David Markowitz
2026-06-14 20:54:52 -07:00
committed by GitHub
parent 90db1ac699
commit 0101933f5c
67 changed files with 676 additions and 754 deletions

View File

@@ -949,13 +949,13 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
}
}
void Entity::WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStream& outBitStream) const {
void Entity::WriteLDFData(const LwoNameValue& ldf, RakNet::BitStream& outBitStream) const {
RakNet::BitStream settingStream;
int32_t numberOfValidKeys = ldf.size();
int32_t numberOfValidKeys = ldf.values.size();
// Writing keys value pairs the client does not expect to receive or interpret will result in undefined behavior,
// so we need to filter out any keys that are not valid and fix the number of valid keys to be correct.
for (LDFBaseData* data : ldf) {
for (const auto& data : ldf.values | std::views::values) {
if (data && data->GetValueType() != eLDFType::LDF_TYPE_UNKNOWN) {
data->WriteToPacket(settingStream);
} else {
@@ -987,16 +987,16 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream& outBitStream, eReplicaPacke
const auto& syncLDF = GetVar<std::vector<std::u16string>>(u"syncLDF");
// Only sync for models.
if (!m_Settings.empty() && (GetComponent<ModelComponent>() && !GetComponent<PetComponent>())) {
if (!m_Settings.values.empty() && (GetComponent<ModelComponent>() && !GetComponent<PetComponent>())) {
outBitStream.Write1(); // Has ldf data
WriteLDFData(m_Settings, outBitStream);
} else if (!syncLDF.empty()) {
// Find all the ldf data we need to write
std::vector<LDFBaseData*> ldfData;
ldfData.reserve(m_Settings.size());
LwoNameValue ldfData;
for (const auto& data : syncLDF) {
ldfData.push_back(GetVarData(data));
const auto* toInsert = GetVarData(data);
if (toInsert) ldfData.values.insert_or_assign(data, toInsert->Copy());
}
outBitStream.Write1(); // Has ldf data
@@ -2045,13 +2045,7 @@ void Entity::SetI64(const std::u16string& name, const int64_t value) {
}
bool Entity::HasVar(const std::u16string& name) const {
for (auto* data : m_Settings) {
if (data->GetKey() == name) {
return true;
}
}
return false;
return m_Settings.values.contains(name);
}
uint16_t Entity::GetNetworkId() const {
@@ -2083,24 +2077,13 @@ void Entity::SendNetworkVar(const std::string& data, const SystemAddress& sysAdd
GameMessages::SendSetNetworkScriptVar(this, sysAddr, data);
}
LDFBaseData* Entity::GetVarData(const std::u16string& name) const {
for (auto* data : m_Settings) {
if (data == nullptr) {
continue;
}
if (data->GetKey() != name) {
continue;
}
return data;
}
return nullptr;
const LDFBaseData* const Entity::GetVarData(const std::u16string& name) const {
const auto itr = m_Settings.values.find(name);
return itr != m_Settings.values.cend() ? itr->second.get() : nullptr;
}
std::string Entity::GetVarAsString(const std::u16string& name) const {
auto* data = GetVarData(name);
const auto* const data = GetVarData(name);
return data ? data->GetValueAsString() : "";
}
@@ -2276,7 +2259,7 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfo& r
}
auto& configData = objectInfo.PushDebug("Config Data");
for (const auto config : m_Settings) {
for (const auto& config : m_Settings.values | std::views::values) {
configData.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(config->GetKey())) = config->GetValueAsString();
}