From a2ca2733702f2be1e8a0277c1f9ba64edc0c1b65 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Dec 2022 13:23:02 -0800 Subject: [PATCH 1/4] Cleanup behavior bitstream reads (#888) * Add failArmor server side Address out of bounds reading in behavior Address the basicAttackBehavior reading out of bounds memory and reading bits that didnt exist, which occasionally caused crashes and also caused the behavior to do undefined behavior due to the bad reads. Tested that attacking a wall anywhere with a projectile now does not crash the game. Tested with logs that the behavior correctly returned when there were no allocated bits or returned when other states were met. Add back logs and add fail handle Remove comment block Revert "Add back logs and add fail handle" This reverts commit db19be0906fc8bf35bf89037e2bfba39f5ef9c0c. Split out checks * Cleanup Behavior streams --- dGame/dBehaviors/AirMovementBehavior.cpp | 27 +++++++++++++------ dGame/dBehaviors/AirMovementBehavior.h | 2 +- dGame/dBehaviors/AreaOfEffectBehavior.cpp | 16 ++++++++--- dGame/dBehaviors/AttackDelayBehavior.cpp | 7 +++-- dGame/dBehaviors/ChainBehavior.cpp | 15 +++++++---- dGame/dBehaviors/ChargeUpBehavior.cpp | 8 ++++-- dGame/dBehaviors/ForceMovementBehavior.cpp | 23 +++++++++++----- dGame/dBehaviors/InterruptBehavior.cpp | 15 ++++++++--- dGame/dBehaviors/KnockbackBehavior.cpp | 9 +++++-- dGame/dBehaviors/MovementSwitchBehavior.cpp | 9 ++++--- dGame/dBehaviors/ProjectileAttackBehavior.cpp | 21 ++++++++++----- dGame/dBehaviors/StunBehavior.cpp | 7 +++-- dGame/dBehaviors/SwitchBehavior.cpp | 5 +++- dGame/dBehaviors/SwitchMultipleBehavior.cpp | 12 +++++---- dGame/dBehaviors/TacArcBehavior.cpp | 18 +++++++++---- 15 files changed, 138 insertions(+), 56 deletions(-) diff --git a/dGame/dBehaviors/AirMovementBehavior.cpp b/dGame/dBehaviors/AirMovementBehavior.cpp index 469ac6e4..932297b9 100644 --- a/dGame/dBehaviors/AirMovementBehavior.cpp +++ b/dGame/dBehaviors/AirMovementBehavior.cpp @@ -2,11 +2,16 @@ #include "BehaviorBranchContext.h" #include "BehaviorContext.h" #include "EntityManager.h" +#include "Game.h" +#include "dLogger.h" void AirMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("AirMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } context->RegisterSyncBehavior(handle, this, branch); } @@ -17,14 +22,20 @@ void AirMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream->Write(handle); } -void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { - uint32_t behaviorId; +void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + uint32_t behaviorId{}; - bit_stream->Read(behaviorId); + if (!bitStream->Read(behaviorId)) { + Game::logger->Log("AirMovementBehavior", "Unable to read behaviorId from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - LWOOBJID target; + LWOOBJID target{}; - bit_stream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("AirMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } auto* behavior = CreateBehavior(behaviorId); @@ -32,7 +43,7 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bit_ branch.target = target; } - behavior->Handle(context, bit_stream, branch); + behavior->Handle(context, bitStream, branch); } void AirMovementBehavior::Load() { diff --git a/dGame/dBehaviors/AirMovementBehavior.h b/dGame/dBehaviors/AirMovementBehavior.h index 323edf37..89dc1e05 100644 --- a/dGame/dBehaviors/AirMovementBehavior.h +++ b/dGame/dBehaviors/AirMovementBehavior.h @@ -16,7 +16,7 @@ public: void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; - void Sync(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) override; + void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; void Load() override; }; diff --git a/dGame/dBehaviors/AreaOfEffectBehavior.cpp b/dGame/dBehaviors/AreaOfEffectBehavior.cpp index 898d1f99..ca3bdf93 100644 --- a/dGame/dBehaviors/AreaOfEffectBehavior.cpp +++ b/dGame/dBehaviors/AreaOfEffectBehavior.cpp @@ -9,11 +9,16 @@ #include "BehaviorContext.h" #include "RebuildComponent.h" #include "DestroyableComponent.h" +#include "Game.h" +#include "dLogger.h" void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t targetCount; + uint32_t targetCount{}; - bitStream->Read(targetCount); + if (!bitStream->Read(targetCount)) { + Game::logger->Log("AreaOfEffectBehavior", "Unable to read targetCount from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } if (targetCount > this->m_maxTargets) { return; @@ -24,9 +29,12 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b targets.reserve(targetCount); for (auto i = 0u; i < targetCount; ++i) { - LWOOBJID target; + LWOOBJID target{}; - bitStream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("AreaOfEffectBehavior", "failed to read in target %i from bitStream, aborting target Handle!", i); + return; + }; targets.push_back(target); } diff --git a/dGame/dBehaviors/AttackDelayBehavior.cpp b/dGame/dBehaviors/AttackDelayBehavior.cpp index 450741ec..201921a3 100644 --- a/dGame/dBehaviors/AttackDelayBehavior.cpp +++ b/dGame/dBehaviors/AttackDelayBehavior.cpp @@ -5,9 +5,12 @@ #include "dLogger.h" void AttackDelayBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("AttackDelayBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; for (auto i = 0u; i < this->m_numIntervals; ++i) { context->RegisterSyncBehavior(handle, this, branch); diff --git a/dGame/dBehaviors/ChainBehavior.cpp b/dGame/dBehaviors/ChainBehavior.cpp index 3ef8c15b..ec0f8969 100644 --- a/dGame/dBehaviors/ChainBehavior.cpp +++ b/dGame/dBehaviors/ChainBehavior.cpp @@ -4,14 +4,19 @@ #include "dLogger.h" void ChainBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t chain_index; + uint32_t chainIndex{}; - bitStream->Read(chain_index); + if (!bitStream->Read(chainIndex)) { + Game::logger->Log("ChainBehavior", "Unable to read chainIndex from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - chain_index--; + chainIndex--; - if (chain_index < this->m_behaviors.size()) { - this->m_behaviors.at(chain_index)->Handle(context, bitStream, branch); + if (chainIndex < this->m_behaviors.size()) { + this->m_behaviors.at(chainIndex)->Handle(context, bitStream, branch); + } else { + Game::logger->Log("ChainBehavior", "chainIndex out of bounds, aborting handle of chain %i bits unread %i", chainIndex, bitStream->GetNumberOfUnreadBits()); } } diff --git a/dGame/dBehaviors/ChargeUpBehavior.cpp b/dGame/dBehaviors/ChargeUpBehavior.cpp index fa9fa34b..1b9ba433 100644 --- a/dGame/dBehaviors/ChargeUpBehavior.cpp +++ b/dGame/dBehaviors/ChargeUpBehavior.cpp @@ -1,12 +1,16 @@ #include "ChargeUpBehavior.h" #include "BehaviorBranchContext.h" #include "BehaviorContext.h" +#include "Game.h" #include "dLogger.h" void ChargeUpBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { - uint32_t handle; + uint32_t handle{}; - bitStream->Read(handle); + if (!bitStream->Read(handle)) { + Game::logger->Log("ChargeUpBehavior", "Unable to read handle from bitStream, aborting Handle! variable_type"); + return; + }; context->RegisterSyncBehavior(handle, this, branch); } diff --git a/dGame/dBehaviors/ForceMovementBehavior.cpp b/dGame/dBehaviors/ForceMovementBehavior.cpp index e1ac6133..e095447c 100644 --- a/dGame/dBehaviors/ForceMovementBehavior.cpp +++ b/dGame/dBehaviors/ForceMovementBehavior.cpp @@ -3,23 +3,34 @@ #include "BehaviorContext.h" #include "ControllablePhysicsComponent.h" #include "EntityManager.h" +#include "Game.h" +#include "dLogger.h" void ForceMovementBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) { if (this->m_hitAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitEnemyAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY && this->m_hitFactionAction->m_templateId == BehaviorTemplates::BEHAVIOR_EMPTY) { return; } - uint32_t handle; - bitStream->Read(handle); + uint32_t handle{}; + if (!bitStream->Read(handle)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read handle from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + } context->RegisterSyncBehavior(handle, this, branch); } void ForceMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - uint32_t next; - bitStream->Read(next); + uint32_t next{}; + if (!bitStream->Read(next)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } - LWOOBJID target; - bitStream->Read(target); + LWOOBJID target{}; + if (!bitStream->Read(target)) { + Game::logger->Log("ForceMovementBehavior", "Unable to read target from bitStream, aborting Sync! %i", bitStream->GetNumberOfUnreadBits()); + return; + } branch.target = target; auto* behavior = CreateBehavior(next); diff --git a/dGame/dBehaviors/InterruptBehavior.cpp b/dGame/dBehaviors/InterruptBehavior.cpp index b42eadb0..9035c092 100644 --- a/dGame/dBehaviors/InterruptBehavior.cpp +++ b/dGame/dBehaviors/InterruptBehavior.cpp @@ -11,7 +11,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (branch.target != context->originator) { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown1 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; if (unknown) return; } @@ -19,7 +22,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS if (!this->m_interruptBlock) { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown2 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; if (unknown) return; } @@ -28,7 +34,10 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS { bool unknown = false; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("InterruptBehavior", "Unable to read unknown3 from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } if (branch.target == context->originator) return; diff --git a/dGame/dBehaviors/KnockbackBehavior.cpp b/dGame/dBehaviors/KnockbackBehavior.cpp index 83c82010..1b878ed0 100644 --- a/dGame/dBehaviors/KnockbackBehavior.cpp +++ b/dGame/dBehaviors/KnockbackBehavior.cpp @@ -6,11 +6,16 @@ #include "EntityManager.h" #include "GameMessages.h" #include "DestroyableComponent.h" +#include "Game.h" +#include "dLogger.h" void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - bool unknown; + bool unknown{}; - bitStream->Read(unknown); + if (!bitStream->Read(unknown)) { + Game::logger->Log("KnockbackBehavior", "Unable to read unknown from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { diff --git a/dGame/dBehaviors/MovementSwitchBehavior.cpp b/dGame/dBehaviors/MovementSwitchBehavior.cpp index 17ed5c40..c893e6e1 100644 --- a/dGame/dBehaviors/MovementSwitchBehavior.cpp +++ b/dGame/dBehaviors/MovementSwitchBehavior.cpp @@ -13,9 +13,11 @@ void MovementSwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* return; } - uint32_t movementType; - - bitStream->Read(movementType); + uint32_t movementType{}; + if (!bitStream->Read(movementType)) { + Game::logger->Log("MovementSwitchBehavior", "Unable to read movementType from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; switch (movementType) { case 1: @@ -55,4 +57,3 @@ void MovementSwitchBehavior::Load() { this->m_jumpAction = GetAction("jump_action"); } - diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index 350234e2..c14f032d 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -8,9 +8,12 @@ #include "../dWorldServer/ObjectIDManager.h" void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { - LWOOBJID target; + LWOOBJID target{}; - bitStream->Read(target); + if (!bitStream->Read(target)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read target from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; auto* entity = EntityManager::Instance()->GetEntity(context->originator); @@ -30,15 +33,21 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea if (m_useMouseposit) { NiPoint3 targetPosition = NiPoint3::ZERO; - bitStream->Read(targetPosition); + if (!bitStream->Read(targetPosition)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read targetPosition from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } auto* targetEntity = EntityManager::Instance()->GetEntity(target); for (auto i = 0u; i < this->m_projectileCount; ++i) { - LWOOBJID projectileId; + LWOOBJID projectileId{}; - bitStream->Read(projectileId); + if (!bitStream->Read(projectileId)) { + Game::logger->Log("ProjectileAttackBehavior", "Unable to read projectileId from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; branch.target = target; branch.isProjectile = true; @@ -98,7 +107,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt for (auto i = 0u; i < this->m_projectileCount; ++i) { auto id = static_cast(ObjectIDManager::Instance()->GenerateObjectID()); - id = GeneralUtils::SetBit(id, OBJECT_BIT_CLIENT); + id = GeneralUtils::SetBit(id, OBJECT_BIT_SPAWNED); bitStream->Write(id); diff --git a/dGame/dBehaviors/StunBehavior.cpp b/dGame/dBehaviors/StunBehavior.cpp index 59a81440..065b7220 100644 --- a/dGame/dBehaviors/StunBehavior.cpp +++ b/dGame/dBehaviors/StunBehavior.cpp @@ -14,8 +14,11 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream return; } - bool blocked; - bitStream->Read(blocked); + bool blocked{}; + if (!bitStream->Read(blocked)) { + Game::logger->Log("StunBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; auto* target = EntityManager::Instance()->GetEntity(branch.target); diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index 78271b99..f6eb3ff5 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -10,7 +10,10 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre auto state = true; if (this->m_imagination > 0 || !this->m_isEnemyFaction) { - bitStream->Read(state); + if (!bitStream->Read(state)) { + Game::logger->Log("SwitchBehavior", "Unable to read state from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + return; + }; } auto* entity = EntityManager::Instance()->GetEntity(context->originator); diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 946e5e0f..e92393fc 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -9,10 +9,12 @@ #include "EntityManager.h" -void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { - float value; +void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + float value{}; - bit_stream->Read(value); + if (!bitStream->Read(value)) { + Game::logger->Log("SwitchMultipleBehavior", "Unable to read value from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; uint32_t trigger = 0; @@ -30,10 +32,10 @@ void SwitchMultipleBehavior::Handle(BehaviorContext* context, RakNet::BitStream* auto* behavior = this->m_behaviors.at(trigger).second; - behavior->Handle(context, bit_stream, branch); + behavior->Handle(context, bitStream, branch); } -void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bit_stream, BehaviorBranchContext branch) { +void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { // TODO } diff --git a/dGame/dBehaviors/TacArcBehavior.cpp b/dGame/dBehaviors/TacArcBehavior.cpp index 8789f9b6..38efdea4 100644 --- a/dGame/dBehaviors/TacArcBehavior.cpp +++ b/dGame/dBehaviors/TacArcBehavior.cpp @@ -20,12 +20,16 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre bool hit = false; - bitStream->Read(hit); + if (!bitStream->Read(hit)) { + Game::logger->Log("TacArcBehavior", "Unable to read hit from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (this->m_checkEnv) { bool blocked = false; - bitStream->Read(blocked); + if (!bitStream->Read(blocked)) { + Game::logger->Log("TacArcBehavior", "Unable to read blocked from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (blocked) { this->m_blockedAction->Handle(context, bitStream, branch); @@ -37,7 +41,9 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre if (hit) { uint32_t count = 0; - bitStream->Read(count); + if (!bitStream->Read(count)) { + Game::logger->Log("TacArcBehavior", "Unable to read count from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; if (count > m_maxTargets && m_maxTargets > 0) { count = m_maxTargets; @@ -46,9 +52,11 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre std::vector targets; for (auto i = 0u; i < count; ++i) { - LWOOBJID id; + LWOOBJID id{}; - bitStream->Read(id); + if (!bitStream->Read(id)) { + Game::logger->Log("TacArcBehavior", "Unable to read id from bitStream, aborting Handle! %i", bitStream->GetNumberOfUnreadBits()); + }; targets.push_back(id); } From cd78a3dec72ac2e4c427ef21c9fbcb452fc02fe5 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 16 Dec 2022 13:23:09 -0800 Subject: [PATCH 2/4] Fix cannon super charge speed (#883) * Fix cannon * Update SGCannon.cpp --- dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 049837a4..912b9f58 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -722,7 +722,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { Game::logger->Log("SGCannon", "Player has %d equipped items", equippedItems.size()); auto skillID = constants.cannonSkill; - auto coolDown = constants.cannonRefireRate; + auto cooldown = constants.cannonRefireRate; auto* selfInventoryComponent = self->GetComponent(); @@ -738,7 +738,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { // TODO: Equip items skillID = constants.cannonSuperChargeSkill; - coolDown = 400; + cooldown = 400; } else { selfInventoryComponent->UpdateSlot("greeble_r", { ObjectIDManager::GenerateRandomObjectID(), 0, 0, 0 }); selfInventoryComponent->UpdateSlot("greeble_l", { ObjectIDManager::GenerateRandomObjectID(), 0, 0, 0 }); @@ -761,7 +761,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { } } } - + cooldown = 800; self->SetVar(NumberOfChargesVariable, 0); } @@ -777,7 +777,7 @@ void SGCannon::ToggleSuperCharge(Entity* self, bool enable) { properties.cannonFOV = 58.6f; properties.cannonVelocity = 129.0; - properties.cannonRefireRate = 800; + properties.cannonRefireRate = cooldown; properties.cannonMinDistance = 30; properties.cannonTimeout = -1; From 32f8bda53866996de7ece9cb591e2b82d1fb7e9c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Dec 2022 15:23:38 -0600 Subject: [PATCH 3/4] Allow the player to be interrupted (#881) --- dGame/dComponents/SkillComponent.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index c749dbaf..445a837e 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -181,17 +181,11 @@ void SkillComponent::Reset() { } void SkillComponent::Interrupt() { - if (m_Parent->IsPlayer()) return; - + // TODO: need to check immunities on the destroyable component, but they aren't implemented auto* combat = m_Parent->GetComponent(); + if (combat != nullptr && combat->GetStunImmune()) return; - if (combat != nullptr && combat->GetStunImmune()) { - return; - } - - for (const auto& behavior : this->m_managedBehaviors) { - behavior.second->Interrupt(); - } + for (const auto& behavior : this->m_managedBehaviors) behavior.second->Interrupt(); } void SkillComponent::RegisterCalculatedProjectile(const LWOOBJID projectileId, BehaviorContext* context, const BehaviorBranchContext& branch, const LOT lot, const float maxTime, From 631365b7f70fe138fe39a390d5fac2134ffcca5e Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 16 Dec 2022 15:24:13 -0600 Subject: [PATCH 4/4] Add change idle flags behavior and GM (#871) * update naming for animation flag enum value 0 * Add change idle flags behaviors and GM * default to 0 when none is given --- dCommon/dEnums/dMessageIdentifiers.h | 1 + dCommon/dEnums/eAninmationFlags.h | 2 +- dGame/dBehaviors/Behavior.cpp | 5 ++- dGame/dBehaviors/CMakeLists.txt | 1 + dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp | 37 ++++++++++++++++++++ dGame/dBehaviors/ChangeIdleFlagsBehavior.h | 23 ++++++++++++ dGame/dBehaviors/SwitchBehavior.cpp | 2 +- dGame/dComponents/PossessableComponent.cpp | 4 +-- dGame/dComponents/PossessableComponent.h | 2 +- dGame/dGameMessages/GameMessages.cpp | 12 +++++++ dGame/dGameMessages/GameMessages.h | 10 ++++++ 11 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp create mode 100644 dGame/dBehaviors/ChangeIdleFlagsBehavior.h diff --git a/dCommon/dEnums/dMessageIdentifiers.h b/dCommon/dEnums/dMessageIdentifiers.h index 5a5c9088..129585a0 100644 --- a/dCommon/dEnums/dMessageIdentifiers.h +++ b/dCommon/dEnums/dMessageIdentifiers.h @@ -488,6 +488,7 @@ enum GAME_MSG : unsigned short { GAME_MSG_MATCH_UPDATE = 1310, GAME_MSG_MODULE_ASSEMBLY_DB_DATA_FOR_CLIENT = 1131, GAME_MSG_MODULE_ASSEMBLY_QUERY_DATA = 1132, + GAME_MSG_CHANGE_IDLE_FLAGS = 1338, GAME_MSG_VEHICLE_ADD_PASSIVE_BOOST_ACTION = 1340, GAME_MSG_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION = 1341, GAME_MSG_VEHICLE_NOTIFY_SERVER_ADD_PASSIVE_BOOST_ACTION = 1342, diff --git a/dCommon/dEnums/eAninmationFlags.h b/dCommon/dEnums/eAninmationFlags.h index 9b2ea3fb..ce235ae9 100644 --- a/dCommon/dEnums/eAninmationFlags.h +++ b/dCommon/dEnums/eAninmationFlags.h @@ -6,7 +6,7 @@ #include enum class eAnimationFlags : uint32_t { - IDLE_INVALID = 0, // made up, for internal use!!! + IDLE_NONE = 0, IDLE_BASIC, IDLE_SWIM, IDLE_CARRY, diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index d0d6192b..cd9304d3 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -60,6 +60,7 @@ #include "SpeedBehavior.h" #include "DamageReductionBehavior.h" #include "JetPackBehavior.h" +#include "ChangeIdleFlagsBehavior.h" //CDClient includes #include "CDBehaviorParameterTable.h" @@ -196,7 +197,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { behavior = new SkillCastFailedBehavior(behaviorId); break; case BehaviorTemplates::BEHAVIOR_IMITATION_SKUNK_STINK: break; - case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS: break; + case BehaviorTemplates::BEHAVIOR_CHANGE_IDLE_FLAGS: + behavior = new ChangeIdleFlagsBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_APPLY_BUFF: behavior = new ApplyBuffBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 297c389b..40ac0a9c 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -12,6 +12,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "BuffBehavior.cpp" "CarBoostBehavior.cpp" "ChainBehavior.cpp" + "ChangeIdleFlagsBehavior.cpp" "ChangeOrientationBehavior.cpp" "ChargeUpBehavior.cpp" "ClearTargetBehavior.cpp" diff --git a/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp b/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp new file mode 100644 index 00000000..06a79fa7 --- /dev/null +++ b/dGame/dBehaviors/ChangeIdleFlagsBehavior.cpp @@ -0,0 +1,37 @@ + +#include "ChangeIdleFlagsBehavior.h" +#include "BehaviorContext.h" +#include "BehaviorBranchContext.h" + +void ChangeIdleFlagsBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; + if (!target) return; + + GameMessages::SendChangeIdleFlags(target, m_FlagsOn, m_FlagsOff, UNASSIGNED_SYSTEM_ADDRESS); + + if (branch.duration > 0.0f) { + context->RegisterTimerBehavior(this, branch); + } else if (branch.start > 0) { + context->RegisterEndBehavior(this, branch); + } +} + +void ChangeIdleFlagsBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); +} + +void ChangeIdleFlagsBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator; + if (!target) return; + // flip on and off to end behavior + GameMessages::SendChangeIdleFlags(target, m_FlagsOff, m_FlagsOn, UNASSIGNED_SYSTEM_ADDRESS); +} + +void ChangeIdleFlagsBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) { + End(context, branch, second); +} + +void ChangeIdleFlagsBehavior::Load() { + m_FlagsOff = static_cast(GetInt("flags_off", 0)); + m_FlagsOn = static_cast(GetInt("flags_on", 0)); +} diff --git a/dGame/dBehaviors/ChangeIdleFlagsBehavior.h b/dGame/dBehaviors/ChangeIdleFlagsBehavior.h new file mode 100644 index 00000000..91f802f4 --- /dev/null +++ b/dGame/dBehaviors/ChangeIdleFlagsBehavior.h @@ -0,0 +1,23 @@ + +#pragma once +#include "Behavior.h" +#include "eAninmationFlags.h" + +class ChangeIdleFlagsBehavior final : public Behavior { +public: + + /* + * Inherited + */ + explicit ChangeIdleFlagsBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} + + void Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) override; + void Load() override; + +private: + eAnimationFlags m_FlagsOff; + eAnimationFlags m_FlagsOn; +}; diff --git a/dGame/dBehaviors/SwitchBehavior.cpp b/dGame/dBehaviors/SwitchBehavior.cpp index f6eb3ff5..c010f31b 100644 --- a/dGame/dBehaviors/SwitchBehavior.cpp +++ b/dGame/dBehaviors/SwitchBehavior.cpp @@ -28,7 +28,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre return; } - Game::logger->Log("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); + Game::logger->LogDebug("SwitchBehavior", "[%i] State: (%d), imagination: (%i) / (%f)", entity->GetLOT(), state, destroyableComponent->GetImagination(), destroyableComponent->GetMaxImagination()); if (state || (entity->GetLOT() == 8092 && destroyableComponent->GetImagination() >= m_imagination)) { this->m_actionTrue->Handle(context, bitStream, branch); diff --git a/dGame/dComponents/PossessableComponent.cpp b/dGame/dComponents/PossessableComponent.cpp index 37591532..5c45a6c1 100644 --- a/dGame/dComponents/PossessableComponent.cpp +++ b/dGame/dComponents/PossessableComponent.cpp @@ -34,8 +34,8 @@ void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_Possessor != LWOOBJID_EMPTY); if (m_Possessor != LWOOBJID_EMPTY) outBitStream->Write(m_Possessor); - outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_INVALID); - if (m_AnimationFlag != eAnimationFlags::IDLE_INVALID) outBitStream->Write(m_AnimationFlag); + outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_NONE); + if (m_AnimationFlag != eAnimationFlags::IDLE_NONE) outBitStream->Write(m_AnimationFlag); outBitStream->Write(m_ImmediatelyDepossess); m_ImmediatelyDepossess = false; // reset flag diff --git a/dGame/dComponents/PossessableComponent.h b/dGame/dComponents/PossessableComponent.h index 43ce8610..e1dc5ccd 100644 --- a/dGame/dComponents/PossessableComponent.h +++ b/dGame/dComponents/PossessableComponent.h @@ -109,7 +109,7 @@ private: * @brief What animaiton flag to use * */ - eAnimationFlags m_AnimationFlag = eAnimationFlags::IDLE_INVALID; + eAnimationFlags m_AnimationFlag = eAnimationFlags::IDLE_NONE; /** * @brief Should this be immediately depossessed diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index fcc25fdc..8c82f644 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -3922,6 +3922,18 @@ void GameMessages::SendDisplayChatBubble(LWOOBJID objectId, const std::u16string SEND_PACKET; } + +void GameMessages::SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags FlagsOn, eAnimationFlags FlagsOff, const SystemAddress& sysAddr) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(objectId); + bitStream.Write(GAME_MSG::GAME_MSG_CHANGE_IDLE_FLAGS); + bitStream.Write(FlagsOff); + bitStream.Write(FlagsOn); + + SEND_PACKET_BROADCAST; +} // Mounts void GameMessages::SendSetMountInventoryID(Entity* entity, const LWOOBJID& objectID, const SystemAddress& sysAddr) { diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index f9968d14..4f92480f 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -14,6 +14,7 @@ #include "TradingManager.h" #include "LeaderboardManager.h" #include "MovingPlatformComponent.h" +#include "eAninmationFlags.h" class NiQuaternion; class User; @@ -373,6 +374,15 @@ namespace GameMessages { void SendDisplayChatBubble(LWOOBJID objectId, const std::u16string& text, const SystemAddress& sysAddr); + /** + * @brief + * + * @param objectId ID of the entity to set idle flags + * @param FlagsOn Flag to turn on + * @param FlagsOff Flag to turn off + */ + void SendChangeIdleFlags(LWOOBJID objectId, eAnimationFlags FlagsOn, eAnimationFlags FlagsOff, const SystemAddress& sysAddr); + // Mounts /** * @brief Set the Inventory LWOOBJID of the mount