Implement basic functionality (#794)

Implements the basic functionality and parsing of property behaviors.

Unhandled messages and logged and discarded for the time being.  The only implemented message is a basic one that sends the needed info the the client side User Interface to pop up.

Tested that the User Interface properly shows up with zero behaviors on it.  No other functionality is changed.
This commit is contained in:
David Markowitz 2022-10-31 15:32:07 -07:00 committed by GitHub
parent d4af7d76a2
commit 62213cd701
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 148 additions and 2 deletions

View File

@ -143,6 +143,7 @@ set(INCLUDED_DIRECTORIES
"dGame/dInventory"
"dGame/dMission"
"dGame/dEntity"
"dGame/dPropertyBehaviors"
"dGame/dUtilities"
"dPhysics"
"dNavigation"

View File

@ -44,6 +44,13 @@ foreach(file ${DGAME_DMISSION_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dMission/${file}")
endforeach()
add_subdirectory(dPropertyBehaviors)
foreach(file ${DGAME_DPROPERTYBEHAVIORS_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "dPropertyBehaviors/${file}")
endforeach()
add_subdirectory(dUtilities)
foreach(file ${DGAME_DUTILITIES_SOURCES})

View File

@ -68,6 +68,8 @@
#include "PropertyVendorComponent.h"
#include "PropertySelectQueryProperty.h"
#include "TradingManager.h"
#include "ControlBehaviors.h"
#include "AMFDeserialize.h"
void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) {
CBITSTREAM;
@ -2396,8 +2398,24 @@ void GameMessages::SendUnSmash(Entity* entity, LWOOBJID builderID, float duratio
}
void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {
// TODO
Game::logger->Log("GameMessages", "Recieved Control Behavior GameMessage, but property behaviors are unimplemented.");
AMFDeserialize reader;
std::unique_ptr<AMFValue> amfArguments(reader.Read(inStream));
if (amfArguments->GetValueType() != AMFValueType::AMFArray) return;
uint32_t commandLength{};
inStream->Read(commandLength);
std::string command;
for (uint32_t i = 0; i < commandLength; i++) {
unsigned char character;
inStream->Read(character);
command.push_back(character);
}
auto owner = PropertyManagementComponent::Instance()->GetOwner();
if (!owner) return;
ControlBehaviors::ProcessCommand(entity, sysAddr, static_cast<AMFArrayValue*>(amfArguments.get()), command, owner);
}
void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) {

View File

@ -0,0 +1,4 @@
set(DGAME_DPROPERTYBEHAVIORS_SOURCES
"ControlBehaviors.cpp"
PARENT_SCOPE
)

View File

@ -0,0 +1,81 @@
#include "ControlBehaviors.h"
#include "AMFFormat.h"
#include "Entity.h"
#include "Game.h"
#include "GameMessages.h"
#include "ModelComponent.h"
#include "dLogger.h"
void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) {
if (!modelEntity || !modelOwner || !arguments) return;
if (command == "sendBehaviorListToClient")
SendBehaviorListToClient(modelEntity, sysAddr, modelOwner);
else if (command == "modelTypeChanged")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "toggleExecutionUpdates")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "addStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "removeStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "mergeStrips")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "splitStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "updateStripUI")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "addAction")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "migrateActions")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "rearrangeStrip")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "add")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "removeActions")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "rename")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "sendBehaviorBlocksToClient")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "moveToInventory")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else if (command == "updateAction")
Game::logger->Log("ControlBehaviors", "Got command %s but is not implemented!", command.c_str());
else
Game::logger->Log("ControlBehaviors", "Unknown behavior command (%s)\n", command.c_str());
}
void ControlBehaviors::SendBehaviorListToClient(
Entity* modelEntity,
const SystemAddress& sysAddr,
Entity* modelOwner
) {
auto* modelComponent = modelEntity->GetComponent<ModelComponent>();
if (!modelComponent) return;
AMFArrayValue behaviorsToSerialize;
AMFArrayValue* behaviors = new AMFArrayValue(); // Empty for now
/**
* The behaviors AMFArray will have up to 5 elements in the dense portion.
* Each element in the dense portion will be made up of another AMFArray
* with the following information mapped in the associative portion
* "id": Behavior ID cast to an AMFString
* "isLocked": AMFTrue or AMFFalse of whether or not the behavior is locked
* "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom)
* "name": The name of the behavior formatted as an AMFString
*/
behaviorsToSerialize.InsertValue("behaviors", behaviors);
AMFStringValue* amfStringValueForObjectID = new AMFStringValue();
amfStringValueForObjectID->SetStringValue(std::to_string(modelComponent->GetParent()->GetObjectID()));
behaviorsToSerialize.InsertValue("objectID", amfStringValueForObjectID);
GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", &behaviorsToSerialize);
}

View File

@ -0,0 +1,35 @@
#pragma once
#ifndef __CONTROLBEHAVIORS__H__
#define __CONTROLBEHAVIORS__H__
#include <string>
#include "RakNetTypes.h"
class Entity;
class AMFArrayValue;
namespace ControlBehaviors {
/**
* @brief Main driver for processing Property Behavior commands
*
* @param modelEntity The model that sent this command
* @param sysAddr The SystemAddress to respond to
* @param arguments The arguments formatted as an AMFArrayValue
* @param command The command to perform
* @param modelOwner The owner of the model which sent this command
*/
void ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner);
/**
* @brief Helper function to send the behavior list to the client
*
* @param modelEntity The model that sent this command
* @param sysAddr The SystemAddress to respond to
* @param modelOwner The owner of the model which sent this command
*/
void SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner);
};
#endif //!__CONTROLBEHAVIORS__H__