Files
DarkflameServer/dGame/dComponents/ScriptComponent.cpp
Aaron Kimbrell 0138d45c58 fix(component): the zone control object constructs as on live
Minigame control (50) is an activity component in the client
(LWOMinigameComponent) and is made from the registry, so the zone control
object (LOT 2365, registry id 0) has one; it sends what an activity sends
(dirty, no players), not a fixed 0x40000000 (which nothing sent: the old
id > 0 check never made it). The zone's script on that object is server
only: the client makes no script component for it, so it sends nothing.
DLU's zone control construction now equals live's byte for byte (209
captures, e.g. GruntMonkey world2); the decoder reads 50 as an activity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:29:02 -05:00

69 lines
2.3 KiB
C++

/*
* Darkflame Universe
* Copyright 2018
*/
#include "Entity.h"
#include "ScriptComponent.h"
#include "GameMessages.h"
#include "Amf3.h"
#include <ranges>
ScriptComponent::ScriptComponent(Entity* parent, const int32_t componentID, const std::string& scriptName, bool serialized, bool client) : Component(parent, componentID) {
m_Serialized = serialized;
m_Client = client;
m_ScriptName = scriptName;
SetScript(scriptName);
Component::RegisterMsg(&ScriptComponent::OnGetObjectReportInfo);
}
void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
// A server-only script (the zone control object's) sends nothing: the client made no script component for it
if (!m_Serialized) return;
if (bIsInitialUpdate) {
const auto& networkSettings = m_Parent->GetNetworkSettings();
auto hasNetworkSettings = !networkSettings.values.empty();
outBitStream.Write(hasNetworkSettings);
if (hasNetworkSettings) {
// First write the most inner LDF data
RakNet::BitStream ldfData;
ldfData.Write<uint8_t>(0);
ldfData.Write<uint32_t>(networkSettings.values.size());
for (const auto& networkSetting : networkSettings.values | std::views::values) {
networkSetting->WriteToPacket(ldfData);
}
// Finally write everything to the stream
outBitStream.Write<uint32_t>(ldfData.GetNumberOfBytesUsed());
outBitStream.Write(ldfData);
}
}
}
CppScripts::Script* const ScriptComponent::GetScript() {
return m_Script;
}
void ScriptComponent::SetScript(const std::string& scriptName) {
// Scripts are managed by the CppScripts class and are effecitvely singletons
// and they may also be used by other script components so DON'T delete them.
m_Script = CppScripts::GetScript(m_Parent, scriptName);
}
bool ScriptComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
auto& scriptInfo = reportInfo.info->PushDebug("Script");
scriptInfo.PushDebug<AMFStringValue>("Script Name") = m_ScriptName.empty() ? "None" : m_ScriptName;
auto& networkSettings = scriptInfo.PushDebug("Network Settings");
for (const auto& setting : m_Parent->GetNetworkSettings().values | std::views::values) {
networkSettings.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString();
}
return true;
}