示例#1
0
	public void ReplicateRPC(SerializableObject context, int rpcID, ObjectRPCSerializer serializer, params object[] args) {
		if (!_connection.isValid) {
			return;
		}

		Perf.Begin("ActorReplicationChannel.ReplicateRPC");

		if (isServer) {
			if (!didHandshake) {
				// client hasn't finished connecting
				Perf.End();
				return;
			}

			if ((clientLevel == null) || (clientLevel != _connection.world.currentLevel)) {
				Perf.End();
				return;
			}
		} else if (_connection.world.isTraveling) {
			Perf.End();
			return;
		}

		if (context.internal_GetReplicator(connection) == null) {
			// has not been replicated.
			Perf.End();
			return;
		}

		var actor = context as Actor;
		if ((actor != null) && isServer && serializer.rpcInfo.CheckRelevancy && !actor.IsNetRelevantFor(this)) {
			// not relevant
			Perf.End();
			return;
		}

		Assert.IsFalse((actor != null) ? actor.netTornOff : false);

		objectRefs.Clear();

		var netMsg = NetMsgs.ReplicatedObjectRPC.New(context.netID, (ushort)rpcID);
		serializer.Write(netMsg.archive, this, args);
		
		if (_connection.world is Server.ServerWorld) {
			// send objects in the argument list first
			ReplicateDependencies();
		} else {
			objectRefs.Clear();
		}

		_connection.SendReliable(netMsg);

		Perf.End();
	}
示例#2
0
	void ReplicateObject(float dt, SerializableObject obj, Actor actor, ObjectReplicator replicator, bool isOwner, bool isRelevant, ref NetMsgs.ReplicatedObjectData msg) {
		Perf.Begin("ActorReplicationChannel.ReplicateObject");

		Assert.IsFalse((actor != null) ? actor.netTornOff : false);
		
		bool wroteAnything = false;

		// start on a byte boundary so we can restore the position to this point if we don't write any data.
		msg.archive.Flush();
		msg = msg.MaybeSend(connection);

		var position = msg.archive.Position;
		bool relevancyChanged = true;

		CHECK_FLD(msg.archive);

		if (replicator == null) {
			replicator = obj.internal_GetReplicator(connection);
		}

		if (replicator == null) {

			replicator = new ObjectReplicator(this, obj, connection.world.InternalGetReplicatedFields(obj), isOwner);
			obj.internal_SetReplicator(connection, replicator);
			
			msg.archive.Write((ushort)obj.netID);

			CHECK_FLD(msg.archive);

			// actor has not been replicated yet
			msg.archive.WriteUnsignedBits(1, 1);
			msg.archive.WriteUnsignedBits(isRelevant ? 1 : 0, 1);
			msg.archive.WriteUnsignedBits(((actor != null) && (actor.internal_NetTearOff)) ? 1 : 0, 1);

			CHECK_FLD(msg.archive);

			msg.archive.Write((ushort)((obj.outer is SerializableObject) ? (obj.outer as SerializableObject).netID : 0));
			msg.archive.Write(obj.classID);

			CHECK_FLD(msg.archive);

			replicator.FullSerialize(dt, msg.archive);
			SerializeCustomData(obj, msg.archive);
			wroteAnything = true;

		} else {

			relevancyChanged = replicator.wasRelevant != isRelevant;

			bool replicate = true;
			if ((dt >= 0f) && (actor != null) && !actor.internal_NetTearOff && !actor.internal_NetFlush && !relevancyChanged) {
				replicator.serializeDeltaTime += dt;
				if (replicator.serializeDeltaTime < actor.replicateRate) {
					replicate = false;
				}
            }

			if (replicate) {
				msg.archive.Write((ushort)obj.netID);
				CHECK_FLD(msg.archive);
				msg.archive.WriteUnsignedBits(0, 1);
				msg.archive.WriteUnsignedBits(isRelevant ? 1 : 0, 1);
				msg.archive.WriteUnsignedBits(((actor != null) && (actor.internal_NetTearOff)) ? 1 : 0, 1);
				CHECK_FLD(msg.archive);

				wroteAnything = replicator.DeltaSerialize(dt, msg.archive, (actor != null) && (actor.internal_NetFlush || relevancyChanged));
				wroteAnything = SerializeCustomData(obj, msg.archive) || wroteAnything;
			}
		}

		if (wroteAnything || ((actor != null) && (actor.internal_NetFlush || relevancyChanged))) {
			CHECK_FLD(msg.archive);
			obj.SerializeSubobjects(this);
		} else {
			msg.archive.Position = position;
			msg.archive.Discard();
		}

		replicator.wasRelevant = isRelevant;

		if ((actor != null) && actor.internal_NetTearOff) {
			obj.internal_SetReplicator(connection, null);
        }

		Perf.End();
	}
示例#3
0
	public bool HasReplicated(SerializableObject obj) {
		return obj.internal_GetReplicator(connection) != null;
	}