/// <summary> Invokes RPC with parameters from the NetMessage. </summary> internal void Invoke(object instance, string methodName, NetMessage message, NetConnection sender) { RpcMethodInfo rpcInfo = RpcInfoCache.Get(methodName); MethodInfo method = rpcInfo.MethodInfoLookup[instance.GetType()]; if (rpcInfo.TakesRequests && Socket.Request.Dispatch(message, sender, method, instance)) return; if (method.ReturnType == typeof (IEnumerator)) { var coroutine = (IEnumerator) method.Invoke(instance, message.Parameters); var behaviour = (MonoBehaviour) instance; if (coroutine != null) behaviour.StartCoroutine(coroutine); } else method.Invoke(instance, message.Parameters); }
/// <summary> Processes a request to assign an RPC method name to a numeric ID. </summary> internal void ReceiveAssignmentRequest(NetMessage netMessage, NetConnection connection) { // If we aren't responsible for RPC ID assignment, ignore request. if (!Socket.ProtocolAuthority) return; var rpcName = (string) netMessage.Parameters[0]; if (!HasId(rpcName)) { if (NameCount > 1800) return; AssignRemoteRpc(rpcName); // Send new assignment to all connections. foreach (NetConnection conn in Socket.Connections) { if (conn == connection || conn.IsServer) continue; Socket.Command.Send((int) Cmd.RemoteAssignment, conn, nameToId[rpcName], rpcName); } } Socket.Command.Send((int) Cmd.AssignmentResponse, connection, nameToId[rpcName], rpcName); }
/// <summary> Adds the assigned id and remote method name to the RemoteRpcIds dictionary. </summary> internal void ReceiveRemoteAssignment(NetMessage netMessage, NetConnection connection) { if (!connection.IsServer && !connection.IsPeer) return; var rpcId = (ushort)netMessage.Parameters[0]; var rpcName = (string) netMessage.Parameters[1]; if (!HasId(rpcName) && !HasName(rpcId)) { nameToId.Add(rpcName, rpcId); idToName.Add(rpcId, rpcName); foreach (NetConnection conn in Socket.Connections) { if (conn == connection || conn.IsServer) continue; Socket.Command.Send((int)Cmd.RemoteAssignment, conn, nameToId[rpcName], rpcName); } } WaitingForRpcs--; //NetLog.Trace("Waiting for RPCs: " + WaitingForRpcs); if (WaitingForRpcs != 0) return; if (IdCount >= RpcInfoCache.Count) Socket.SendRequirementsMet(connection); else RequestAssignments(connection); }
/// <summary> Sends a message to this connection. </summary> internal void Send(NetMessage message) { if (this == Socket.Self) NetLog.Warning("Trying to send message to self."); if (!message.Reliable) Unreliable.SerializeMessage(message); else Reliable.SerializeReliableMessage(message); }
/// <summary> Processes a response to an RPC assignment request. The assigned id and method name are added to the LocalRpcs dictionary. </summary> internal void ReceiveAssignmentResponse(NetMessage netMessage, NetConnection connection) { if (!connection.IsServer && !connection.IsPeer) return; var id = (ushort) netMessage.Parameters[0]; var methodName = (string) netMessage.Parameters[1]; if (RpcInfoCache.Exists(methodName) && !idToName.ContainsKey(id)) { idToName.Add(id, methodName); if (!nameToId.ContainsKey(methodName)) nameToId.Add(methodName, id); } else NetLog.Error("Cannot assign local RPC. ID: " + id + " MethodName: " + methodName); if (idToName.Count == RpcInfoCache.Count) Socket.SendRequirementsMet(connection); }
/// <summary> Processes a DestroyView command, this destroys the GameObject associated with the provided viewId. </summary> private void ReceiveDestroyView(NetMessage message, NetConnection connection) { int viewId = (int)message.Parameters[0]; if (!ViewLookup.ContainsKey(viewId)) return; var view = ViewLookup[viewId]; if (view.Server != connection) return; DestroyView(view); }
internal void Dispatch(NetMessage message, NetConnection connection) { if (targets.ContainsKey(message.MessageId)) targets[message.MessageId](message, connection); else if (streamTargets.ContainsKey(message.MessageId)) streamTargets[message.MessageId]((NetStream) message.Parameters[0], connection); }
/// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary> internal void Send(NetView view, NetMessage netMessage, RpcTarget target) { switch (target) { case (RpcTarget.All): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (!connection.HasScope) continue; if (view.Group != 0 && !connection.InGroup(view.Group)) continue; if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection)) connection.Send(netMessage); } break; case (RpcTarget.Controllers): foreach (NetConnection controller in view.Controllers) { if (controller == Socket.Self) continue; controller.Send(netMessage); } break; case (RpcTarget.NonControllers): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (connection.IsServer || !connection.HasScope) continue; if (view.IsController(connection)) continue; if (view.Group != 0 && !connection.InGroup(view.Group)) continue; if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame)) connection.Send(netMessage); } break; case (RpcTarget.Server): if (view.Server != Socket.Self) view.Server.Send(netMessage); else NetLog.Warning("Trying to send message to self."); break; case (RpcTarget.AllInclOutOfScope): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (view.Group != 0 && !connection.InGroup(view.Group)) continue; connection.Send(netMessage); } break; } }
private void ReceiveCreateView(NetMessage message, NetConnection server) { if (!server.IsServer && !server.IsPeer) return; int viewId = (int)message.Parameters[0]; int group = (int)message.Parameters[1]; string prefabRoot = (string)message.Parameters[2]; var stream = (NetStream)message.Parameters[3]; NetView.Relation relation = default(NetView.Relation); NetConnection controller = null; switch (message.MessageId) { case (int)ViewCmd.CreateOwnerView: controller = Socket.Self; relation = NetView.Relation.Owner; break; case (int)ViewCmd.CreatePeerView: relation = NetView.Relation.Peer; break; case (int)ViewCmd.CreateCreatorView: server = Socket.Self; relation = NetView.Relation.Creator; break; case (int)ViewCmd.CreateProxyView: relation = NetView.Relation.Proxy; break; } if (relation == NetView.Relation.Creator || relation == NetView.Relation.Peer) { var ipendpoint = (IPEndPoint)message.Parameters[4]; if (ipendpoint != null) { if (Socket.EndpointConnected(ipendpoint)) controller = Socket.EndpointToConnection(ipendpoint); else NetLog.Error("Failed to create view, controller endpoint not connected: " + ipendpoint); } } var view = CreateView(controller, server, viewId, group, prefabRoot, relation); view.TriggerReadInstantiateData(stream); if (OnNetViewCreated != null) OnNetViewCreated(view); }
/// <summary> Handles the OutOfScope command by triggering the OnOutOfScope delegate for the view. </summary> private void ReceiveOutOfScope(NetMessage message, NetConnection connection) { if (!connection.IsServer && !connection.IsPeer) return; int viewId = (int)message.Parameters[0]; if (!ViewLookup.ContainsKey(viewId)) return; ViewLookup[viewId].Scope.FireOutEvent(); }
/// <summary> Handles the ChangeServer command by changing the View's Server to that of the sender. </summary> internal void ReceiveChangeServer(NetMessage message, NetConnection connection) { if (!connection.IsServer && !connection.IsPeer) return; int viewId = (int)message.Parameters[0]; if (!ViewLookup.ContainsKey(viewId)) return; ViewLookup[viewId].Server = connection; }
private void ReceiveMessage(NetMessage message, NetConnection connection) { if (!ViewLookup.ContainsKey((int)message.ViewId)) return; string methodName = Socket.Rpc.IdToName(message.MessageId); var view = ViewLookup[(int)message.ViewId]; if (!view.IsController(connection) && connection != view.Server) { if (!connection.IsServer) { NetLog.Warning("Connection attempting to send to unauthorized View: " + connection.Endpoint); return; } view.Server = connection; } view.DispatchRpc(methodName, message, connection); }
private void DeliverSyncStream(NetMessage message, NetConnection connection) { if (!ViewLookup.ContainsKey((int)message.ViewId)) return; var view = ViewLookup[(int)message.ViewId]; if (!view.IsController(connection) && connection != view.Server) { if (!connection.IsServer) { NetLog.Warning("Connection attempting to send to unauthorized View: " + connection.Endpoint); return; } view.Server = connection; } view.TriggerReadSync((NetStream)message.Parameters[0]); }
/// <summary> /// Serializes a NetMessage to the reliable stream. /// If there is no current stream, one is prepared. /// If the current stream cannot fit the message, it is sent and a new stream is prepared. /// </summary> internal void SerializeReliableMessage(NetMessage message) { if (sendWindow.Count >= 512) return; if (sendStream == null) InitializeStream(); if (!NetSerializer.TryWriteMessage(sendStream, message)) { if (retryingSerialization) { NetLog.Warning("SerializeReliableMessage failed."); retryingSerialization = false; return; } retryingSerialization = true; FlushStream(); SerializeReliableMessage(message); } if (retryingSerialization) retryingSerialization = false; }
internal void MessageReceived(NetMessage message, NetConnection connection) { if (OnMessageReceived != null) OnMessageReceived(message, connection); }
/// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary> internal void Send(NetView view, NetMessage netMessage, RpcTarget target) { switch (target) { case (RpcTarget.All): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (!connection.HasScope) { continue; } if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection)) { connection.Send(netMessage); } } break; case (RpcTarget.Controllers): foreach (NetConnection controller in view.Controllers) { if (controller == Socket.Self) { continue; } controller.Send(netMessage); } break; case (RpcTarget.NonControllers): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (connection.IsServer || !connection.HasScope) { continue; } if (view.IsController(connection)) { continue; } if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame)) { connection.Send(netMessage); } } break; case (RpcTarget.Server): if (view.Server != Socket.Self) { view.Server.Send(netMessage); } else { NetLog.Warning("Trying to send message to self."); } break; case (RpcTarget.AllInclOutOfScope): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } connection.Send(netMessage); } break; } }