internal override void ReceiveMessage(NetIncomingMessage msg) { if (m_doFlowControl) m_connection.QueueAck(msg.m_receivedMessageType, msg.m_sequenceNumber); m_peer.ReleaseMessage(msg); }
/// <summary> /// Decrypt an incoming message /// </summary> public override bool Decrypt(NetIncomingMessage msg) { int numBytes = msg.LengthBytes; for (int i = 0; i < numBytes; i++) { int offset = i % m_key.Length; msg.m_data[i] = (byte)(msg.m_data[i] ^ m_key[offset]); } return true; }
/// <summary> /// Recycles a NetIncomingMessage instance for reuse; taking pressure off the garbage collector /// </summary> public void Recycle(NetIncomingMessage msg) { if (m_incomingMessagesPool == null || msg == null) return; NetException.Assert(m_incomingMessagesPool.Contains(msg) == false, "Recyling already recycled incoming message! Thread race?"); byte[] storage = msg.m_data; msg.m_data = null; Recycle(storage); msg.Reset(); if (m_incomingMessagesPool.Count < m_maxCacheCount) m_incomingMessagesPool.Enqueue(msg); }
internal override void ReceiveMessage(NetIncomingMessage msg) { int nr = msg.m_sequenceNumber; // ack no matter what m_connection.QueueAck(msg.m_receivedMessageType, nr); int relate = NetUtility.RelativeSequenceNumber(nr, m_lastReceivedSequenceNumber + 1); if (relate < 0) { m_connection.m_statistics.MessageDropped(); m_peer.LogVerbose("Received message #" + nr + " DROPPING DUPLICATE"); return; // drop if late } m_lastReceivedSequenceNumber = nr; m_peer.ReleaseMessage(msg); }
public override bool Decrypt(NetIncomingMessage msg) { int unEncLenBits = (int)msg.ReadUInt32(); var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4); var cs = GetDecryptStream(ms); var result = m_peer.GetStorage(unEncLenBits); cs.Read(result, 0, NetUtility.BytesToHoldBits(unEncLenBits)); cs.Close(); // TODO: recycle existing msg msg.m_data = result; msg.m_bitLength = unEncLenBits; return true; }
internal override void ReceiveMessage(NetIncomingMessage message) { int nr = message.m_sequenceNumber; int relate = NetUtility.RelativeSequenceNumber(nr, m_windowStart); // ack no matter what m_connection.QueueAck(message.m_receivedMessageType, nr); if (relate == 0) { // Log("Received message #" + message.SequenceNumber + " right on time"); // // excellent, right on time // AdvanceWindow(); m_peer.ReleaseMessage(message); return; } if (relate < 0) { m_connection.m_statistics.MessageDropped(); m_peer.LogVerbose("Received message #" + message.m_sequenceNumber + " DROPPING LATE or DUPE"); return; } // relate > 0 = early message if (relate > m_windowSize) { // too early message! m_connection.m_statistics.MessageDropped(); m_peer.LogDebug("Received " + message + " TOO EARLY! Expected " + m_windowStart); return; } // ok m_windowStart = (m_windowStart + relate) % NetConstants.NumSequenceNumbers; m_peer.ReleaseMessage(message); return; }
/// <summary> /// Decrypt an incoming message encrypted with corresponding Encrypt /// </summary> /// <param name="msg">message to decrypt</param> /// <returns>true if successful; false if failed</returns> public override bool Decrypt(NetIncomingMessage msg) { int numEncryptedBytes = msg.LengthBytes - 4; // last 4 bytes is true bit length int blockSize = BlockSize; int numBlocks = numEncryptedBytes / blockSize; if (numBlocks * blockSize != numEncryptedBytes) return false; for (int i = 0; i < numBlocks; i++) { DecryptBlock(msg.m_data, (i * blockSize), m_tmp); Buffer.BlockCopy(m_tmp, 0, msg.m_data, (i * blockSize), m_tmp.Length); } // read 32 bits of true payload length uint realSize = NetBitWriter.ReadUInt32(msg.m_data, 32, (numEncryptedBytes * 8)); msg.m_bitLength = (int)realSize; return true; }
public override bool Decrypt(NetIncomingMessage msg) { int unEncLenBits = (int)msg.ReadUInt32(); var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4); var cs = new CryptoStream(ms, m_algorithm.CreateDecryptor(), CryptoStreamMode.Read); var byteLen = NetUtility.BytesToHoldBits(unEncLenBits); var result = m_peer.GetStorage(byteLen); cs.Read(result, 0, byteLen); cs.Close(); // TODO: recycle existing msg msg.m_data = result; msg.m_bitLength = unEncLenBits; msg.m_readPosition = 0; return true; }
/// <summary> /// Decrypt an incoming message in place /// </summary> public abstract bool Decrypt(NetIncomingMessage msg);
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 = NetUtility.GetMacAddressBytes(); var boundEp = m_socket.LocalEndPoint as NetEndPoint; 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.ComputeSHAHash(combined), 0); m_status = NetPeerStatus.Running; } }
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); } } } }
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_connection.m_statistics.MessageDropped(); m_peer.LogVerbose("Received message #" + message.m_sequenceNumber + " DROPPING DUPLICATE"); return; } // relate > 0 = early message if (relate > m_windowSize) { // too early message! m_connection.m_statistics.MessageDropped(); 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; }
internal void ReceivedMessage(NetIncomingMessage msg) { m_peer.VerifyNetworkThread(); NetMessageType tp = msg.m_receivedMessageType; int channelSlot = (int)tp - 1; NetReceiverChannelBase chan = m_receiveChannels[channelSlot]; if (chan == null) chan = CreateReceiverChannel(tp); chan.ReceiveMessage(msg); }
internal NetIncomingMessage CreateIncomingMessage(NetIncomingMessageType tp, byte[] useStorageData) { NetIncomingMessage retval; if (m_incomingMessagesPool == null || !m_incomingMessagesPool.TryDequeue(out retval)) retval = new NetIncomingMessage(tp); else retval.m_incomingMessageType = tp; retval.m_data = useStorageData; return retval; }
//Fonction pouvant être appelée de l'extérieur de façon à updater le serveur tout le temps public void UpdateServeur() { if ((MessageInc = Serveur.ReadMessage()) != null) { switch (MessageInc.MessageType) { //message reçu lors de la connection initiale case NetIncomingMessageType.ConnectionApproval: if (MessageInc.ReadByte() == (byte)PacketTypes.LOGIN) { GérerLogin(); } break; //Représente tout les messages envoyés manuellement par le client case NetIncomingMessageType.Data: //Lit le type d'information byte byteEnum = MessageInc.ReadByte(); if (byteEnum == (byte)PacketTypes.STARTGAME_INFO) { GérerStartGameInfo(); } if(byteEnum == (byte)PacketTypes.ANIMATION) { GérerAnimation(); } if(byteEnum == (byte)PacketTypes.POSITION_BALLE) { GérerInfoPositionBalle(); } if(byteEnum == (byte)PacketTypes.EST_TOUR_JOUEUR_PRINCIPAL_INFO) { GérerInfoEstTourJoueurPrincipal(); } if (byteEnum == (byte)PacketTypes.VERRE_À_ENLEVER) { GérerVerreÀEnlever(); } if(byteEnum == (byte)PacketTypes.LANCER_BALLE_INFO) { GérerInfoLancerBalle(); } break; //S'il y a un message parmi: NetConnectionStatus.Connected, NetConnectionStatus.Connecting , //NetConnectionStatus.Disconnected, NetConnectionStatus.Disconnecting, NetConnectionStatus.None case NetIncomingMessageType.StatusChanged: GérerChangementStatutJoueur(); break; //Pour tout autres types de messages default: Console.WriteLine("Message non géré(non important)"); break; } } // Si l'intervalle de temps est passé if ((Temps + IntervalleRafraichissement) < DateTime.Now) { //Regarde s'il y a au moins un client de connecté if (Serveur.ConnectionsCount != 0) { EnvoieNouveauMessageWorldState(); } //Update le temps Temps = DateTime.Now; } }
internal NetIncomingMessage CreateIncomingMessage(NetIncomingMessageType tp, int minimumByteSize) { NetIncomingMessage retval; if (m_incomingMessagesPool == null || !m_incomingMessagesPool.TryDequeue(out retval)) retval = new NetIncomingMessage(tp); else retval.m_incomingMessageType = tp; retval.m_data = GetStorage(minimumByteSize); return retval; }
internal abstract void ReceiveMessage(NetIncomingMessage msg);
private void HandleConnectResponse(double now, NetMessageType tp, int ptr, int payloadLength) { byte[] hail; 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.ReceivedInitiation: case NetConnectionStatus.None: // wtf? anyway, bye! break; case NetConnectionStatus.Connected: // my ConnectionEstablished must have been lost, send another one SendConnectionEstablished(); return; } }
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.ReceivedInitiation) { // 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); SetStatus(NetConnectionStatus.RespondedAwaitingApproval, "Awaiting approval"); m_peer.ReleaseMessage(appMsg); return; } SendConnectResponse((float)now, true); } return; } if (m_status == NetConnectionStatus.RespondedAwaitingApproval) { m_peer.LogWarning("Ignoring multiple Connect() most likely due to a delayed Approval"); 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: HandleConnectResponse(now, tp, ptr, payloadLength); 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.ReceivedInitiation: // uh, a little premature... ignore break; case NetConnectionStatus.InitiatedConnect: // weird, should have been RespondedConnect... 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; case NetMessageType.Discovery: m_peer.HandleIncomingDiscoveryRequest(now, m_remoteEndPoint, ptr, payloadLength); return; case NetMessageType.DiscoveryResponse: m_peer.HandleIncomingDiscoveryResponse(now, m_remoteEndPoint, ptr, payloadLength); return; case NetMessageType.Ping: // silently ignore return; default: m_peer.LogDebug("Unhandled type during handshake: " + tp + " length: " + payloadLength); break; } }