From 6a38b67ed5508ec7bffdb985baf278a8ee833e1d Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Thu, 21 Jul 2022 22:26:09 -0700 Subject: [PATCH] General AMF cleanup (#663) * General AMF cleanup Proper memory management as well as style cleanup * General optimizations Fix AMFArray so values are properly deleted when you leave the scope it was created in. Add bounds check for deletion so you don't double delete. Remove all AMFdeletions that are contained in an array since the array now manages its own memory and deletes it when it is no longer needed. * Better tests and fix de-serialize Fix de-serialize to be correct and implement a test to check this * Update AMFDeserializeTests.cpp * Update AMFFormat.cpp --- dCommon/AMFDeserialize.cpp | 28 +- dCommon/AMFFormat.cpp | 14 + dCommon/AMFFormat.h | 4 + dCommon/AMFFormat_BitStream.cpp | 373 +++++++++--------- dCommon/AMFFormat_BitStream.h | 158 ++++---- dGame/dComponents/DestroyableComponent.cpp | 11 +- .../dComponents/PropertyEntranceComponent.cpp | 2 - dGame/dGameMessages/GameMessages.cpp | 5 +- dGame/dUtilities/SlashCommandHandler.cpp | 22 +- dScripts/BankInteractServer.cpp | 7 +- dScripts/MailBoxServer.cpp | 1 - dScripts/NsLegoClubDoor.cpp | 39 -- dScripts/PropertyBankInteract.cpp | 6 +- dScripts/StoryBoxInteractServer.cpp | 8 +- dWorldServer/WorldServer.cpp | 5 - tests/AMFDeserializeTests.cpp | 9 +- 16 files changed, 303 insertions(+), 389 deletions(-) diff --git a/dCommon/AMFDeserialize.cpp b/dCommon/AMFDeserialize.cpp index 7f3f6d95..afe2b61b 100644 --- a/dCommon/AMFDeserialize.cpp +++ b/dCommon/AMFDeserialize.cpp @@ -127,21 +127,23 @@ AMFValue* AMFDeserialize::ReadAmfDouble(RakNet::BitStream* inStream) { AMFValue* AMFDeserialize::ReadAmfArray(RakNet::BitStream* inStream) { auto arrayValue = new AMFArrayValue(); + + // Read size of dense array auto sizeOfDenseArray = (ReadU29(inStream) >> 1); - if (sizeOfDenseArray >= 1) { - char valueType; - inStream->Read(valueType); // Unused - for (uint32_t i = 0; i < sizeOfDenseArray; i++) { - arrayValue->PushBackValue(Read(inStream)); - } - } else { - while (true) { - auto key = ReadString(inStream); - // No more values when we encounter an empty string - if (key.size() == 0) break; - arrayValue->InsertValue(key, Read(inStream)); - } + + // Then read Key'd portion + while (true) { + auto key = ReadString(inStream); + // No more values when we encounter an empty string + if (key.size() == 0) break; + arrayValue->InsertValue(key, Read(inStream)); } + + // Finally read dense portion + for (uint32_t i = 0; i < sizeOfDenseArray; i++) { + arrayValue->PushBackValue(Read(inStream)); + } + return arrayValue; } diff --git a/dCommon/AMFFormat.cpp b/dCommon/AMFFormat.cpp index d4cf6531..741a8bc4 100644 --- a/dCommon/AMFFormat.cpp +++ b/dCommon/AMFFormat.cpp @@ -108,6 +108,14 @@ _AMFArrayList_::iterator AMFArrayValue::GetDenseIteratorEnd() { return this->dense.end(); } +AMFArrayValue::~AMFArrayValue() { + for (auto valueToDelete : GetDenseArray()) { + if (valueToDelete) delete valueToDelete; + } + for (auto valueToDelete : GetAssociativeMap()) { + if (valueToDelete.second) delete valueToDelete.second; + } +} // AMFObject Constructor AMFObjectValue::AMFObjectValue(std::vector> traits) { @@ -155,3 +163,9 @@ _AMFObjectTraits_::iterator AMFObjectValue::GetTraitsIteratorEnd() { uint32_t AMFObjectValue::GetTraitArrayCount() { return (uint32_t)this->traits.size(); } + +AMFObjectValue::~AMFObjectValue() { + for (auto valueToDelete = GetTraitsIteratorBegin(); valueToDelete != GetTraitsIteratorEnd(); valueToDelete++) { + if (valueToDelete->second.second) delete valueToDelete->second.second; + } +} diff --git a/dCommon/AMFFormat.h b/dCommon/AMFFormat.h index c3d0936c..54a02944 100644 --- a/dCommon/AMFFormat.h +++ b/dCommon/AMFFormat.h @@ -59,6 +59,7 @@ public: \return The AMF value type */ virtual AMFValueType GetValueType() = 0; + virtual ~AMFValue() {}; }; //! A typedef for a pointer to an AMF value @@ -233,6 +234,7 @@ public: }; //! The array value AMF type +// This object will manage it's own memory map and list. Do not delete its values. class AMFArrayValue : public AMFValue { private: _AMFArrayMap_ associative; //!< The array map (associative part) @@ -245,6 +247,7 @@ private: AMFValueType GetValueType() { return AMFArray; } public: + ~AMFArrayValue() override; //! Inserts an item into the array map for a specific key /*! \param key The key to set @@ -332,6 +335,7 @@ private: \return The AMF value type */ AMFValueType GetValueType() { return AMFObject; } + ~AMFObjectValue() override; public: //! Constructor diff --git a/dCommon/AMFFormat_BitStream.cpp b/dCommon/AMFFormat_BitStream.cpp index 57497951..96ccdab3 100644 --- a/dCommon/AMFFormat_BitStream.cpp +++ b/dCommon/AMFFormat_BitStream.cpp @@ -3,269 +3,248 @@ // Writes an AMFValue pointer to a RakNet::BitStream template<> void RakNet::BitStream::Write(AMFValue* value) { - if (value != nullptr) { - AMFValueType type = value->GetValueType(); - - switch (type) { - case AMFUndefined: { - AMFUndefinedValue* v = (AMFUndefinedValue*)value; - this->Write(*v); - break; - } - - case AMFNull: { - AMFNullValue* v = (AMFNullValue*)value; - this->Write(*v); - break; - } - - case AMFFalse: { - AMFFalseValue* v = (AMFFalseValue*)value; - this->Write(*v); - break; - } - - case AMFTrue: { - AMFTrueValue* v = (AMFTrueValue*)value; - this->Write(*v); - break; - } - - case AMFInteger: { - AMFIntegerValue* v = (AMFIntegerValue*)value; - this->Write(*v); - break; - } - - case AMFString: { - AMFStringValue* v = (AMFStringValue*)value; - this->Write(*v); - break; - } - - case AMFXMLDoc: { - AMFXMLDocValue* v = (AMFXMLDocValue*)value; - this->Write(*v); - break; - } - - case AMFDate: { - AMFDateValue* v = (AMFDateValue*)value; - this->Write(*v); - break; - } - - case AMFArray: { - AMFArrayValue* v = (AMFArrayValue*)value; - this->Write(*v); - break; - } - } - } + if (value != nullptr) { + AMFValueType type = value->GetValueType(); + + switch (type) { + case AMFUndefined: { + AMFUndefinedValue* v = (AMFUndefinedValue*)value; + this->Write(*v); + break; + } + + case AMFNull: { + AMFNullValue* v = (AMFNullValue*)value; + this->Write(*v); + break; + } + + case AMFFalse: { + AMFFalseValue* v = (AMFFalseValue*)value; + this->Write(*v); + break; + } + + case AMFTrue: { + AMFTrueValue* v = (AMFTrueValue*)value; + this->Write(*v); + break; + } + + case AMFInteger: { + AMFIntegerValue* v = (AMFIntegerValue*)value; + this->Write(*v); + break; + } + + case AMFDouble: { + AMFDoubleValue* v = (AMFDoubleValue*)value; + this->Write(*v); + break; + } + + case AMFString: { + AMFStringValue* v = (AMFStringValue*)value; + this->Write(*v); + break; + } + + case AMFXMLDoc: { + AMFXMLDocValue* v = (AMFXMLDocValue*)value; + this->Write(*v); + break; + } + + case AMFDate: { + AMFDateValue* v = (AMFDateValue*)value; + this->Write(*v); + break; + } + + case AMFArray: { + this->Write((AMFArrayValue*)value); + break; + } + } + } } -// A private function to write an value to a RakNet::BitStream +/** + * A private function to write an value to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteUInt29(RakNet::BitStream* bs, uint32_t v) { - unsigned char b4 = (unsigned char)v; - if (v < 0x00200000) { - b4 = b4 & 0x7F; - if (v > 0x7F) { - unsigned char b3; - v = v >> 7; - b3 = ((unsigned char)(v)) | 0x80; - if (v > 0x7F) { - unsigned char b2; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - bs->Write(b2); - } - - bs->Write(b3); - } - } else { - unsigned char b1; - unsigned char b2; - unsigned char b3; - - v = v >> 8; - b3 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b2 = ((unsigned char)(v)) | 0x80; - v = v >> 7; - b1 = ((unsigned char)(v)) | 0x80; - - bs->Write(b1); - bs->Write(b2); - bs->Write(b3); - } - - bs->Write(b4); + unsigned char b4 = (unsigned char)v; + if (v < 0x00200000) { + b4 = b4 & 0x7F; + if (v > 0x7F) { + unsigned char b3; + v = v >> 7; + b3 = ((unsigned char)(v)) | 0x80; + if (v > 0x7F) { + unsigned char b2; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + bs->Write(b2); + } + + bs->Write(b3); + } + } else { + unsigned char b1; + unsigned char b2; + unsigned char b3; + + v = v >> 8; + b3 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b2 = ((unsigned char)(v)) | 0x80; + v = v >> 7; + b1 = ((unsigned char)(v)) | 0x80; + + bs->Write(b1); + bs->Write(b2); + bs->Write(b3); + } + + bs->Write(b4); } -// Writes a flag number to a RakNet::BitStream +/** + * Writes a flag number to a RakNet::BitStream + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteFlagNumber(RakNet::BitStream* bs, uint32_t v) { - v = (v << 1) | 0x01; - WriteUInt29(bs, v); + v = (v << 1) | 0x01; + WriteUInt29(bs, v); } -// Writes an AMFString to a RakNet::BitStream +/** + * Writes an AMFString to a RakNet::BitStream + * + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteAMFString(RakNet::BitStream* bs, const std::string& str) { - WriteFlagNumber(bs, (uint32_t)str.size()); - bs->Write(str.c_str(), (uint32_t)str.size()); + WriteFlagNumber(bs, (uint32_t)str.size()); + bs->Write(str.c_str(), (uint32_t)str.size()); } -// Writes an AMF U16 to a RakNet::BitStream +/** + * Writes an U16 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteAMFU16(RakNet::BitStream* bs, uint16_t value) { - unsigned char b2; - b2 = (unsigned char)value; - value = value >> 8; - bs->Write((unsigned char)value); - bs->Write(b2); + bs->Write(value); } -// Writes an AMF U32 to RakNet::BitStream +/** + * Writes an U32 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteAMFU32(RakNet::BitStream* bs, uint32_t value) { - unsigned char b2; - unsigned char b3; - unsigned char b4; - - b4 = (unsigned char)value; - value = value >> 8; - b3 = (unsigned char)value; - value = value >> 8; - b2 = (unsigned char)value; - value = value >> 8; - - bs->Write((unsigned char)value); - bs->Write(b2); - bs->Write(b3); - bs->Write(b4); + bs->Write(value); } -// Writes an AMF U64 to RakNet::BitStream +/** + * Writes an U64 to a bitstream + * + * RakNet writes in the correct byte order - do not reverse this. + */ void WriteAMFU64(RakNet::BitStream* bs, uint64_t value) { - unsigned char b2; - unsigned char b3; - unsigned char b4; - unsigned char b5; - unsigned char b6; - unsigned char b7; - unsigned char b8; - - b8 = (unsigned char)value; - value = value >> 8; - b7 = (unsigned char)value; - value = value >> 8; - b6 = (unsigned char)value; - value = value >> 8; - b5 = (unsigned char)value; - value = value >> 8; - b4 = (unsigned char)value; - value = value >> 8; - b3 = (unsigned char)value; - value = value >> 8; - b2 = (unsigned char)value; - value = value >> 8; - - bs->Write((unsigned char)value); - bs->Write(b2); - bs->Write(b3); - bs->Write(b4); - bs->Write(b5); - bs->Write(b6); - bs->Write(b7); - bs->Write(b8); + bs->Write(value); } // Writes an AMFUndefinedValue to BitStream template<> void RakNet::BitStream::Write(AMFUndefinedValue value) { - this->Write(AMFUndefined); + this->Write(AMFUndefined); } // Writes an AMFNullValue to BitStream template<> void RakNet::BitStream::Write(AMFNullValue value) { - this->Write(AMFNull); + this->Write(AMFNull); } // Writes an AMFFalseValue to BitStream template<> void RakNet::BitStream::Write(AMFFalseValue value) { - this->Write(AMFFalse); + this->Write(AMFFalse); } // Writes an AMFTrueValue to BitStream template<> void RakNet::BitStream::Write(AMFTrueValue value) { - this->Write(AMFTrue); + this->Write(AMFTrue); } // Writes an AMFIntegerValue to BitStream template<> void RakNet::BitStream::Write(AMFIntegerValue value) { - this->Write(AMFInteger); - WriteUInt29(this, value.GetIntegerValue()); + this->Write(AMFInteger); + WriteUInt29(this, value.GetIntegerValue()); } // Writes an AMFDoubleValue to BitStream template<> void RakNet::BitStream::Write(AMFDoubleValue value) { - this->Write(AMFDouble); - double d = value.GetDoubleValue(); - WriteAMFU64(this, *((unsigned long long*)&d)); + this->Write(AMFDouble); + double d = value.GetDoubleValue(); + WriteAMFU64(this, *((unsigned long long*)&d)); } // Writes an AMFStringValue to BitStream template<> void RakNet::BitStream::Write(AMFStringValue value) { - this->Write(AMFString); - std::string v = value.GetStringValue(); - WriteAMFString(this, v); + this->Write(AMFString); + std::string v = value.GetStringValue(); + WriteAMFString(this, v); } // Writes an AMFXMLDocValue to BitStream template<> void RakNet::BitStream::Write(AMFXMLDocValue value) { - this->Write(AMFXMLDoc); - std::string v = value.GetXMLDocValue(); - WriteAMFString(this, v); + this->Write(AMFXMLDoc); + std::string v = value.GetXMLDocValue(); + WriteAMFString(this, v); } // Writes an AMFDateValue to BitStream template<> void RakNet::BitStream::Write(AMFDateValue value) { - this->Write(AMFDate); - uint64_t date = value.GetDateValue(); - WriteAMFU64(this, date); + this->Write(AMFDate); + uint64_t date = value.GetDateValue(); + WriteAMFU64(this, date); } // Writes an AMFArrayValue to BitStream template<> -void RakNet::BitStream::Write(AMFArrayValue value) { - this->Write(AMFArray); - uint32_t denseSize = value.GetDenseValueSize(); - WriteFlagNumber(this, denseSize); - - _AMFArrayMap_::iterator it = value.GetAssociativeIteratorValueBegin(); - _AMFArrayMap_::iterator end = value.GetAssociativeIteratorValueEnd(); - - while (it != end) { - WriteAMFString(this, it->first); - this->Write(it->second); - it++; - } - - this->Write(AMFNull); - - if (denseSize > 0) { - _AMFArrayList_::iterator it2 = value.GetDenseIteratorBegin(); - _AMFArrayList_::iterator end2 = value.GetDenseIteratorEnd(); - - while (it2 != end2) { - this->Write(*it2); - it2++; - } - } +void RakNet::BitStream::Write(AMFArrayValue* value) { + this->Write(AMFArray); + uint32_t denseSize = value->GetDenseValueSize(); + WriteFlagNumber(this, denseSize); + + _AMFArrayMap_::iterator it = value->GetAssociativeIteratorValueBegin(); + _AMFArrayMap_::iterator end = value->GetAssociativeIteratorValueEnd(); + + while (it != end) { + WriteAMFString(this, it->first); + this->Write(it->second); + it++; + } + + this->Write(AMFNull); + + if (denseSize > 0) { + _AMFArrayList_::iterator it2 = value->GetDenseIteratorBegin(); + _AMFArrayList_::iterator end2 = value->GetDenseIteratorEnd(); + + while (it2 != end2) { + this->Write(*it2); + it2++; + } + } } diff --git a/dCommon/AMFFormat_BitStream.h b/dCommon/AMFFormat_BitStream.h index 69dd0896..ff72a180 100644 --- a/dCommon/AMFFormat_BitStream.h +++ b/dCommon/AMFFormat_BitStream.h @@ -7,86 +7,86 @@ #include /*! - \file AMFBitStream.hpp - \brief A class that implements native writing of AMF values to RakNet::BitStream + \file AMFFormat_BitStream.h + \brief A class that implements native writing of AMF values to RakNet::BitStream */ // We are using the RakNet namespace namespace RakNet { - //! Writes an AMFValue pointer to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFValue* value); - - //! Writes an AMFUndefinedValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFUndefinedValue value); - - //! Writes an AMFNullValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFNullValue value); - - //! Writes an AMFFalseValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFFalseValue value); - - //! Writes an AMFTrueValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFTrueValue value); - - //! Writes an AMFIntegerValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFIntegerValue value); - - //! Writes an AMFDoubleValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFDoubleValue value); - - //! Writes an AMFStringValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFStringValue value); - - //! Writes an AMFXMLDocValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFXMLDocValue value); - - //! Writes an AMFDateValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFDateValue value); - - //! Writes an AMFArrayValue to a RakNet::BitStream - /*! - \param value The value to write - */ - template<> - void RakNet::BitStream::Write(AMFArrayValue value); -} + //! Writes an AMFValue pointer to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFValue* value); + + //! Writes an AMFUndefinedValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFUndefinedValue value); + + //! Writes an AMFNullValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFNullValue value); + + //! Writes an AMFFalseValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFFalseValue value); + + //! Writes an AMFTrueValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFTrueValue value); + + //! Writes an AMFIntegerValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFIntegerValue value); + + //! Writes an AMFDoubleValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFDoubleValue value); + + //! Writes an AMFStringValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFStringValue value); + + //! Writes an AMFXMLDocValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFXMLDocValue value); + + //! Writes an AMFDateValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFDateValue value); + + //! Writes an AMFArrayValue to a RakNet::BitStream + /*! + \param value The value to write + */ + template <> + void RakNet::BitStream::Write(AMFArrayValue* value); +} // namespace RakNet diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 37d74a55..efcfb5cb 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -234,10 +234,8 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { AMFArrayValue args; args.InsertValue("amount", amount); args.InsertValue("type", type); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - delete amount; - delete type; + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); } EntityManager::Instance()->SerializeEntity(m_Parent); @@ -283,9 +281,6 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - - delete amount; - delete type; } EntityManager::Instance()->SerializeEntity(m_Parent); @@ -328,10 +323,8 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { AMFArrayValue args; args.InsertValue("amount", amount); args.InsertValue("type", type); - GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - delete amount; - delete type; + GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); } EntityManager::Instance()->SerializeEntity(m_Parent); } diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 87e0c7ed..4be059ed 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -40,8 +40,6 @@ void PropertyEntranceComponent::OnUse(Entity* entity) { args.InsertValue("state", state); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); - - delete state; } void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index, bool returnToZone, const SystemAddress& sysAddr) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index ba410b70..a971b723 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -4978,12 +4978,9 @@ void GameMessages::HandleFireEventServerSide(RakNet::BitStream* inStream, Entity } if (args == u"toggleMail") { - AMFFalseValue* value = new AMFFalseValue(); - AMFArrayValue args; - args.InsertValue("visible", value); + args.InsertValue("visible", new AMFFalseValue()); GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleMail", &args); - delete value; } // This should probably get it's own "ServerEvents" system or something at some point diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 74d44ce7..22fbb680 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -276,27 +276,21 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit args.InsertValue("state", state); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", &args); - - delete state; } entity->AddCallbackTimer(0.5f, [customText, entity] () { AMFArrayValue args; - auto* visiable = new AMFTrueValue(); auto* text = new AMFStringValue(); text->SetStringValue(customText); - args.InsertValue("visible", visiable); + args.InsertValue("visible", new AMFTrueValue()); args.InsertValue("text", text); Game::logger->Log("SlashCommandHandler", "Sending \n%s\n", customText.c_str()); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", &args); - - delete visiable; - delete text; }); return; @@ -556,8 +550,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Switched UI state."); - delete value; - return; } @@ -570,8 +562,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit ChatPackets::SendSystemMessage(sysAddr, u"Toggled UI state."); - delete value; - return; } @@ -1578,11 +1568,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if ((chatCommand == "debugui") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { ChatPackets::SendSystemMessage(sysAddr, u"Opening UIDebugger..."); - AMFStringValue* value = new AMFStringValue(); - value->SetStringValue("ToggleUIDebugger;"); AMFArrayValue args; - GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, value->GetStringValue(), &args); - delete value; + GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "ToggleUIDebugger;", nullptr); } if ((chatCommand == "boost") && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { @@ -2008,11 +1995,6 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); - delete titleValue; - delete messageValue; - titleValue = nullptr; - messageValue = nullptr; - //Notify chat about it CBITSTREAM; PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ANNOUNCEMENT); diff --git a/dScripts/BankInteractServer.cpp b/dScripts/BankInteractServer.cpp index 9bea375a..dc119056 100644 --- a/dScripts/BankInteractServer.cpp +++ b/dScripts/BankInteractServer.cpp @@ -9,8 +9,6 @@ void BankInteractServer::OnUse(Entity* self, Entity* user) args.InsertValue("state", bank); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); - - delete bank; } void BankInteractServer::OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, @@ -19,13 +17,10 @@ void BankInteractServer::OnFireEventServerSide(Entity *self, Entity *sender, std if (args == "ToggleBank") { AMFArrayValue args; - AMFFalseValue* amfFalse = new AMFFalseValue(); - args.InsertValue("visible", amfFalse); + args.InsertValue("visible", new AMFFalseValue()); GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &args); - delete amfFalse; - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); } } diff --git a/dScripts/MailBoxServer.cpp b/dScripts/MailBoxServer.cpp index 3e4e9687..56e7793e 100644 --- a/dScripts/MailBoxServer.cpp +++ b/dScripts/MailBoxServer.cpp @@ -8,5 +8,4 @@ void MailBoxServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; args.InsertValue("state", value); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); - delete value; } \ No newline at end of file diff --git a/dScripts/NsLegoClubDoor.cpp b/dScripts/NsLegoClubDoor.cpp index 0b773b09..0a73c6d0 100644 --- a/dScripts/NsLegoClubDoor.cpp +++ b/dScripts/NsLegoClubDoor.cpp @@ -13,21 +13,6 @@ void NsLegoClubDoor::OnStartup(Entity* self) args = {}; - /** - { {0,{ - {"image", "textures/ui/zone_thumnails/Nimbus_Station.dds"}, - {"caption", "%[UI_CHOICE_NS]"}, -- "%[LOC_STRING]" is the format for sending localization tokens to the choice box - {"identifier", "zoneID_1200"}, - {"tooltipText", "%[UI_CHOICE_NS_HOVER]"} - }}, - {1,{ - {"image", "textures/ui/zone_thumnails/Nexus_Tower.dds"}, - {"caption", "%[UI_CHOICE_NT]"}, - {"identifier", "zoneID_1900"}, - {"tooltipText", "%[UI_CHOICE_NT_HOVER]"} - } } } - */ - AMFStringValue* callbackClient = new AMFStringValue(); callbackClient->SetStringValue(std::to_string(self->GetObjectID())); args.InsertValue("callbackClient", callbackClient); @@ -97,12 +82,6 @@ void NsLegoClubDoor::OnUse(Entity* self, Entity* user) if (CheckChoice(self, player)) { - /** - { {"callbackClient", self}, - {"strIdentifier", "choiceDoor"}, - {"title", "%[UI_CHOICE_DESTINATION]"}, - {"options", choiceOptions} } - */ AMFArrayValue* multiArgs = new AMFArrayValue(); AMFStringValue* callbackClient = new AMFStringValue(); @@ -120,19 +99,9 @@ void NsLegoClubDoor::OnUse(Entity* self, Entity* user) multiArgs->InsertValue("options", options); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", multiArgs); - - delete multiArgs; - delete callbackClient; - delete strIdentifier; - delete title; } else if (self->GetVar(u"currentZone") != m_ChoiceZoneID) { - /** - { {"state", "Lobby"}, - {"context", {{"user", msg.user}, {"callbackObj", self}, - {"HelpVisible", "show" }, {"type", "Lego_Club_Valid"}} }} - */ AMFArrayValue* multiArgs = new AMFArrayValue(); AMFStringValue* state = new AMFStringValue(); @@ -160,14 +129,6 @@ void NsLegoClubDoor::OnUse(Entity* self, Entity* user) multiArgs->InsertValue("context", context); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "pushGameState", multiArgs); - - delete multiArgs; - delete state; - delete context; - delete user; - delete callbackObj; - delete helpVisible; - delete type; } else { diff --git a/dScripts/PropertyBankInteract.cpp b/dScripts/PropertyBankInteract.cpp index 974b33a6..d564c503 100644 --- a/dScripts/PropertyBankInteract.cpp +++ b/dScripts/PropertyBankInteract.cpp @@ -24,7 +24,6 @@ void PropertyBankInteract::OnUse(Entity *self, Entity *user) { args.InsertValue("state", value); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); - delete value; GameMessages::SendNotifyClientObject(self->GetObjectID(), u"OpenBank", 0, 0, LWOOBJID_EMPTY, "", user->GetSystemAddress()); @@ -34,13 +33,10 @@ void PropertyBankInteract::OnFireEventServerSide(Entity *self, Entity *sender, s int32_t param2, int32_t param3) { if (args == "ToggleBank") { AMFArrayValue amfArgs; - auto* amfFalse = new AMFFalseValue(); - amfArgs.InsertValue("visible", amfFalse); + amfArgs.InsertValue("visible", new AMFFalseValue()); GameMessages::SendUIMessageServerToSingleClient(sender, sender->GetSystemAddress(), "ToggleBank", &amfArgs); - delete amfFalse; - GameMessages::SendNotifyClientObject(self->GetObjectID(), u"CloseBank", 0, 0, LWOOBJID_EMPTY, "", sender->GetSystemAddress()); } diff --git a/dScripts/StoryBoxInteractServer.cpp b/dScripts/StoryBoxInteractServer.cpp index e5899f5d..187d05a2 100644 --- a/dScripts/StoryBoxInteractServer.cpp +++ b/dScripts/StoryBoxInteractServer.cpp @@ -18,24 +18,18 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { args.InsertValue("state", state); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", &args); - - delete state; } user->AddCallbackTimer(0.1f, [user, customText] () { AMFArrayValue args; - auto* visiable = new AMFTrueValue(); auto* text = new AMFStringValue(); text->SetStringValue(customText); - args.InsertValue("visible", visiable); + args.InsertValue("visible", new AMFTrueValue()); args.InsertValue("text", text); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "ToggleStoryBox", &args); - - delete visiable; - delete text; }); return; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index d7a3b41e..96149ae4 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -577,11 +577,6 @@ void HandlePacketChat(Packet* packet) { GameMessages::SendUIMessageServerToAllClients("ToggleAnnounce", &args); - delete titleValue; - delete messageValue; - titleValue = nullptr; - messageValue = nullptr; - break; } diff --git a/tests/AMFDeserializeTests.cpp b/tests/AMFDeserializeTests.cpp index 88405803..58d7eea4 100644 --- a/tests/AMFDeserializeTests.cpp +++ b/tests/AMFDeserializeTests.cpp @@ -129,20 +129,25 @@ int ReadAMFArrayFromBitStream() { ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 0); } bitStream.Reset(); - // Test a key'd value + // Test a key'd value and dense value bitStream.Write(0x09); - bitStream.Write(0x01); + bitStream.Write(0x03); bitStream.Write(0x15); for (auto e : "BehaviorID") if (e != '\0') bitStream.Write(e); bitStream.Write(0x06); bitStream.Write(0x0B); for (auto e : "10447") if (e != '\0') bitStream.Write(e); bitStream.Write(0x01); + bitStream.Write(0x06); + bitStream.Write(0x0B); + for (auto e : "10447") if (e != '\0') bitStream.Write(e); { std::unique_ptr res(ReadFromBitStream(&bitStream)); ASSERT_EQ(res->GetValueType(), AMFValueType::AMFArray); ASSERT_EQ(static_cast(res.get())->GetAssociativeMap().size(), 1); + ASSERT_EQ(static_cast(res.get())->GetDenseArray().size(), 1); ASSERT_EQ(static_cast(static_cast(res.get())->FindValue("BehaviorID"))->GetStringValue(), "10447"); + ASSERT_EQ(static_cast(static_cast(res.get())->GetDenseArray()[0])->GetStringValue(), "10447"); } // Test a dense array return 0;