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); } }
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)); }
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); } }
public void DisconnectFromServer(EDisconnectReason reason) { if (_serverConnection != null) { _serverConnection.connection.SendReliable(NetMsgs.Disconnect.New(reason, null)); _serverConnection.connection.driverConnection.Dispose(); _serverConnection = null; } }
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)); }
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)); } }
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); } }
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); }
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; } }
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); }
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; }
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)); } }
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; }
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; } }
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); }
void OnNetMsg(NetMsgs.Pong msg, ActorReplicationChannel channel) { channel.Pong(msg); }
void OnNetMsg(NetMsgs.Ping msg, ActorReplicationChannel channel) { channel.connection.SendReliable(NetMsgs.Pong.New(msg)); }
protected abstract void OnDisconnect(ActorReplicationChannel channel, EDisconnectReason reason, string msg);
void OnNetMsg(NetMsgs.Disconnect msg, ActorReplicationChannel channel) { OnDisconnect(channel, msg.reason, msg.message); }