Files
firestorm/Gameleap/code/mw4/Libraries/Adept/Replicator.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

383 lines
10 KiB
C++

//===========================================================================//
// File: Replicator.cpp //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/29/94 JMA Initial coding. //
// 08/25/97 JMA Infrastructure changes //
// 08/25/97 ECH Infrastructure changes //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-97, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "AdeptHeaders.hpp"
#include "Replicator.hpp"
#include "Connection.hpp"
//#############################################################################
//########################## Replicator #################################
//#############################################################################
ReplicatorID
ReplicatorID::Null;
Replicator::ClassData
*Replicator::DefaultData = NULL;
const Receiver::MessageEntry
Replicator::MessageEntries[]=
{
MESSAGE_ENTRY(Replicator, Destroy)
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
ReplicatorClassID,
"Adept::Replicator",
Receiver::DefaultData,
ELEMENTS(MessageEntries), MessageEntries,
NULL,
NULL
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::CreateMessage*
Replicator::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
{
Check_Object(this);
Check_Object(stream);
//
//---------------------------------------------------------------------
// Make sure there is enough room for the factory request on the stream
//---------------------------------------------------------------------
//
stream->AllocateBytes(sizeof(CreateMessage));
CreateMessage *message =
Cast_Pointer(CreateMessage*, stream->GetPointer());
message->messageLength = sizeof(*message);
//
//---------------------------
// Create the factory request
//---------------------------
//
message->messageID = Connection::ReplicateMessageID;
message->messagePriority = DefaultEventPriority;
message->messageFlags = CreateMessage::DefaultFlags;
message->replicatorFlags = replicatorFlags;
message->replicatorID.connectionID = 0;
message->replicatorID.localID = 1;
message->classID = GetClassID();
return message;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::Replicator(
ClassData *class_data,
const CreateMessage *message,
ReplicatorID *base_id
):
Receiver(class_data)
{
Check_Pointer(this);
Check_Object(message);
//
//---------------------------------
// Extract our data from the stream
//---------------------------------
//
Verify(message->classID == GetClassID());
replicatorFlags = message->replicatorFlags;
//
//---------------------
// Get the replicant ID
//---------------------
//
replicatorID = *base_id;
++*base_id;
owningConnection =
Network::GetInstance()->GetConnection(replicatorID.connectionID);
Check_Object(owningConnection);
if(owningConnection == Connection::Hermit)
{
Verify(GetReplicatorMode() == HermitMode);
}
// here we go...
// if we are the server than we own everything..
if (owningConnection != Connection::Hermit)
{
SetReplicatorMode(MasterMode);
Verify(GetReplicatorMode() != HermitMode);
if (Network::GetInstance()->AmIServer())
{
// if we don't own it and it is a master it will be the ServerMasterMode ( the receiver of a ClientMaster )
if ((owningConnection != Connection::Local) && (owningConnection != Connection::Hermit))
{
if (GetReplicatorMode() == MasterMode)
SetReplicatorMode(ServerMasterMode);
}
}
else
{
// we are a client so we don't own anything.
if ((owningConnection == Connection::Local) && (GetReplicatorMode() == MasterMode))
{
SetReplicatorMode(ClientMasterMode);
}
else if ((owningConnection != Connection::Local) && GetReplicatorMode() == MasterMode)
{
SetReplicatorMode(ReplicantMode);
}
}
}
//
//----------------------------
// Hook up to the host manager
//----------------------------
//
owningConnection->AddReplicator(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::~Replicator()
{
DESTRUCTOR("Replicator");
//
//--------------------------------------------------------------
// Notify replicator manager, the connection to the host manager
// is removed automatically
//--------------------------------------------------------------
//
if (owningConnection)
{
Check_Object(owningConnection);
owningConnection->ReplicatorDestroyed(this);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::Reuse(
const Replicator::CreateMessage *message,
ReplicatorID *base_id
)
{
Check_Pointer(this);
Check_Object(message);
//
//---------------------------------
// Extract our data from the stream
//---------------------------------
//
Verify(message->classID == GetClassID());
replicatorFlags = message->replicatorFlags;
//
//---------------------
// Get the replicant ID
//---------------------
//
replicatorID = *base_id;
++*base_id;
Verify(!owningConnection);
owningConnection =
Network::GetInstance()->GetConnection(replicatorID.connectionID);
Check_Object(owningConnection);
if(owningConnection == Connection::Hermit)
{
Verify(GetReplicatorMode() == HermitMode);
}
// here we go...
// if we are the server than we own everything..
if (owningConnection != Connection::Hermit)
{
Verify(GetReplicatorMode() != HermitMode);
SetReplicatorMode(MasterMode);
if (Network::GetInstance()->AmIServer())
{
// if we don't own it and it is a master it will be the ServerMasterMode ( the receiver of a ClientMaster )
if ((owningConnection != Connection::Local) && (owningConnection != Connection::Hermit))
{
if (GetReplicatorMode() == MasterMode)
SetReplicatorMode(ServerMasterMode);
}
}
else
{
// we are a client so we don't own anything.
if ((owningConnection == Connection::Local) && (GetReplicatorMode() == MasterMode))
{
SetReplicatorMode(ClientMasterMode);
}
else if ((owningConnection != Connection::Local) && GetReplicatorMode() == MasterMode)
{
SetReplicatorMode(ReplicantMode);
}
}
}
//
//----------------------------
// Hook up to the host manager
//----------------------------
//
owningConnection->AddReplicator(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::Respawn(
const Replicator::CreateMessage *message
)
{
Check_Pointer(this);
Check_Object(message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::Dispatch(const Receiver::Message *incoming)
{
Check_Object(this);
Check_Object(incoming);
STOP(("Replicator::Distpatch has been disabled for networking. Please use Receiver::Receive instead!"));
#if 0
//
//------------------------------------------------------
// Call Receiver if it is not a replicator aware message
//------------------------------------------------------
//
if (incoming->messageID < Receiver::NextMessageID)
Receiver::Dispatch(incoming);
//
//---------------------------------------------
// Initialize the replicator information fields
//---------------------------------------------
//
const Message *message = Cast_Pointer(const Message*, incoming);
Check_Object(message);
//
//-------------------------------------------------------------------
// If this is a replicant instance, reroute the message to the master
//-------------------------------------------------------------------
//
if (GetReplicatorMode() == ReplicantMode)
{
Check_Object(owningConnection);
owningConnection->SendToMaster(this, message);
return;
}
//
//--------------------------------------------
// Otherwise, go ahead and receive the message
//--------------------------------------------
//
Receiver::Receive(message);
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::DispatchToReplicants(const Message *message)
{
Check_Object(this);
Check_Object(message);
Check_Object(owningConnection);
owningConnection->BroadcastToReplicants(this, message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::DestroyMessageHandler(const DestroyMessage *message)
{
Check_Object(this);
Check_Object(message);
Verify(message->messageID == DestroyMessageID);
delete this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Replicator__ClassData::TestInstance()
{
Verify(IsDerivedFrom(Replicator::DefaultData));
}