/// <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; } }
/// <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> /// Starts the socket using the supplied endpoint. /// If the port is taken, the given port will be incremented to a free port. /// </summary> public void StartSocket(IPEndPoint endpoint) { Self = new NetConnection(false, false, this, endpoint); socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); try { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null); } catch { NetLog.Warning("Failed to set control code for ignoring ICMP port unreachable."); } socket.ReceiveBufferSize = 4194304; if (socket.ReceiveBufferSize != 4194304) { NetLog.Warning("ReceiveBufferSize restricted by OS."); } socket.SendBufferSize = 1048576; socket.Blocking = false; try { socket.Bind(endpoint); } catch (SocketException e) { if (e.ErrorCode == 10048) { var newEp = new IPEndPoint(endpoint.Address, endpoint.Port + 1); NetLog.Warning("Port in use. Incrementing and retrying..."); StartSocket(newEp); } else { NetLog.Error(e.Message); } return; } NetLog.Info(NetTime.StartDateTime() + " | Socket Started. Bound to: " + endpoint); NetTime.Milliseconds(); if (ProtocolAuthority) { Rpc.AssignLocalRpcs(); } Events.SocketStart(); }
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]); }
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); }
internal void RemovePeerSelf(NetZone zone) { NetLog.Info("Removing zone"); if (peerLookup.ContainsKey(zone.ServerEndpoint)) { peerLookup.Remove(zone.ServerEndpoint); } else if (peerLookup.ContainsValue(zone)) { NetLog.Warning("RemovePeer: Zone endpoint mismatch."); } if (peers.Contains(zone)) { peers.Remove(zone); } else { NetLog.Info("RemovePeer: Zone not in peer list."); } }
/// <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; } }