Example #1
0
    void OnNetMsg(NetMsgs.ReplicatedObjectRPC msg, ActorReplicationChannel channel)
    {
        bool isServer = this is Server.ServerWorld;

        if (isServer)
        {
            if (isTraveling || (channel.clientLevel == null) || (channel.clientLevel != currentLevel))
            {
                // discard RPC's from clients if we are traveling.
                return;
            }
        }

        var obj = GetObjectByNetID(msg.netID);

        if (obj != null)
        {
            var rpcTarget = (ActorRPCObject)obj;
            var rpc       = rpcTarget.rpcTable.GetObjectRPCByID(msg.rpcID);
            if (rpc != null)
            {
                if (isServer)
                {
                    if (rpc.rpcInfo.Domain != ERPCDomain.Server)
                    {
                        throw new ActorReplicationException("Non server RPC invoked by client!");
                    }
                }
                var args = rpc.Read(msg.archive, _rpcReferenceCollector);
                rpc.method.Invoke(obj, args);
                rpc.Flush();
            }
        }
    }
 void OnNetMsg(NetMsgs.ReplicatedObjectData msg, ActorReplicationChannel channel)
 {
     if (channel == _serverConnection)
     {
         _serverConnection.HandleReplicatedObjectData(msg);
     }
 }
Example #3
0
    void RawNetRecv(ActorReplicationChannel channel, int size)
    {
#if PROFILING
        try {
            Perf.Begin("World.RawNetRecv");
#endif
        _netArchive.BeginRead(size);
        int typeID = _netArchive.ReadInt();
        NetMsg msg = _netMsgFactory.GetNetMsg(typeID);
        if (msg != null)
        {
            msg.Serialize(channel.connection, _netArchive);
            if (_netArchive.hasUnreadBytes)
            {
                throw new System.IO.IOException(msg.GetType().FullName + " did not consume its entire payload.");
            }
            DynamicDispatchNetMsg(msg, channel);
        }
        else
        {
            throw new System.IO.IOException("Unrecognized net message type " + typeID);
        }
#if PROFILING
    }

    finally {
        Perf.End();
    }
#endif
    }
 protected override EClientConnectResult TickPendingConnection(ActorReplicationChannel channel)
 {
     if (_gameMode == null)
     {
         return(EClientConnectResult.Pending);
     }
     return(_gameMode.TickPendingConnection(channel));
 }
Example #5
0
 public override void OnConnect(NetDriverConnection connection)
 {
     Assert.IsNull(_serverConnection);
     _serverConnection = new ActorReplicationChannel(new NetConnection(this, connection));
     _serverConnection.ResetTimeoutForTravel();
     connection.outer = _serverConnection;
     Debug.Log("Connected to server (" + connection.address + ")");
 }
        void OnNetMsg(NetMsgs.DestroyActor msg, ActorReplicationChannel channel)
        {
            var actor = (Actor)GetObjectByNetID(msg.netID);

            if (actor != null)
            {
                DestroyAndRemoveActor(actor);
            }
        }
Example #7
0
 public void DisconnectFromServer(EDisconnectReason reason)
 {
     if (_serverConnection != null)
     {
         _serverConnection.connection.SendReliable(NetMsgs.Disconnect.New(reason, null));
         _serverConnection.connection.driverConnection.Dispose();
         _serverConnection = null;
     }
 }
Example #8
0
        public void Tick(float dt, MonoBehaviour loadingContext, ref NetIOMetrics reliableMetrics, ref NetIOMetrics unreliableMetrics)
        {
            if (!isTraveling)
            {
                UpdateTime(Mathf.Min(dt * Time.timeScale, 1 / 3f), dt);
            }

            TickWorldStreaming();

            netDriver.TickClient(Mathf.Min(dt, 1 / 3f), netMessageBytes, ref reliableMetrics, ref unreliableMetrics);

            if (_serverConnection != null)
            {
                if (isTraveling || _wasTraveling)
                {
                    TickTravel(loadingContext);
                    if (!isTraveling)
                    {
                        if (_serverConnection != null)
                        {
                            _serverConnection.ResetTimeout();
                        }
                        FinishTravel();
                        OnLevelStart();
                        GC.Collect();
                    }

                    if (_serverConnection != null)
                    {
                        _serverConnection.ResetTimeoutForTravel();
                    }
                }
                else
                {
                    TickActors(loadingContext);

#if !UNITY_EDITOR
                    if ((_serverConnection != null) && _serverConnection.timedOut)
                    {
                        Debug.LogError("Server connection timed out");
                        _serverConnection.connection.driverConnection.Dispose();
                        _serverConnection = null;
                    }
#endif
                }

                if (_serverConnection != null)
                {
                    _serverConnection.Ping(dt);
                    _serverConnection.connection.driverConnection.GetIOMetrics(ref reliableMetrics, ref unreliableMetrics, true);
                }

                _wasTraveling = isTraveling;
            }
        }
 void OnNetMsg(NetMsgs.Welcome msg, ActorReplicationChannel channel)
 {
     if (channel == _serverConnection)
     {
         Debug.Log("Welcomed by server: " + msg.serverName);
         Debug.Log(msg.message);
         Debug.Log("ConnectionID = " + msg.connectionID);
         _serverConnection.connection.SetID(msg.connectionID);
         _connectionState = EConnectionState.Joining;
         SendClientConnect();
     }
 }
        public override void OnConnect(NetDriverConnection connection)
        {
            var channel = new ActorReplicationChannel(new NetConnection(this, connection));

            channel.connection.SetID(++nextConnectionID);
            channel.connection.driverConnection.blocking = true;
            connection.outer = channel;
            connectionList.Add(channel);

            Debug.Log("Client connected (" + connection.address + ").");

            channel.connection.SendReliable(NetMsgs.Welcome.New(serverName, serverMessage, channel.connection.id));
        }
Example #11
0
	public ObjectReplicator(ActorReplicationChannel channel, SerializableObject obj, SerializedObjectFields fields, bool isOwner) {
		this.channel = channel;
		_object = obj;

		wasRelevant = true;
		this.isOwner = isOwner;

        fieldStates = new IntHashtableList<ReplicatedObjectFieldState>();
		for (int i = 0; i < fields.serializedFields.Values.Count; ++i) {
			SerializedObjectFields.FieldSpec fieldSpec = fields.serializedFields.Values[i];
			fieldStates.Add(fieldSpec.fieldID, new ReplicatedObjectFieldState(fieldSpec));
		}
	}
Example #12
0
 public override void OnDisconnect(NetDriverConnection connection)
 {
     if (_connectionState == EConnectionState.Connecting)
     {
         Debug.Log("Cannot connect to server!");
     }
     else
     {
         Debug.Log("Disconnected from server (" + connection.address + ")");
         _connectionState  = EConnectionState.Disconnected;
         _serverConnection = null;
         OnDisconnectedFromServer(EDisconnectReason.Error);
     }
 }
Example #13
0
 protected override void OnDisconnect(ActorReplicationChannel channel, EDisconnectReason reason, string msg)
 {
     if (string.IsNullOrEmpty(msg))
     {
         Debug.LogError("Disconnected by server " + reason);
     }
     else
     {
         Debug.LogError("Disconnected by server " + reason + " - " + msg);
     }
     _serverConnection.connection.driverConnection.Dispose();
     _serverConnection = null;
     OnDisconnectedFromServer(reason);
 }
Example #14
0
        void OnNetMsg(NetMsgs.ClientLevelStarted msg, ActorReplicationChannel channel)
        {
            channel.ResetTimeoutForTravel();

            if (isTraveling)
            {
                if (channel.clientLevel == travelLevel)
                {
                    channel.levelStarted = true;
                }
            }
            else if (channel.clientLevel == currentLevel)
            {
                channel.levelStarted = true;
            }
        }
Example #15
0
        protected override void OnNetMsg(NetMsgs.ClientTravel msg, ActorReplicationChannel channel)
        {
            base.OnNetMsg(msg, channel);

            if (GameManager.instance.serverWorld != null)
            {
                if (!GameManager.instance.serverWorld.isTraveling)
                {
                    // server does the traveling.
                    serverConnection.SendReliable(NetMsgs.ClientFinishedTravel.New(msg.levelName));
                }
                return;
            }

            BeginTravel(msg.levelName, msg.travelActorNetIDs);
            GameManager.instance.SetPendingLevel(msg.levelName, null);
        }
Example #16
0
    void DynamicDispatchNetMsg(NetMsg msg, ActorReplicationChannel channel)
    {
        MethodInfo m;

        if (!_netMsgDispatchHash.TryGetValue(msg.msgTypeID, out m))
        {
            throw new TargetInvocationException(GetType().FullName + " is not supposed to be received!", null);
        }

        _dispatchArgs[0] = msg;
        _dispatchArgs[1] = channel;

        m.Invoke(this, _dispatchArgs);

        _dispatchArgs[0] = null;
        _dispatchArgs[1] = null;
    }
Example #17
0
        void OnNetMsg(NetMsgs.ClientFinishedTravel msg, ActorReplicationChannel channel)
        {
            channel.clientLevel = msg.levelName;
            channel.ResetTimeoutForTravel();

            if (isTraveling)
            {
                if (channel.clientLevel != travelLevel)
                {
                    // travel
                    channel.connection.SendReliable(NetMsgs.ClientTravel.New(travelLevel, null));
                }
            }
            else if (channel.clientLevel != currentLevel)
            {
                channel.connection.SendReliable(NetMsgs.ClientTravel.New(currentLevel, null));
            }
        }
Example #18
0
        void OnNetMsg(NetMsgs.ClientConnect msg, ActorReplicationChannel channel)
        {
            if (msg.gameVersion != BuildInfo.ID)
            {
                DisconnectClient(channel.connection, null, EDisconnectReason.WrongVersion, BuildInfo.ID);
                return;
            }
            if (channel.didHandshake)
            {
                DisconnectClient(channel.connection, null, EDisconnectReason.Error, null);
                return;
            }

            channel.uuid = msg.uuid;
#if BACKEND_SERVER
            channel.challenge = msg.challenge;
#endif
            channel.didHandshake   = true;
            channel.isTraveling    = true;
            channel.pendingConnect = true;
            channel.levelStarted   = false;
            channel.clientLevel    = null;
        }
 protected virtual void OnNetMsg(NetMsgs.ServerFinishedTravel msg, ActorReplicationChannel channel)
 {
     _serverTravel = false;
 }
Example #20
0
	bool SerializeFields(float dt, NetArchive archive, bool deltasOnly, bool netFlush) {
		Perf.Begin("SerializeFields");

		ActorReplicationChannel.CHECK_FLD(archive);

		isLoading = archive.isLoading;
		if (isLoading) {
			byte numBits = archive.ReadByte();
			Assert.IsTrue(numBits <= SerializedObjectFields.MAX_REPLICATED_FIELDS);
			uint fieldBits = archive.ReadUnsignedBits(numBits);

			ActorReplicationChannel.CHECK_FLD(archive);

			for (int i = 0; i < numBits; ++i) {
				if (((1U << i) & fieldBits) != 0) {
					var fieldState = fieldStates.Values[i];
					
					curFieldState = fieldState;
					object obj = fieldState.fieldSpec.field.GetValue(_object);
					object orig = obj;

					ActorReplicationChannel.CHECK_FLD(archive);

					if (fieldState.fieldSpec.serializer.Serialize(archive, this, ref obj, null)) {
						fieldState.needsRep = fieldState.fieldSpec.onRep != null;

						if (fieldState.needsRep) {
							++numOnReps;
						}
					}

					ActorReplicationChannel.CHECK_FLD(archive);

					if (obj != orig) {
						fieldState.fieldSpec.field.SetValue(_object, obj);
					}
				}
			}

			curFieldState = null;
			Perf.End();
			return numBits > 0;
		} else {

			fieldsToReplicate.Clear();

			byte numBitsWritten = 0;
			uint fieldBits = 0;

			for (int i = 0; i < fieldStates.Values.Count; ++i) {
				var field = fieldStates.Values[i];

				object fieldVal;
				bool deltaField;

				if (field.IsDirty(channel, _object, dt, deltasOnly, hasReplicated, isOwner, netFlush, out fieldVal, out deltaField)) {
					numBitsWritten = (byte)(i + 1);
					fieldBits |= 1U << i;
					fieldsToReplicate.Add(new FieldReplicateInfo(i, fieldVal, deltaField));
				}
			}

			Assert.IsTrue(numBitsWritten <= SerializedObjectFields.MAX_REPLICATED_FIELDS);
			archive.Write(numBitsWritten);
			archive.WriteUnsignedBits(fieldBits, numBitsWritten);

			ActorReplicationChannel.CHECK_FLD(archive);

			for (int i = 0; i < fieldsToReplicate.Count; ++i) {
				var info = fieldsToReplicate[i];
				var field = fieldStates.Values[info.index];
				ActorReplicationChannel.CHECK_FLD(archive);
				field.Write(archive, this, info.fieldVal, info.deltaField);
				ActorReplicationChannel.CHECK_FLD(archive);
			}

			fieldsToReplicate.Clear();

			hasReplicated = true;

			Perf.End();
			return numBitsWritten > 0;
		}
	}
Example #21
0
	public bool IsDirty(ActorReplicationChannel channel, SerializableObject container, float dt, bool deltasOnly, bool hasReplicated, bool isOwner, bool netFlush, out object fieldValue, out bool deltaField) {
		Perf.Begin("FieldState.IsDirty");

		bool shouldReplicate = true;

		if (fieldSpec.replication.Condition != EReplicateCondition.Always) {
			switch (fieldSpec.replication.Condition) {
				case EReplicateCondition.InitialOnly:
					shouldReplicate = !hasReplicated;
				break;
				case EReplicateCondition.OwnerOnly:
					shouldReplicate = isOwner;
				break;
				case EReplicateCondition.SkipOwner:
					shouldReplicate = !isOwner;
				break;
				case EReplicateCondition.InitialOrOwner:
					shouldReplicate = !hasReplicated || isOwner;
				break;
				case EReplicateCondition.InitialOwnerOnly:
					shouldReplicate = !hasReplicated && isOwner;
				break;
			}
		}

		if (!shouldReplicate) {
			deltaField = false;
			fieldValue = null;
			Perf.End();
			return false;
		}

		if (!netFlush) {
			nextSendTime -= dt;
			if (nextSendTime > 0f) {
				deltaField = false;
				fieldValue = null;
				Perf.End();
				return false;
			}
		}

		// Update send time here: if we don't send because the value hasn't changed
		// we don't want to check again until after the UpdateRate has passed.
		nextSendTime = fieldSpec.replication.UpdateRate;
		
		fieldValue = fieldSpec.field.GetValue(container);

		// check ownerOnly object replication.
		if (fieldSpec.isObjectReference) {
			var actor = fieldValue as Actor;
			if ((actor != null) && actor.ownerOnly) {
				if (actor.ownerConnection != channel) {
					deltaField = false;
					Perf.End();
					return false;
				}
			}
		}

		deltaField = !fieldSpec.serializer.FieldsAreEqual(lastState, fieldValue);

		if (deltasOnly && !deltaField) {
			Perf.End();
			return false;
		}

		Perf.End();
		return true;
	}
 protected abstract EClientConnectResult TickPendingConnection(ActorReplicationChannel channel);
 protected virtual void OnNetMsg(NetMsgs.ClientTravel msg, ActorReplicationChannel channel)
 {
     _serverTravel = true;
 }
 protected override void OnDisconnect(ActorReplicationChannel channel, EDisconnectReason reason, string msg)
 {
     OnDisconnect(channel.connection.driverConnection);
 }
Example #25
0
 void OnNetMsg(NetMsgs.Pong msg, ActorReplicationChannel channel)
 {
     channel.Pong(msg);
 }
Example #26
0
 void OnNetMsg(NetMsgs.Ping msg, ActorReplicationChannel channel)
 {
     channel.connection.SendReliable(NetMsgs.Pong.New(msg));
 }
Example #27
0
 protected abstract void OnDisconnect(ActorReplicationChannel channel, EDisconnectReason reason, string msg);
Example #28
0
 void OnNetMsg(NetMsgs.Disconnect msg, ActorReplicationChannel channel)
 {
     OnDisconnect(channel, msg.reason, msg.message);
 }