void ReplicateDependencies(ref NetMsgs.ReplicatedObjectData packet) { Perf.Begin("ActorReplicationChannel.ReplicateDependencies"); // Serialize referenced actors. objectRefs2.Clear(); while (objectRefs.Values.Count > 0) { Utils.Swap(ref objectRefs, ref objectRefs2); for (int i = 0; i < objectRefs2.Values.Count; ++i) { int netIDHashCode = objectRefs2.Values[i]; var obj = connection.world.GetObjectByNetIDHashCode(netIDHashCode); bool isOwner = true; bool isRelevant = true; var actor = obj as Actor; ObjectReplicator replicator = null; if (actor != null) { Assert.IsFalse(actor.disposed); if (actor.internal_NetTearOff) { continue; } isOwner = actor.ownerConnectionID == _connection.id; if (!isOwner && actor.ownerOnly) { // actor is not replicated on this channel. continue; } if (!CheckRelevancy(actor, out replicator, out isRelevant)) { // actor is not replicated on this channel. continue; } } else { var component = obj as ActorComponent; if (component != null) { isOwner = component.owner.ownerConnectionID == _connection.id; if (!isOwner && component.owner.ownerOnly) { // only replicate to owner. continue; } } } ReplicateObject(0f, obj, actor, replicator, isOwner, isRelevant, ref packet); #if !PACKET_COMBINE packet = packet.Flush(connection); #endif } objectRefs2.Clear(); } Perf.End(); }
public override void Serialize(Archive archive) { archive.Serialize(ref _levelName); int numIds = (_travelActorNetIDs != null) ? _travelActorNetIDs.Values.Count : 0; archive.Serialize(ref numIds); if (archive.isLoading) { if (_travelActorNetIDs != null) { _travelActorNetIDs.Clear(); } else { _travelActorNetIDs = new HashSetList <int>(); } for (int i = 0; i < numIds; ++i) { _travelActorNetIDs.Add(archive.ReadInt()); } } else if (numIds > 0) { for (int i = 0; i < numIds; ++i) { archive.Write(_travelActorNetIDs.Values[i]); } } }
void GarbageCollect() { for (int i = 0; i < garbage.Values.Count; ++i) { connection.SendReliable(NetMsgs.DestroyActor.New(garbage.Values[i])); } garbage.Clear(); }
public void ReplicateActors(float dt) { if (!didHandshake) { handshakeTime += Mathf.Min(dt, 1/3f); // client hasn't finished connecting return; } Ping(dt); if (!clientLevelLoaded) { ResetTimeoutForTravel(); return; } Perf.Begin("ActorReplicationChannel.ReplicateActors"); isSending = true; objectRefs.Clear(); var packet = NetMsgs.ReplicatedObjectData.New(); for (int i = 0; i < connection.world.numReplicatedActors; ++i) { var actor = connection.world.GetReplicatedActor(i); Assert.IsFalse(actor.disposed); var isOwner = actor.ownerConnectionID == _connection.id; if (!isOwner && actor.ownerOnly) { // actor is not replicated on this channel. continue; } Assert.IsFalse(actor.netTornOff); bool isRelevant; ObjectReplicator replicator; if (!CheckRelevancy(actor, out replicator, out isRelevant)) { Assert.IsFalse(actor.internal_NetTearOff); continue; } ReplicateObject(dt, actor, actor, replicator, actor.ownerConnectionID == _connection.id, isRelevant, ref packet); #if !PACKET_COMBINE packet = packet.Flush(connection); #endif objectRefs.Remove(actor.netIDHashCode); } ReplicateDependencies(ref packet); packet.Flush(connection); if (isTraveling) { ResetTimeoutForTravel(); isTraveling = false; GarbageCollect(); connection.SendReliable(NetMsgs.ServerFinishedTravel.New()); connection.driverConnection.blocking = false; } Perf.End(); }