ReplicaReturnResult ReplicaManager::ProcessReceivedCommand(ParticipantStruct *participantStruct, ReceivedCommand *receivedCommand) { Replica *replica = (Replica*) NetworkIDGenerator::GET_BASE_OBJECT_FROM_ID(receivedCommand->networkID); bool objectExists; unsigned index; ReplicaReturnResult b; if (replica) { index = replicatedObjects.GetIndexFromKey(replica, &objectExists); if (objectExists==false) { // Two ways to handle this. One is to autoregister the object - but this is dangerous in that if you have a network object that is not // using the replica system it would be of the wrong type, read read invalid memory, and crash. // Construct(replica, playerId, broadcast, true); // The other way is to assert and do nothing. The disadvantage is now the user has to register the object in order to receive calls on it. #ifdef _DEBUG // If this assert hits, call ReferencePointer on your replica pointer after it is created. assert(0); #endif return REPLICA_CANCEL_PROCESS; } } if (receivedCommand->command==ID_REPLICA_MANAGER_SERIALIZE) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SERIALIZE)) { b=replica->Deserialize(receivedCommand->userData, receivedCommand->u1, replicatedObjects[index].lastDeserializeTrue, receivedCommand->playerId); if (b==REPLICA_PROCESSING_DONE) replicatedObjects[index].lastDeserializeTrue=RakNet::GetTime(); return b; } } else if (receivedCommand->command==ID_REPLICA_MANAGER_CONSTRUCTION) { // If networkID already exists on this system, ignore the packet if (replica==0) { #ifdef _DEBUG assert(_constructionCB); #endif // Call the registered callback. If it crashes, you forgot to register the callback in SetReceiveConstructionCB return _constructionCB(receivedCommand->userData, receivedCommand->u1, receivedCommand->networkID, receivedCommand->playerId, this); } } else if (receivedCommand->command==ID_REPLICA_MANAGER_SCOPE_CHANGE) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SCOPE_CHANGE)) { return replica->ReceiveScopeChange(receivedCommand->userData, receivedCommand->playerId); } } else if (receivedCommand->command==ID_REPLICA_MANAGER_DESTRUCTION) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_DESTRUCTION)) { return replica->ReceiveDestruction(receivedCommand->userData, receivedCommand->playerId); } } else if (receivedCommand->command==ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE) { if (_receiveDownloadCompleteCB) { return _receiveDownloadCompleteCB(receivedCommand->userData, receivedCommand->playerId, this); } } return REPLICA_CANCEL_PROCESS; }
ReplicaReturnResult ReplicaManager::ProcessReceivedCommand(ParticipantStruct *participantStruct, ReceivedCommand *receivedCommand) { (void) participantStruct; // If this assert hits you didn't first call RakPeer::SetNetworkIDManager as required. RakAssert(rakPeerInterface->GetNetworkIDManager()); if (rakPeerInterface->GetNetworkIDManager()==0) return REPLICA_CANCEL_PROCESS; Replica *replica = (Replica*) rakPeerInterface->GetNetworkIDManager()->GET_BASE_OBJECT_FROM_ID(receivedCommand->networkID); bool objectExists; unsigned index=0; ReplicaReturnResult b; if (replica) { index = replicatedObjects.GetIndexFromKey(replica, &objectExists); if (objectExists==false) { if (receivedCommand->command==ID_REPLICA_MANAGER_CONSTRUCTION) { // Object already exists with this ID, but call construction anyway #ifdef _DEBUG RakAssert(_constructionCB); #endif // Call the registered callback. If it crashes, you forgot to register the callback in SetReceiveConstructionCB return _constructionCB->ReceiveConstruction(receivedCommand->userData, receivedCommand->u1, receivedCommand->networkID, replica, receivedCommand->systemAddress, this); } else { // This networkID is already in use but ReferencePointer was never called on it. // RakAssert(0); return REPLICA_CANCEL_PROCESS; } } } if (receivedCommand->command==ID_REPLICA_MANAGER_SERIALIZE) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SERIALIZE)) { b=replica->Deserialize(receivedCommand->userData, receivedCommand->u1, replicatedObjects[index].lastDeserializeTrue, receivedCommand->systemAddress); if (b==REPLICA_PROCESSING_DONE) replicatedObjects[index].lastDeserializeTrue=RakNet::GetTime(); return b; } } else if (receivedCommand->command==ID_REPLICA_MANAGER_CONSTRUCTION) { // If networkID already exists on this system, ignore the packet #ifdef _DEBUG RakAssert(_constructionCB); #endif // Call the registered callback. If it crashes, you forgot to register the callback in SetReceiveConstructionCB return _constructionCB->ReceiveConstruction(receivedCommand->userData, receivedCommand->u1, receivedCommand->networkID, replica, receivedCommand->systemAddress, this); } else if (receivedCommand->command==ID_REPLICA_MANAGER_SCOPE_CHANGE) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_SCOPE_CHANGE)) { return replica->ReceiveScopeChange(receivedCommand->userData, receivedCommand->systemAddress, receivedCommand->u1); } } else if (receivedCommand->command==ID_REPLICA_MANAGER_DESTRUCTION) { if (replica && (replicatedObjects[index].allowedInterfaces & REPLICA_RECEIVE_DESTRUCTION)) { return replica->ReceiveDestruction(receivedCommand->userData, receivedCommand->systemAddress, receivedCommand->u1); } } else if (receivedCommand->command==ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE) { if (_receiveDownloadCompleteCB) { return _receiveDownloadCompleteCB->ReceiveDownloadComplete(receivedCommand->userData, receivedCommand->systemAddress, this); } } return REPLICA_CANCEL_PROCESS; }