internal override void ReceiveMessage(NetIncomingMessage msg) { // ack no matter what m_connection.QueueAck(msg.m_receivedMessageType, msg.m_sequenceNumber); m_peer.ReleaseMessage(msg); }
public override void OnCalled(Message msg, NetIncomingMessage netMsg = null) { MessagePlayerHookReleased message = msg as MessagePlayerHookReleased; var player = MultiplayerManager.instance.m_players.FirstOrDefault(x => x.ID == message.playerId); player.PlayerGameObject.GetComponent<PlayerRemote>().OnPlayerHookReleased(); }
//This is called very first when a client connects to the server, but before OnPlayerConnected private static void ApproveConnection(NetIncomingMessage netIncomingMessage) { netIncomingMessage.SenderConnection.Approve(); //Other things you can do: spawn a separate thread that eventually decides if a connection should be approved or not, //then approve the connection in the gameupdate loop }
public Rock(NetIncomingMessage Message) : base() { Texture = GameClient.ContentManager.Load<Texture2D>("RockFull"); ID = Message.ReadInt64(); BoundingBox = Message.ReadRectangle(); }
public void Decode(NetIncomingMessage im) { this.MessageTime = im.ReadDouble(); this.Id = im.ReadInt32(); this.OldPosition = im.ReadInt32(); this.NewPosition = im.ReadInt32(); }
public void Decode(NetIncomingMessage im) { this.BlockID = im.ReadByte(); this.X = im.ReadInt16(); this.Y = im.ReadInt16(); this.Z = im.ReadByte(); }
public static Packet decode(ref NetIncomingMessage msg) { Packet p = new Packet (0); p.type = msg.ReadByte (); p.clientId = msg.ReadInt32 (); return p; }
public override void Init(NetIncomingMessage msg, params float[] p_afInitFloats) { this.rcShadow = new StaticRenderComponent(CAS.RegionContent.Load<Texture2D>("Sprites/Monster/Winterland/Frostling Scoundrel/Shadow"), this.xTransform); Program.game.xRenderMaster.RegisterShadowLayer(this.rcShadow, 60); this.fVelocity = p_afInitFloats[0]; this.v2Direction = new Vector2(p_afInitFloats[1], p_afInitFloats[2]); }
public ClientDisconnectedTransferableData(NetIncomingMessage message) { SessionID = message.ReadInt64(); ID = message.ReadInt32(); IsValid = message.ReadBoolean(); PlayerIndex = message.ReadInt16(); }
public void Run(ManagerLogger managerLogger, Server server, NetIncomingMessage inc, PlayerAndConnection playerAndConnection, GameRoom gameRoom) { managerLogger.AddLogMessage("server", "New connection..."); var data = inc.ReadByte(); if (data == (byte)PacketType.Login) { managerLogger.AddLogMessage("server", "..connection accpeted."); playerAndConnection = CreatePlayer(inc, gameRoom.Players, gameRoom.ManagerCamera); inc.SenderConnection.Approve(); var outmsg = server.NetServer.CreateMessage(); outmsg.Write((byte)PacketType.Login); outmsg.Write(true); outmsg.Write(gameRoom.Players.Count); for (int n = 0; n < gameRoom.Players.Count; n++) { var p = gameRoom.Players[n]; outmsg.Write(p.Player.Username); outmsg.WriteAllProperties(p.Player.Position); } server.NetServer.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered, 0); var command = new PlayerPositionCommand(); command.Run(managerLogger, server,inc,playerAndConnection,gameRoom); server.SendNewPlayerEvent(playerAndConnection.Player.Username, gameRoom.GameRoomId); } else { inc.SenderConnection.Deny("Didn't send correct information."); } }
internal void ReleaseMessage(NetIncomingMessage msg) { NetException.Assert(msg.m_incomingMessageType != NetIncomingMessageType.Error); if (msg.m_isFragment) { HandleReleasedFragment(msg); return; } m_releasedIncomingMessages.Enqueue(msg); if (m_messageReceivedEvent != null) m_messageReceivedEvent.Set(); if (m_receiveCallbacks != null) { foreach (var tuple in m_receiveCallbacks) { try { tuple.Item1.Post(tuple.Item2, this); } catch (Exception ex) { LogWarning("Receive callback exception:" + ex); } } } }
public void Decode(NetIncomingMessage im) { this.ID = im.ReadByte(); this.Message = im.ReadString(); if (Message.Length > Networking.Messages.ChatMessage.MaxLength) Message= Message.Truncate(Networking.Messages.ChatMessage.MaxLength); }
// Constructor public ConnectionRequestEventArgs(NetIncomingMessage msg, string note, string username, string password) { this.msg = msg; this.username = username; this.password = password; this.note = note; }
public override void ReadPayload(NetIncomingMessage message) { base.ReadPayload(message); Image = message.ReadBytes(message.ReadInt32()); Number = message.ReadUInt32(); SendIndex = message.ReadInt32(); }
public static new Packet FromNetBuffer(NetIncomingMessage incomingMessage) { var id = incomingMessage.ReadInt32(); var type = (ContentType)incomingMessage.ReadByte(); var packet = new ContentReleasePacket(type, id); return packet; }
public static void ToOtherPlayers(NetIncomingMessage im, OtherPlayer[] d) { bool alive = im.ReadBoolean(); float xp = im.ReadFloat(); float yp = im.ReadFloat(); float zp = im.ReadFloat(); Int32 id = im.ReadInt32(); float xr = im.ReadFloat(); float yr = im.ReadFloat(); Int16 model = im.ReadInt16(); if (d[id] == null) { d[id] = new OtherPlayer(xp, yp, zp, id, model, xr, yr); } d[id].model = model; d[id].xr = xr; d[id].yr = yr; if (!alive) { d[id].ChangeLifeStatus(false); } d[id].position = new Vector3(xp, yp, zp); d[id].boundingSphere.Center = new Vector3(d[id].position.X, d[id].position.Y + Constants.HEADMAX/2, d[id].position.Z); }
public override void Read(NetIncomingMessage msg) { Id = msg.ReadUInt16(); int count = msg.ReadInt32(); for(int i = 0; i < count; ++i) Cards.Add(msg.ReadString()); }
public void Decode(NetIncomingMessage im) { this.MessageTime = im.ReadDouble(); this.Id = im.ReadInt32(); this.EquipmentPosition = im.ReadInt32(); this.InventoryPosition = im.ReadInt32(); }
internal override void ReceiveMessage(NetIncomingMessage message) { int relate = NetUtility.RelativeSequenceNumber(message.m_sequenceNumber, m_windowStart); // ack no matter what m_connection.QueueAck(message.m_receivedMessageType, message.m_sequenceNumber); if (relate == 0) { // Log("Received message #" + message.SequenceNumber + " right on time"); // // excellent, right on time // //m_peer.LogVerbose("Received RIGHT-ON-TIME " + message); AdvanceWindow(); m_peer.ReleaseMessage(message); // release withheld messages int nextSeqNr = (message.m_sequenceNumber + 1) % NetConstants.NumSequenceNumbers; while (m_earlyReceived[nextSeqNr % m_windowSize]) { message = m_withheldMessages[nextSeqNr % m_windowSize]; NetException.Assert(message != null); // remove it from withheld messages m_withheldMessages[nextSeqNr % m_windowSize] = null; m_peer.LogVerbose("Releasing withheld message #" + message); m_peer.ReleaseMessage(message); AdvanceWindow(); nextSeqNr++; } return; } if (relate < 0) { m_peer.LogVerbose("Received message #" + message.m_sequenceNumber + " DROPPING DUPLICATE"); // duplicate return; } // relate > 0 = early message if (relate > m_windowSize) { // too early message! m_peer.LogDebug("Received " + message + " TOO EARLY! Expected " + m_windowStart); return; } m_earlyReceived.Set(message.m_sequenceNumber % m_windowSize, true); m_peer.LogVerbose("Received " + message + " WITHHOLDING, waiting for " + m_windowStart); m_withheldMessages[message.m_sequenceNumber % m_windowSize] = message; }
public void Decode(NetIncomingMessage im) { Shots = im.ReadInt32(); Hits = im.ReadInt32(); Misses = im.ReadInt32(); ShipsKilled = im.ReadInt32(); }
internal override void ReceiveMessage(NetIncomingMessage msg) { if (m_doFlowControl) m_connection.QueueAck(msg.m_receivedMessageType, msg.m_sequenceNumber); m_peer.ReleaseMessage(msg); }
/// <summary> /// read the message /// </summary> /// <param name="message">message to read from</param> public void OnDeserialize(NetIncomingMessage message) { X = message.ReadFloat(); Y = message.ReadFloat(); Z = message.ReadFloat(); W = message.ReadFloat(); }
private void InitializeNetwork() { lock (m_initializeLock) { m_configuration.Lock(); if (m_status == NetPeerStatus.Running) return; InitializePools(); m_releasedIncomingMessages.Clear(); m_unsentUnconnectedMessages.Clear(); m_handshakes.Clear(); // bind to socket IPEndPoint iep = null; iep = new IPEndPoint(m_configuration.LocalAddress, m_configuration.Port); EndPoint ep = (EndPoint)iep; m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize; m_socket.SendBufferSize = m_configuration.SendBufferSize; m_socket.Blocking = false; m_socket.Bind(ep); IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint; LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound); m_listenPort = boundEp.Port; m_receiveBuffer = new byte[m_configuration.ReceiveBufferSize]; m_sendBuffer = new byte[m_configuration.SendBufferSize]; m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error); m_readHelperMessage.m_data = m_receiveBuffer; byte[] macBytes = new byte[8]; NetRandom.Instance.NextBytes(macBytes); #if IS_MAC_AVAILABLE System.Net.NetworkInformation.PhysicalAddress pa = NetUtility.GetMacAddress(); if (pa != null) { macBytes = pa.GetAddressBytes(); LogVerbose("Mac address is " + NetUtility.ToHexString(macBytes)); } else { LogWarning("Failed to get Mac address"); } #endif byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode()); byte[] combined = new byte[epBytes.Length + macBytes.Length]; Array.Copy(epBytes, 0, combined, 0, epBytes.Length); Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.Length); m_uniqueIdentifier = BitConverter.ToInt64(SHA1.Create().ComputeHash(combined), 0); m_status = NetPeerStatus.Running; } }
/// <summary> /// Alerts the packet service about possible packets that need processing /// </summary> /// <param name="packetID">The type of packet that is expected</param> /// <param name="incomingMessage">The data contained within the packet</param> public void ProcessPacket(int packetID, NetIncomingMessage incomingMessage) { //TODO: Type.InvokeMember(...) is an expensive call. Do monitor this if at all possible. //It'll likely be fine, and it adds great design addition. No nasty switches. Send and forget. if (!_cache.ContainsKey(packetID)) throw new Exception("The given packet type is missing! Was it marked properly and given an attribute?"); //Take our incoming message and type var type = _cache[packetID]; var val = new object[1]; val[0] = incomingMessage; //Take the given type in the context and create our packet from it // Try and fetch the packet, otherwise abort it var returnValue = (Packet)type.InvokeMember("FromNetBuffer", BindingFlags.InvokeMethod, null, type, val); returnValue.Sender = incomingMessage.SenderConnection; //Automated packet service _packetService.ProcessReceivedPacket(returnValue); //Logger.Instance.Log(Level.Warn, "A packet that had a malformed payload was attempt to be sent. Ignoring for now."); }
public void Decode(NetIncomingMessage im) { this.Value = (ResultOfAttack) im.ReadInt32(); this.Text = im.ReadString(); this.Row = im.ReadInt32(); this.Col = im.ReadInt32(); }
private void ReadData(AttributeTypeID Type, NetIncomingMessage Message) { switch(Type) { case AttributeTypeID.Float: Data = Message.ReadFloat(); break; case AttributeTypeID.Int: Data = Message.ReadInt32(); break; case AttributeTypeID.List: Console.WriteLine("AttributeSystem: List<> Type not supported on network sync"); break; case AttributeTypeID.Long: Data = Message.ReadInt64(); break; case AttributeTypeID.Rectangle: Data = Message.ReadRectangle(); break; case AttributeTypeID.String: Data = Message.ReadString(); break; case AttributeTypeID.Vector2: Data = Message.ReadVector2(); break; case AttributeTypeID.Bool: Data = Message.ReadBoolean(); break; default: Console.WriteLine("Invalid Attribute Type: {0}", Type.ToString()); break; } }
/// <summary> /// Writes a <see cref="NetIncomingMessage"/> buffer into the BitStream. /// </summary> /// <param name="source">The <see cref="NetIncomingMessage"/> who's contents will be copied to this BitStream.</param> public void Write(NetIncomingMessage source) { #if DEBUG var startBSPos = PositionBits; var startMsgPos = (int)source.Position; #endif // Read full 32-bit integers while (source.LengthBits - source.Position >= _bitsInt) { var v = source.ReadUInt32(); Write(v); } // Read full 8-bit integers while (source.LengthBits - source.Position >= _bitsByte) { var v = source.ReadByte(); Write(v); } // Read the remaining bits while (source.LengthBits > source.Position) { var v = source.ReadBoolean(); Write(v); } Debug.Assert(source.Position == source.LengthBits); #if DEBUG Debug.Assert(PositionBits - startBSPos == source.LengthBits - startMsgPos); #endif }
public void Decode(NetIncomingMessage im) { this.Username = im.ReadString(); this.ID = im.ReadByte(); this.Me = im.ReadBoolean(); this.Color = new Color(im.ReadByte(), im.ReadByte(), im.ReadByte()); }
public override void ReadPayload(NetIncomingMessage message) { base.ReadPayload(message); Region = new Rectangle(message.ReadInt32(), message.ReadInt32(), message.ReadInt32(), message.ReadInt32()); Number = message.ReadUInt32(); FinalLength = message.ReadInt32(); }
public override void Init(NetIncomingMessage msg, params float[] p_afInitFloats) { this.fStartRotation = p_afInitFloats[2]; this.localRand = new Random((int)p_afInitFloats[3]); this.iStartup = (int)p_afInitFloats[4]; this.SetOwner(new Vector2(p_afInitFloats[0], p_afInitFloats[1])); }
public override void ReadInUpdateData(Lidgren.Network.NetIncomingMessage im) { base.ReadInUpdateData(im); elapsedTime = im.ReadFloat(); updateMenu(); }
/// <summary> /// Deserialize the array from the message /// </summary> /// <param name="message"></param> public void OnDeserialize(Lidgren.Network.NetIncomingMessage message) { var length = message.ReadInt32(); items = new T[length]; for (int i = 0; i < length; i++) { var t = new T(); t.OnDeserialize(message); items[i] = t; } }
/// <summary> /// deserialize from the message /// </summary> /// <param name="message"></param> public void OnDeserialize(Lidgren.Network.NetIncomingMessage message) { var size = message.ReadInt32(); dictionary = new Dictionary <T, U>(size); for (int i = 0; i < size; ++i) { var key = message.Read <T>(); var value = message.Read <U>(); dictionary[key] = value; } }
private void InitializeNetwork() { lock (m_initializeLock) { m_configuration.Lock(); if (m_status == NetPeerStatus.Running) { return; } if (m_configuration.m_enableUPnP) { m_upnp = new NetUPnP(this); } InitializePools(); m_releasedIncomingMessages.Clear(); m_unsentUnconnectedMessages.Clear(); m_handshakes.Clear(); // bind to socket IPEndPoint iep = null; iep = new IPEndPoint(m_configuration.LocalAddress, m_configuration.Port); EndPoint ep = (EndPoint)iep; m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize; m_socket.SendBufferSize = m_configuration.SendBufferSize; m_socket.Blocking = false; m_socket.Bind(ep); var platform = Environment.OSVersion.Platform; if (platform != PlatformID.MacOSX && platform != PlatformID.Unix) { try { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); } catch { // ignore; SIO_UDP_CONNRESET not supported on this platform } } IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint; LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound); m_listenPort = boundEp.Port; m_receiveBuffer = new byte[m_configuration.ReceiveBufferSize]; m_sendBuffer = new byte[m_configuration.SendBufferSize]; m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error); m_readHelperMessage.m_data = m_receiveBuffer; byte[] macBytes = new byte[8]; NetRandom.Instance.NextBytes(macBytes); #if IS_MAC_AVAILABLE try { System.Net.NetworkInformation.PhysicalAddress pa = NetUtility.GetMacAddress(); if (pa != null) { macBytes = pa.GetAddressBytes(); LogVerbose("Mac address is " + NetUtility.ToHexString(macBytes)); } else { LogWarning("Failed to get Mac address"); } } catch (NotSupportedException) { // not supported; lets just keep the random bytes set above } #endif byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode()); byte[] combined = new byte[epBytes.Length + macBytes.Length]; Array.Copy(epBytes, 0, combined, 0, epBytes.Length); Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.Length); m_uniqueIdentifier = BitConverter.ToInt64(SHA1.Create().ComputeHash(combined), 0); m_status = NetPeerStatus.Running; } }
private void ReceiveSocketData(double now) { int bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); if (bytesReceived < NetConstants.HeaderByteSize) { return; } //LogVerbose("Received " + bytesReceived + " bytes"); var ipsender = (NetEndPoint)m_senderRemote; if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32) { // is this an UPnP response? string resp = System.Text.Encoding.UTF8.GetString(m_receiveBuffer, 0, bytesReceived); if (resp.Contains("upnp:rootdevice") || resp.Contains("UPnP/1.0")) { try { resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); m_upnp.ExtractServiceUrl(resp); return; } catch (Exception ex) { LogDebug("Failed to parse UPnP response: " + ex.ToString()); // don't try to parse this packet further return; } } } NetConnection sender = null; m_connectionLookup.TryGetValue(ipsender, out sender); // // parse packet into messages // int numMessages = 0; int numFragments = 0; int ptr = 0; while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize) { // decode header // 8 bits - NetMessageType // 1 bit - Fragment? // 15 bits - Sequence number // 16 bits - Payload length in bits numMessages++; NetMessageType tp = (NetMessageType)m_receiveBuffer[ptr++]; byte low = m_receiveBuffer[ptr++]; byte high = m_receiveBuffer[ptr++]; bool isFragment = ((low & 1) == 1); ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7)); if (isFragment) { numFragments++; } ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8)); int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength); if (bytesReceived - ptr < payloadByteLength) { LogWarning("Malformed packet; stated payload length " + payloadByteLength + ", remaining bytes " + (bytesReceived - ptr)); return; } if (tp >= NetMessageType.Unused1 && tp <= NetMessageType.Unused29) { ThrowOrLog("Unexpected NetMessageType: " + tp); return; } try { if (tp >= NetMessageType.LibraryError) { if (sender != null) { sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength); } else { ReceivedUnconnectedLibraryMessage(now, ipsender, tp, ptr, payloadByteLength); } } else { if (sender == null && !m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) { return; // dropping unconnected message since it's not enabled } NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength); msg.m_isFragment = isFragment; msg.m_receiveTime = now; msg.m_sequenceNumber = sequenceNumber; msg.m_receivedMessageType = tp; msg.m_senderConnection = sender; msg.m_senderEndPoint = ipsender; msg.m_bitLength = payloadBitLength; Buffer.BlockCopy(m_receiveBuffer, ptr, msg.m_data, 0, payloadByteLength); if (sender != null) { if (tp == NetMessageType.Unconnected) { // We're connected; but we can still send unconnected messages to this peer msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } else { // connected application (non-library) message sender.ReceivedMessage(msg); } } else { // at this point we know the message type is enabled // unconnected application (non-library) message msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } } } catch (Exception ex) { LogError("Packet parsing error: " + ex.Message + " from " + ipsender); } ptr += payloadByteLength; } m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); if (sender != null) { sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); } }
private void Heartbeat() { VerifyNetworkThread(); double dnow = NetTime.Now; float now = (float)dnow; double delta = dnow - m_lastHeartbeat; int maxCHBpS = 1250 - m_connections.Count; if (maxCHBpS < 250) { maxCHBpS = 250; } if (delta > (1.0 / (double)maxCHBpS)) // max connection heartbeats/second max { m_frameCounter++; m_lastHeartbeat = dnow; // do handshake heartbeats if ((m_frameCounter % 3) == 0) { foreach (var kvp in m_handshakes) { NetConnection conn = kvp.Value as NetConnection; #if DEBUG // sanity check if (kvp.Key != kvp.Key) { LogWarning("Sanity fail! Connection in handshake list under wrong key!"); } #endif conn.UnconnectedHeartbeat(now); if (conn.m_status == NetConnectionStatus.Connected || conn.m_status == NetConnectionStatus.Disconnected) { #if DEBUG // sanity check if (conn.m_status == NetConnectionStatus.Disconnected && m_handshakes.ContainsKey(conn.RemoteEndpoint)) { LogWarning("Sanity fail! Handshakes list contained disconnected connection!"); m_handshakes.Remove(conn.RemoteEndpoint); } #endif break; // collection has been modified } } } #if DEBUG SendDelayedPackets(); #endif // do connection heartbeats lock (m_connections) { foreach (NetConnection conn in m_connections) { conn.Heartbeat(now, m_frameCounter); if (conn.m_status == NetConnectionStatus.Disconnected) { // // remove connection // m_connections.Remove(conn); m_connectionLookup.Remove(conn.RemoteEndpoint); break; // can't continue iteration here } } } // send unsent unconnected messages NetTuple <IPEndPoint, NetOutgoingMessage> unsent; while (m_unsentUnconnectedMessages.TryDequeue(out unsent)) { NetOutgoingMessage om = unsent.Item2; #if DEBUG if (om.m_messageType == NetMessageType.NatPunchMessage) { LogDebug("Sending Nat Punch Message to " + unsent.Item1.ToString()); } #endif bool connReset; int len = om.Encode(m_sendBuffer, 0, 0); SendPacket(len, unsent.Item1, 1, out connReset); Interlocked.Decrement(ref om.m_recyclingCount); if (om.m_recyclingCount <= 0) { Recycle(om); } } } // // read from socket // if (m_socket == null) { return; } if (!m_socket.Poll(1000, SelectMode.SelectRead)) // wait up to 1 ms for data to arrive { return; } //if (m_socket == null || m_socket.Available < 1) // return; do { int bytesReceived = 0; try { bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); } catch (SocketException sx) { if (sx.SocketErrorCode == SocketError.ConnectionReset) { // connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable" // we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?! // So, what to do? return; } LogWarning(sx.ToString()); return; } if (bytesReceived < NetConstants.HeaderByteSize) { return; } //LogVerbose("Received " + bytesReceived + " bytes"); IPEndPoint ipsender = (IPEndPoint)m_senderRemote; if (ipsender.Port == 1900) { // UPnP response try { string resp = System.Text.Encoding.ASCII.GetString(m_receiveBuffer, 0, bytesReceived); if (resp.Contains("upnp:rootdevice")) { resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); m_upnp.ExtractServiceUrl(resp); return; } } catch { } } NetConnection sender = null; m_connectionLookup.TryGetValue(ipsender, out sender); double receiveTime = NetTime.Now; // // parse packet into messages // int numMessages = 0; int ptr = 0; while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize) { // decode header // 8 bits - NetMessageType // 1 bit - Fragment? // 15 bits - Sequence number // 16 bits - Payload length in bits numMessages++; NetMessageType tp = (NetMessageType)m_receiveBuffer[ptr++]; byte low = m_receiveBuffer[ptr++]; byte high = m_receiveBuffer[ptr++]; bool isFragment = ((low & 1) == 1); ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7)); ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8)); int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength); if (bytesReceived - ptr < payloadByteLength) { LogWarning("Malformed packet; stated payload length " + payloadByteLength + ", remaining bytes " + (bytesReceived - ptr)); return; } try { NetException.Assert(tp <NetMessageType.Unused1 || tp> NetMessageType.Unused29); if (tp >= NetMessageType.LibraryError) { if (sender != null) { sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength); } else { ReceivedUnconnectedLibraryMessage(receiveTime, ipsender, tp, ptr, payloadByteLength); } } else { if (sender == null && !m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) { return; // dropping unconnected message since it's not enabled } NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength); msg.m_isFragment = isFragment; msg.m_receiveTime = receiveTime; msg.m_sequenceNumber = sequenceNumber; msg.m_receivedMessageType = tp; msg.m_senderConnection = sender; msg.m_senderEndpoint = ipsender; msg.m_bitLength = payloadBitLength; Buffer.BlockCopy(m_receiveBuffer, ptr, msg.m_data, 0, payloadByteLength); if (sender != null) { if (tp == NetMessageType.Unconnected) { // We're connected; but we can still send unconnected messages to this peer msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } else { // connected application (non-library) message sender.ReceivedMessage(msg); } } else { // at this point we know the message type is enabled // unconnected application (non-library) message msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } } } catch (Exception ex) { LogError("Packet parsing error: " + ex.Message + " from " + ipsender); } ptr += payloadByteLength; } m_statistics.PacketReceived(bytesReceived, numMessages); if (sender != null) { sender.m_statistics.PacketReceived(bytesReceived, numMessages); } } while (m_socket.Available > 0); }
/// <summary> /// Reads a pending message from any connection, if any. /// Returns true if message was read, otherwise false. /// </summary> /// <returns>True, if message was read.</returns> public bool ReadMessage(out NetIncomingMessage message) { message = ReadMessage(); return(message != null); }
private void InitializeNetwork() { lock (m_initializeLock) { m_configuration.Lock(); if (m_status == NetPeerStatus.Running) { return; } if (m_configuration.m_enableUPnP) { m_upnp = new NetUPnP(this); } InitializePools(); m_releasedIncomingMessages.Clear(); m_unsentUnconnectedMessages.Clear(); m_handshakes.Clear(); // bind to socket BindSocket(false); m_receiveBuffer = new byte[m_configuration.ReceiveBufferSize]; m_sendBuffer = new byte[m_configuration.SendBufferSize]; m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error); m_readHelperMessage.m_data = m_receiveBuffer; byte[] macBytes = new byte[8]; MWCRandom.Instance.NextBytes(macBytes); #if IS_MAC_AVAILABLE try { System.Net.NetworkInformation.PhysicalAddress pa = NetUtility.GetMacAddress(); if (pa != null) { macBytes = pa.GetAddressBytes(); LogVerbose("Mac address is " + NetUtility.ToHexString(macBytes)); } else { LogWarning("Failed to get Mac address"); } } catch (NotSupportedException) { // not supported; lets just keep the random bytes set above } #endif IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint; byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode()); byte[] combined = new byte[epBytes.Length + macBytes.Length]; Array.Copy(epBytes, 0, combined, 0, epBytes.Length); Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.Length); m_uniqueIdentifier = BitConverter.ToInt64(NetUtility.CreateSHA1Hash(combined), 0); m_status = NetPeerStatus.Running; } }
private void Heartbeat() { VerifyNetworkThread(); double now = NetTime.Now; double delta = now - m_lastHeartbeat; int maxCHBpS = 1250 - m_connections.Count; if (maxCHBpS < 250) { maxCHBpS = 250; } if (delta > (1.0 / maxCHBpS) || delta < 0.0) // max connection heartbeats/second max { m_frameCounter++; m_lastHeartbeat = now; // do handshake heartbeats if ((m_frameCounter % 3) == 0) { foreach (var kvp in m_handshakes) { NetConnection conn = kvp.Value as NetConnection; #if DEBUG // sanity check if (kvp.Key != kvp.Key) { LogWarning("Sanity fail! Connection in handshake list under wrong key!"); } #endif conn.UnconnectedHeartbeat(now); if (conn.m_status == NetConnectionStatus.Connected || conn.m_status == NetConnectionStatus.Disconnected) { #if DEBUG // sanity check if (conn.m_status == NetConnectionStatus.Disconnected && m_handshakes.ContainsKey(conn.RemoteEndPoint)) { LogWarning("Sanity fail! Handshakes list contained disconnected connection!"); m_handshakes.Remove(conn.RemoteEndPoint); } #endif break; // collection has been modified } } } #if DEBUG SendDelayedPackets(); #endif // update m_executeFlushSendQueue if (m_configuration.m_autoFlushSendQueue && m_needFlushSendQueue == true) { m_executeFlushSendQueue = true; m_needFlushSendQueue = false; // a race condition to this variable will simply result in a single superfluous call to FlushSendQueue() } // do connection heartbeats lock (m_connections) { for (int i = m_connections.Count - 1; i >= 0; i--) { var conn = m_connections[i]; conn.Heartbeat(now, m_frameCounter); if (conn.m_status == NetConnectionStatus.Disconnected) { // // remove connection // m_connections.RemoveAt(i); m_connectionLookup.Remove(conn.RemoteEndPoint); } } } m_executeFlushSendQueue = false; // send unsent unconnected messages Tuple <IPEndPoint, NetOutgoingMessage> unsent; while (m_unsentUnconnectedMessages.TryDequeue(out unsent)) { NetOutgoingMessage om = unsent.Item2; int len = om.Encode(m_sendBuffer, 0, 0); Interlocked.Decrement(ref om.m_recyclingCount); if (om.m_recyclingCount <= 0) { Recycle(om); } bool connReset; SendPacket(len, unsent.Item1, 1, out connReset); } } // // read from socket // if (m_socket == null) { return; } if (!m_socket.Poll(1000, SelectMode.SelectRead)) // wait up to 1 ms for data to arrive { return; } //if (m_socket == null || m_socket.Available < 1) // return; // update now now = NetTime.Now; do { int bytesReceived = 0; try { bytesReceived = m_socket.ReceiveFrom(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, ref m_senderRemote); } catch (SocketException sx) { switch (sx.SocketErrorCode) { case SocketError.ConnectionReset: // connection reset by peer, aka connection forcibly closed aka "ICMP port unreachable" // we should shut down the connection; but m_senderRemote seemingly cannot be trusted, so which connection should we shut down?! // So, what to do? LogWarning("ConnectionReset"); return; case SocketError.NotConnected: // socket is unbound; try to rebind it (happens on mobile when process goes to sleep) BindSocket(true); return; default: LogWarning("Socket exception: " + sx.ToString()); return; } } if (bytesReceived < NetConstants.HeaderByteSize) { return; } //LogVerbose("Received " + bytesReceived + " bytes"); IPEndPoint ipsender = (IPEndPoint)m_senderRemote; if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32) { // is this an UPnP response? string resp = System.Text.Encoding.ASCII.GetString(m_receiveBuffer, 0, bytesReceived); if (resp.Contains("upnp:rootdevice") || resp.Contains("UPnP/1.0")) { try { resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); m_upnp.ExtractServiceUrl(resp); return; } catch (Exception ex) { LogDebug("Failed to parse UPnP response: " + ex.ToString()); // don't try to parse this packet further return; } } } NetConnection sender = null; m_connectionLookup.TryGetValue(ipsender, out sender); // // parse packet into messages // int numMessages = 0; int numFragments = 0; int ptr = 0; while ((bytesReceived - ptr) >= NetConstants.HeaderByteSize) { // decode header // 8 bits - NetMessageType // 1 bit - Fragment? // 15 bits - Sequence number // 16 bits - Payload length in bits numMessages++; NetMessageType tp = (NetMessageType)m_receiveBuffer[ptr++]; byte low = m_receiveBuffer[ptr++]; byte high = m_receiveBuffer[ptr++]; bool isFragment = ((low & 1) == 1); ushort sequenceNumber = (ushort)((low >> 1) | (((int)high) << 7)); numFragments++; ushort payloadBitLength = (ushort)(m_receiveBuffer[ptr++] | (m_receiveBuffer[ptr++] << 8)); int payloadByteLength = NetUtility.BytesToHoldBits(payloadBitLength); if (bytesReceived - ptr < payloadByteLength) { LogWarning("Malformed packet; stated payload length " + payloadByteLength + ", remaining bytes " + (bytesReceived - ptr)); return; } if (tp >= NetMessageType.Unused1 && tp <= NetMessageType.Unused29) { ThrowOrLog("Unexpected NetMessageType: " + tp); return; } try { if (tp >= NetMessageType.LibraryError) { if (sender != null) { sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength); } else { ReceivedUnconnectedLibraryMessage(now, ipsender, tp, ptr, payloadByteLength); } } else { if (sender == null && !m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.UnconnectedData)) { return; // dropping unconnected message since it's not enabled } NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength); msg.m_isFragment = isFragment; msg.m_receiveTime = now; msg.m_sequenceNumber = sequenceNumber; msg.m_receivedMessageType = tp; msg.m_senderConnection = sender; msg.m_senderEndPoint = ipsender; msg.m_bitLength = payloadBitLength; Buffer.BlockCopy(m_receiveBuffer, ptr, msg.m_data, 0, payloadByteLength); if (sender != null) { if (tp == NetMessageType.Unconnected) { // We're connected; but we can still send unconnected messages to this peer msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } else { // connected application (non-library) message sender.ReceivedMessage(msg); } } else { // at this point we know the message type is enabled // unconnected application (non-library) message msg.m_incomingMessageType = NetIncomingMessageType.UnconnectedData; ReleaseMessage(msg); } } } catch (Exception ex) { LogError("Packet parsing error: " + ex.Message + " from " + ipsender); } ptr += payloadByteLength; } m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); if (sender != null) { sender.m_statistics.PacketReceived(bytesReceived, numMessages, numFragments); } } while (m_socket.Available > 0); }
private void HandleReleasedFragment(NetIncomingMessage im) { VerifyNetworkThread(); // // read fragmentation header and combine fragments // int group; int totalBits; int chunkByteSize; int chunkNumber; int ptr = NetFragmentationHelper.ReadHeader( im.m_data, 0, out group, out totalBits, out chunkByteSize, out chunkNumber ); NetException.Assert(im.LengthBytes > ptr); NetException.Assert(group > 0); NetException.Assert(totalBits > 0); NetException.Assert(chunkByteSize > 0); int totalBytes = NetUtility.BytesToHoldBits((int)totalBits); int totalNumChunks = totalBytes / chunkByteSize; if (totalNumChunks * chunkByteSize < totalBytes) { totalNumChunks++; } NetException.Assert(chunkNumber < totalNumChunks); if (chunkNumber >= totalNumChunks) { LogWarning("Index out of bounds for chunk " + chunkNumber + " (total chunks " + totalNumChunks + ")"); return; } Dictionary <int, ReceivedFragmentGroup> groups; if (!m_receivedFragmentGroups.TryGetValue(im.SenderConnection, out groups)) { groups = new Dictionary <int, ReceivedFragmentGroup>(); m_receivedFragmentGroups[im.SenderConnection] = groups; } ReceivedFragmentGroup info; if (!groups.TryGetValue(group, out info)) { info = new ReceivedFragmentGroup(); info.Data = new byte[totalBytes]; info.ReceivedChunks = new NetBitVector(totalNumChunks); groups[group] = info; } info.ReceivedChunks[chunkNumber] = true; //info.LastReceived = (float)NetTime.Now; // copy to data int offset = (chunkNumber * chunkByteSize); Buffer.BlockCopy(im.m_data, ptr, info.Data, offset, im.LengthBytes - ptr); int cnt = info.ReceivedChunks.Count(); //LogVerbose("Found fragment #" + chunkNumber + " in group " + group + " offset " + offset + " of total bits " + totalBits + " (total chunks done " + cnt + ")"); LogVerbose("Received fragment " + chunkNumber + " of " + totalNumChunks + " (" + cnt + " chunks received)"); if (info.ReceivedChunks.Count() == totalNumChunks) { // Done! Transform this incoming message im.m_data = info.Data; im.m_bitLength = (int)totalBits; im.m_isFragment = false; LogVerbose("Fragment group #" + group + " fully received in " + totalNumChunks + " chunks (" + totalBits + " bits)"); groups.Remove(group); ReleaseMessage(im); } else { // data has been copied; recycle this incoming message Recycle(im); } return; }
// received a library message while Connected internal void ReceivedLibraryMessage(NetMessageType tp, int ptr, int payloadLength) { m_peer.VerifyNetworkThread(); double now = NetTime.Now; switch (tp) { case NetMessageType.Connect: m_peer.LogDebug("Received handshake message (" + tp + ") despite connection being in place"); break; case NetMessageType.ConnectResponse: // handshake message must have been lost HandleConnectResponse(now, tp, ptr, payloadLength); break; case NetMessageType.ConnectionEstablished: // do nothing, all's well break; case NetMessageType.LibraryError: m_peer.ThrowOrLog("LibraryError received by ReceivedLibraryMessage; this usually indicates a malformed message"); break; case NetMessageType.Disconnect: NetIncomingMessage msg = m_peer.SetupReadHelperMessage(ptr, payloadLength); m_disconnectRequested = true; m_disconnectMessage = msg.ReadString(); m_disconnectReqSendBye = false; //ExecuteDisconnect(msg.ReadString(), false); break; case NetMessageType.Acknowledge: for (int i = 0; i < payloadLength; i += 3) { NetMessageType acktp = (NetMessageType)m_peer.m_receiveBuffer[ptr++]; // netmessagetype int seqNr = m_peer.m_receiveBuffer[ptr++]; seqNr |= (m_peer.m_receiveBuffer[ptr++] << 8); // need to enqueue this and handle it in the netconnection heartbeat; so be able to send resends together with normal sends m_queuedIncomingAcks.Enqueue(new NetTuple <NetMessageType, int>(acktp, seqNr)); } break; case NetMessageType.Ping: int pingNr = m_peer.m_receiveBuffer[ptr++]; SendPong(pingNr); break; case NetMessageType.Pong: NetIncomingMessage pmsg = m_peer.SetupReadHelperMessage(ptr, payloadLength); int pongNr = pmsg.ReadByte(); float remoteSendTime = pmsg.ReadSingle(); ReceivedPong(now, pongNr, remoteSendTime); break; case NetMessageType.ExpandMTURequest: SendMTUSuccess(payloadLength); break; case NetMessageType.ExpandMTUSuccess: if (m_peer.Configuration.AutoExpandMTU == false) { m_peer.LogDebug("Received ExpandMTURequest altho AutoExpandMTU is turned off!"); break; } NetIncomingMessage emsg = m_peer.SetupReadHelperMessage(ptr, payloadLength); int size = emsg.ReadInt32(); HandleExpandMTUSuccess(now, size); break; case NetMessageType.NatIntroduction: // Unusual situation where server is actually already known, but got a nat introduction - oh well, lets handle it as usual m_peer.HandleNatIntroduction(ptr); break; default: m_peer.LogError("Connection received unhandled library message: " + tp); break; } }
internal void ReceivedHandshake(TimeSpan now, NetMessageType type, int offset, int payloadLength) { Peer.AssertIsOnLibraryThread(); switch (type) { case NetMessageType.Connect: if (Status == NetConnectionStatus.ReceivedInitiation) { // Whee! Server full has already been checked var(success, hail, hailLength) = ValidateHandshakeData(offset, payloadLength); if (success) { if (hail != null) { RemoteHailMessage = Peer.CreateIncomingMessage(NetIncomingMessageType.Data); RemoteHailMessage.SetBuffer(hail, true); RemoteHailMessage.ByteLength = hailLength; } else { RemoteHailMessage = null; } if (_peerConfiguration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionApproval)) { // ok, let's not add connection just yet var appMsg = Peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionApproval); appMsg.ReceiveTime = now; appMsg.SenderConnection = this; appMsg.SenderEndPoint = RemoteEndPoint; if (RemoteHailMessage != null) { appMsg.Write(RemoteHailMessage.GetBuffer().AsSpan(0, RemoteHailMessage.ByteLength)); } SetStatus(NetConnectionStatus.RespondedAwaitingApproval); Peer.ReleaseMessage(appMsg); return; } SendConnectResponse(now, true); } return; } if (Status == NetConnectionStatus.RespondedAwaitingApproval) { Peer.LogWarning(new NetLogMessage(NetLogCode.IgnoringMultipleConnects, endPoint: this)); return; } if (Status == NetConnectionStatus.RespondedConnect) { // our ConnectResponse must have been lost SendConnectResponse(now, true); return; } Peer.LogDebug(NetLogMessage.FromValues(NetLogCode.UnhandledConnect, endPoint: this, value: (int)Status)); break; case NetMessageType.ConnectResponse: HandleConnectResponse(offset, payloadLength); break; case NetMessageType.ConnectionEstablished: switch (Status) { case NetConnectionStatus.Connected: // ok... break; case NetConnectionStatus.Disconnected: case NetConnectionStatus.Disconnecting: case NetConnectionStatus.None: // too bad, almost made it break; case NetConnectionStatus.ReceivedInitiation: // uh, a little premature... ignore break; case NetConnectionStatus.InitiatedConnect: // weird, should have been RespondedConnect... break; case NetConnectionStatus.RespondedConnect: // awesome NetIncomingMessage msg = Peer.SetupReadHelperMessage(offset, payloadLength); InitializeRemoteTimeOffset(msg.ReadTimeSpan()); Peer.AcceptConnection(this); InitializePing(); SetStatus(NetConnectionStatus.Connected); return; } break; case NetMessageType.InvalidHandshake: case NetMessageType.WrongAppIdentifier: case NetMessageType.ConnectTimedOut: case NetMessageType.TimedOut: case NetMessageType.Disconnect: NetOutgoingMessage?reason = null; try { reason = Peer.CreateReadHelperOutMessage(offset, payloadLength); } catch { } ExecuteDisconnect(reason, false); break; case NetMessageType.Discovery: Peer.HandleIncomingDiscoveryRequest(now, RemoteEndPoint, offset, payloadLength); return; case NetMessageType.DiscoveryResponse: Peer.HandleIncomingDiscoveryResponse(now, RemoteEndPoint, offset, payloadLength); return; case NetMessageType.Ping: // silently ignore return; default: Peer.LogDebug(NetLogMessage.FromValues(NetLogCode.UnhandledHandshakeMessage, value: (int)Status)); break; } }
internal void ReceivedHandshake(double now, NetMessageType tp, int ptr, int payloadLength) { m_peer.VerifyNetworkThread(); byte[] hail; switch (tp) { case NetMessageType.Connect: if (m_status == NetConnectionStatus.None) { // Whee! Server full has already been checked bool ok = ValidateHandshakeData(ptr, payloadLength, out hail); if (ok) { if (hail != null) { m_remoteHailMessage = m_peer.CreateIncomingMessage(NetIncomingMessageType.Data, hail); m_remoteHailMessage.LengthBits = (hail.Length * 8); } else { m_remoteHailMessage = null; } if (m_peerConfiguration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionApproval)) { // ok, let's not add connection just yet NetIncomingMessage appMsg = m_peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionApproval, (m_remoteHailMessage == null ? 0 : m_remoteHailMessage.LengthBytes)); appMsg.m_receiveTime = now; appMsg.m_senderConnection = this; appMsg.m_senderEndpoint = this.m_remoteEndpoint; if (m_remoteHailMessage != null) { appMsg.Write(m_remoteHailMessage.m_data, 0, m_remoteHailMessage.LengthBytes); } m_peer.ReleaseMessage(appMsg); return; } SendConnectResponse((float)now, true); } return; } if (m_status == NetConnectionStatus.RespondedConnect) { // our ConnectResponse must have been lost SendConnectResponse((float)now, true); return; } m_peer.LogDebug("Unhandled Connect: " + tp + ", status is " + m_status + " length: " + payloadLength); break; case NetMessageType.ConnectResponse: switch (m_status) { case NetConnectionStatus.InitiatedConnect: // awesome bool ok = ValidateHandshakeData(ptr, payloadLength, out hail); if (ok) { if (hail != null) { m_remoteHailMessage = m_peer.CreateIncomingMessage(NetIncomingMessageType.Data, hail); m_remoteHailMessage.LengthBits = (hail.Length * 8); } else { m_remoteHailMessage = null; } m_peer.AcceptConnection(this); SendConnectionEstablished(); return; } break; case NetConnectionStatus.RespondedConnect: // hello, wtf? break; case NetConnectionStatus.Disconnecting: case NetConnectionStatus.Disconnected: case NetConnectionStatus.None: // wtf? anyway, bye! break; case NetConnectionStatus.Connected: // my ConnectionEstablished must have been lost, send another one SendConnectionEstablished(); return; } break; case NetMessageType.ConnectionEstablished: switch (m_status) { case NetConnectionStatus.Connected: // ok... break; case NetConnectionStatus.Disconnected: case NetConnectionStatus.Disconnecting: case NetConnectionStatus.None: // too bad, almost made it break; case NetConnectionStatus.InitiatedConnect: // weird, should have been ConnectResponse... break; case NetConnectionStatus.RespondedConnect: // awesome NetIncomingMessage msg = m_peer.SetupReadHelperMessage(ptr, payloadLength); InitializeRemoteTimeOffset(msg.ReadSingle()); m_peer.AcceptConnection(this); InitializePing(); SetStatus(NetConnectionStatus.Connected, "Connected to " + NetUtility.ToHexString(m_remoteUniqueIdentifier)); return; } break; case NetMessageType.Disconnect: // ouch string reason = "Ouch"; try { NetIncomingMessage inc = m_peer.SetupReadHelperMessage(ptr, payloadLength); reason = inc.ReadString(); } catch { } ExecuteDisconnect(reason, false); break; default: m_peer.LogDebug("Unhandled type during handshake: " + tp + " length: " + payloadLength); break; } }
internal override void ReceiveMessage(NetIncomingMessage message) { int relate = NetUtility.RelativeSequenceNumber(message.m_sequenceNumber, m_windowStart); // ack no matter what m_connection.QueueAck(message.m_receivedMessageType, message.m_sequenceNumber); if (relate == 0) { // Log("Received message #" + message.SequenceNumber + " right on time"); // // excellent, right on time // //m_peer.LogVerbose("Received RIGHT-ON-TIME " + message); AdvanceWindow(); m_peer.ReleaseMessage(message); // release withheld messages int nextSeqNr = (message.m_sequenceNumber + 1) % NetConstants.NumSequenceNumbers; while (m_earlyReceived[nextSeqNr % m_windowSize]) { //message = m_withheldMessages[nextSeqNr % m_windowSize]; //NetException.Assert(message != null); // remove it from withheld messages //m_withheldMessages[nextSeqNr % m_windowSize] = null; //m_peer.LogVerbose("Releasing withheld message #" + message); //m_peer.ReleaseMessage(message); AdvanceWindow(); nextSeqNr++; } return; } if (relate < 0) { // duplicate m_peer.LogVerbose("Received message #" + message.m_sequenceNumber + " DROPPING DUPLICATE"); return; } // relate > 0 = early message if (relate > m_windowSize) { // too early message! m_peer.LogDebug("Received " + message + " TOO EARLY! Expected " + m_windowStart); return; } m_earlyReceived.Set(message.m_sequenceNumber % m_windowSize, true); //m_peer.LogVerbose("Received " + message + " WITHHOLDING, waiting for " + m_windowStart); //m_withheldMessages[message.m_sequenceNumber % m_windowSize] = message; m_peer.ReleaseMessage(message); }
/// <summary> /// Decrypt an incoming message in place /// </summary> public abstract bool Decrypt(NetIncomingMessage msg);