From 5aa8b1395b1685f76d6200c890b74e172eb96239 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Thu, 21 Nov 2024 18:37:50 -0600 Subject: [PATCH] memcpy and template deduction guide --- dCommon/Amf3.h | 14 ++++----- dGame/dComponents/DestroyableComponent.cpp | 12 ++++---- .../dComponents/PropertyEntranceComponent.cpp | 2 +- .../SlashCommands/GMZeroCommands.cpp | 4 +-- .../Map/General/BankInteractServer.cpp | 2 +- .../02_server/Map/General/MailBoxServer.cpp | 2 +- .../Map/General/StoryBoxInteractServer.cpp | 2 +- dScripts/02_server/Map/NS/NsLegoClubDoor.cpp | 30 +++++++++---------- dScripts/02_server/Map/NS/NsLupTeleport.cpp | 20 ++++++------- .../Map/Property/PropertyBankInteract.cpp | 2 +- dWorldServer/WorldServer.cpp | 5 +++- tests/dCommonTests/Amf3Tests.cpp | 8 +++-- 12 files changed, 54 insertions(+), 49 deletions(-) diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h index af1b9142..fc3b5d61 100644 --- a/dCommon/Amf3.h +++ b/dCommon/Amf3.h @@ -1,5 +1,5 @@ -#ifndef __AMF3__H__ -#define __AMF3__H__ +#ifndef AMF3_H +#define AMF3_H #include "dCommonVars.h" #include "Logger.h" @@ -64,10 +64,6 @@ template class AMFValue; template class AMFValue; template class AMFValue; -// Blank specialization to make sure AMFValue fails -template <> -class AMFValue {}; - // AMFValue template class member function instantiations template <> [[nodiscard]] constexpr eAmf AMFValue::GetValueType() const noexcept { return eAmf::Null; } template <> [[nodiscard]] constexpr eAmf AMFValue::GetValueType() const noexcept { return m_Data ? eAmf::True : eAmf::False; } @@ -85,6 +81,10 @@ using AMFIntValue = AMFValue; using AMFStringValue = AMFValue; using AMFDoubleValue = AMFValue; +// Template deduction guide to ensure string literals deduce +template +AMFValue(const char (&)[N]) -> AMFStringValue; + /** * The AMFArrayValue object holds 2 types of lists: * An associative list where a key maps to a value @@ -345,4 +345,4 @@ private: AMFDense m_Dense; }; -#endif //!__AMF3__H__ +#endif //!AMF3_H diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index d3ea1989..cb8afd5a 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -258,8 +258,8 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { if (!characterComponent) return; AMFArrayValue args; - args.Insert("amount", std::to_string(difference)); - args.Insert("type", "health"); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "health"); GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } @@ -300,8 +300,8 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { if (!characterComponent) return; AMFArrayValue args; - args.Insert("amount", std::to_string(value)); - args.Insert("type", "armor"); + args.Insert("amount", std::to_string(value)); + args.Insert("type", "armor"); GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } @@ -341,8 +341,8 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { if (!characterComponent) return; AMFArrayValue args; - args.Insert("amount", std::to_string(difference)); - args.Insert("type", "imagination"); + args.Insert("amount", std::to_string(difference)); + args.Insert("type", "imagination"); GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args); } diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index 4cc0580b..ab3bb5da 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -36,7 +36,7 @@ void PropertyEntranceComponent::OnUse(Entity* entity) { AMFArrayValue args; - args.Insert("state", "property_menu"); + args.Insert("state", "property_menu"); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } diff --git a/dGame/dUtilities/SlashCommands/GMZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMZeroCommands.cpp index 855bb714..6c9811c2 100644 --- a/dGame/dUtilities/SlashCommands/GMZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMZeroCommands.cpp @@ -98,7 +98,7 @@ namespace GMZeroCommands { { AMFArrayValue args; - args.Insert("state", "Story"); + args.Insert("state", "Story"); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } @@ -121,7 +121,7 @@ namespace GMZeroCommands { { AMFArrayValue args; - args.Insert("state", "Story"); + args.Insert("state", "Story"); GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args); } diff --git a/dScripts/02_server/Map/General/BankInteractServer.cpp b/dScripts/02_server/Map/General/BankInteractServer.cpp index cfb8357f..9b563491 100644 --- a/dScripts/02_server/Map/General/BankInteractServer.cpp +++ b/dScripts/02_server/Map/General/BankInteractServer.cpp @@ -6,7 +6,7 @@ void BankInteractServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - args.Insert("state", "bank"); + args.Insert("state", "bank"); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } diff --git a/dScripts/02_server/Map/General/MailBoxServer.cpp b/dScripts/02_server/Map/General/MailBoxServer.cpp index 340529a5..53f3b3a2 100644 --- a/dScripts/02_server/Map/General/MailBoxServer.cpp +++ b/dScripts/02_server/Map/General/MailBoxServer.cpp @@ -6,7 +6,7 @@ void MailBoxServer::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - args.Insert("state", "Mail"); + args.Insert("state", "Mail"); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } diff --git a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp index f8528b2f..4ad78d6a 100644 --- a/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp +++ b/dScripts/02_server/Map/General/StoryBoxInteractServer.cpp @@ -12,7 +12,7 @@ void StoryBoxInteractServer::OnUse(Entity* self, Entity* user) { { AMFArrayValue args; - args.Insert("state", "Story"); + args.Insert("state", "Story"); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); } diff --git a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp index c945a9e2..959466e9 100644 --- a/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp +++ b/dScripts/02_server/Map/NS/NsLegoClubDoor.cpp @@ -13,27 +13,27 @@ void NsLegoClubDoor::OnStartup(Entity* self) { args = {}; args.Insert("callbackClient", std::to_string(self->GetObjectID())); - args.Insert("strIdentifier", "choiceDoor"); - args.Insert("title", "%[UI_CHOICE_DESTINATION]"); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); AMFArrayValue* choiceOptions = args.InsertArray("options"); { AMFArrayValue* nsArgs = choiceOptions->PushArray(); - nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); - nsArgs->Insert("identifier", "zoneID_1200"); - nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { AMFArrayValue* ntArgs = choiceOptions->PushArray(); - ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); - ntArgs->Insert("identifier", "zoneID_1900"); - ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } options = choiceOptions; @@ -46,8 +46,8 @@ void NsLegoClubDoor::OnUse(Entity* self, Entity* user) { AMFArrayValue multiArgs; multiArgs.Insert("callbackClient", std::to_string(self->GetObjectID())); - multiArgs.Insert("strIdentifier", "choiceDoor"); - multiArgs.Insert("title", "%[UI_CHOICE_DESTINATION]"); + multiArgs.Insert("strIdentifier", "choiceDoor"); + multiArgs.Insert("title", "%[UI_CHOICE_DESTINATION]"); multiArgs.Insert("options", static_cast(options)); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "QueueChoiceBox", multiArgs); @@ -55,13 +55,13 @@ void NsLegoClubDoor::OnUse(Entity* self, Entity* user) { multiArgs.Remove("options", false); // We do not want the local amf to delete the options! } else if (self->GetVar(u"currentZone") != m_ChoiceZoneID) { AMFArrayValue multiArgs; - multiArgs.Insert("state", "Lobby"); + multiArgs.Insert("state", "Lobby"); AMFArrayValue* context = multiArgs.InsertArray("context"); context->Insert("user", std::to_string(player->GetObjectID())); context->Insert("callbackObj", std::to_string(self->GetObjectID())); - context->Insert("HelpVisible", "show"); - context->Insert("type", "Lego_Club_Valid"); + context->Insert("HelpVisible", "show"); + context->Insert("type", "Lego_Club_Valid"); GameMessages::SendUIMessageServerToSingleClient(player, player->GetSystemAddress(), "pushGameState", multiArgs); } else { diff --git a/dScripts/02_server/Map/NS/NsLupTeleport.cpp b/dScripts/02_server/Map/NS/NsLupTeleport.cpp index d92f6132..6886b4cd 100644 --- a/dScripts/02_server/Map/NS/NsLupTeleport.cpp +++ b/dScripts/02_server/Map/NS/NsLupTeleport.cpp @@ -13,27 +13,27 @@ void NsLupTeleport::OnStartup(Entity* self) { args = {}; args.Insert("callbackClient", std::to_string(self->GetObjectID())); - args.Insert("strIdentifier", "choiceDoor"); - args.Insert("title", "%[UI_CHOICE_DESTINATION]"); + args.Insert("strIdentifier", "choiceDoor"); + args.Insert("title", "%[UI_CHOICE_DESTINATION]"); AMFArrayValue* choiceOptions = args.InsertArray("options"); { AMFArrayValue* nsArgs = choiceOptions->PushArray(); - nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); - nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); - nsArgs->Insert("identifier", "zoneID_1200"); - nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); + nsArgs->Insert("image", "textures/ui/zone_thumnails/Nimbus_Station.dds"); + nsArgs->Insert("caption", "%[UI_CHOICE_NS]"); + nsArgs->Insert("identifier", "zoneID_1200"); + nsArgs->Insert("tooltipText", "%[UI_CHOICE_NS_HOVER]"); } { AMFArrayValue* ntArgs = choiceOptions->PushArray(); - ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); - ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); - ntArgs->Insert("identifier", "zoneID_1900"); - ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); + ntArgs->Insert("image", "textures/ui/zone_thumnails/Nexus_Tower.dds"); + ntArgs->Insert("caption", "%[UI_CHOICE_NT]"); + ntArgs->Insert("identifier", "zoneID_1900"); + ntArgs->Insert("tooltipText", "%[UI_CHOICE_NT_HOVER]"); } } diff --git a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp index 5e4288d5..50fea9a0 100644 --- a/dScripts/02_server/Map/Property/PropertyBankInteract.cpp +++ b/dScripts/02_server/Map/Property/PropertyBankInteract.cpp @@ -22,7 +22,7 @@ void PropertyBankInteract::OnUse(Entity* self, Entity* user) { AMFArrayValue args; - args.Insert("state", "bank"); + args.Insert("state", "bank"); GameMessages::SendUIMessageServerToSingleClient(user, user->GetSystemAddress(), "pushGameState", args); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 30ba9521..c6c894b4 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -1396,7 +1396,10 @@ void HandlePacket(Packet* packet) { } default: - const auto messageId = static_cast(packet->data[3]); + // Need to use memcpy instead of reinterpret_cast to avoid UB + MessageType::World messageId; + std::memcpy(&messageId, &packet->data[3], sizeof(MessageType::World)); + const std::string_view messageIdString = StringifiedEnum::ToString(messageId); LOG("Unknown world packet received: %4i, %s", messageId, messageIdString.data()); } diff --git a/tests/dCommonTests/Amf3Tests.cpp b/tests/dCommonTests/Amf3Tests.cpp index 74614c51..79d0d496 100644 --- a/tests/dCommonTests/Amf3Tests.cpp +++ b/tests/dCommonTests/Amf3Tests.cpp @@ -61,8 +61,8 @@ TEST(dCommonTests, AMF3AssociativeArrayTest) { TEST(dCommonTests, AMF3InsertionAssociativeTest) { AMFArrayValue array; - array.Insert("CString", "string"); - array.Insert("String", std::string("string")); + array.Insert("CString", "string"); + array.Insert("String", std::string("string")); array.Insert("False", false); array.Insert("True", true); array.Insert("Integer", 42U); @@ -71,6 +71,7 @@ TEST(dCommonTests, AMF3InsertionAssociativeTest) { array.Insert>("Undefined", {}); array.Insert("Null", nullptr); + ASSERT_EQ(array.Get("CString")->GetValueType(), eAmf::String); ASSERT_EQ(array.Get("String")->GetValueType(), eAmf::String); ASSERT_EQ(array.Get("False")->GetValueType(), eAmf::False); ASSERT_EQ(array.Get("True")->GetValueType(), eAmf::True); @@ -84,7 +85,7 @@ TEST(dCommonTests, AMF3InsertionAssociativeTest) { TEST(dCommonTests, AMF3InsertionDenseTest) { AMFArrayValue array; array.Push("string"); - array.Push("CString"); + array.Push("CString"); array.Push(false); array.Push(true); array.Push(42U); @@ -94,6 +95,7 @@ TEST(dCommonTests, AMF3InsertionDenseTest) { array.Push>({}); ASSERT_EQ(array.Get(0)->GetValueType(), eAmf::String); + ASSERT_EQ(array.Get(1)->GetValueType(), eAmf::String); ASSERT_EQ(array.Get(2)->GetValueType(), eAmf::False); ASSERT_EQ(array.Get(3)->GetValueType(), eAmf::True); ASSERT_EQ(array.Get(4)->GetValueType(), eAmf::Integer);