コード例 #1
0
ファイル: ENetHost.cs プロジェクト: wyb314/ENetSharp
 private void HandleReliable(ENetPeer peer, ENetProtocol packet, bool isFragment, byte[] data)
 {
     if (peer.State != ENetPeerState.Connected && peer.State != ENetPeerState.DisconnectLater) return;
     var channel = peer.Channels[packet.Header.ChannelID];
     if (DropSequencedData(channel, packet.Header) || packet.Header.ReliableSequenceNumber == channel.IncomingSequenceNumber) return;
     if (!isFragment && packet.Header.ReliableSequenceNumber == (channel.IncomingSequenceNumber + 1))
     {
         if (OnData != null) OnData(peer, data);
         channel.IncomingSequenceNumber++;
         return;
     }
     lock (channel.IncomingCommandLock)
     {
         var command = new ENetIncomingCommand(packet.Header.ReliableSequenceNumber);
         var existingCommand = channel.IncomingCommands.Find(command); //Establish if we already have the packet
         if (existingCommand != null && !isFragment) return; //We already have the command, ignore it
         else if (existingCommand != null)
         {
             if (existingCommand.Value.FragmentsRemaining == 0) return;
         }
         if (isFragment)
         {
             command.FragmentsRemaining = packet.SendFragment.FragmentCount - 1;
         }
         if(packet.Header.ReliableSequenceNumber == (channel.IncomingSequenceNumber + 1))channel.IncomingCommands.AddFirst()
     }
 }
コード例 #2
0
ファイル: Cli2Srv.cs プロジェクト: branan/PlasmaDotNet
 public void Read(hsStream s)
 {
     fType = (ENetProtocol)s.ReadByte();
     if (s.ReadUShort() != kHeaderSize)
         throw new NotSupportedException();
     fBuildID = s.ReadUInt();
     fBuildType = (EBuildType)s.ReadUInt();
     fBranchID = s.ReadUInt();
     fProductUuid = pnHelpers.ReadUuid(s);
 }
コード例 #3
0
ファイル: NsBase.cs プロジェクト: branan/PlasmaDotNet
 public void Read(hsStream s)
 {
     fType = (ENetProtocol)s.ReadByte();
     if (s.ReadUShort() != kHeaderSize)
         throw new NotSupportedException();
     fBuildID = s.ReadUInt();
     fProtocolVer = s.ReadUInt();
     if (fProtocolVer < 50)
         fProtocolVer = 50; // <= 50 are the old "Build Type" values...
     fBranchID = s.ReadUInt();
     fProductUuid = pnHelpers.ReadUuid(s);
 }
コード例 #4
0
ファイル: ENetHost.cs プロジェクト: wyb314/ENetSharp
        private unsafe void ReceiveDatagram(IAsyncResult ar)
        {
            IPEndPoint fromAddr = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = connection.EndReceive(ar, ref fromAddr);
            if (!shuttingDown) connection.BeginReceive(ReceiveDatagram, null);

            #region "ENet Structure Handling"
            var handle = GCHandle.Alloc(data, GCHandleType.Pinned);
            IntPtr dataStart = handle.AddrOfPinnedObject();
            ENetProtocolHeader header = (ENetProtocolHeader)Marshal.PtrToStructure(dataStart, typeof(ENetProtocolHeader));
            Util.ToHostOrder(ref header.PeerID);
            ushort flag = (ushort)(header.PeerID & PROTOCOL_HEADER_FLAG_MASK);
            header.PeerID &= unchecked((ushort)~(uint)PROTOCOL_HEADER_FLAG_MASK);

            ENetPeer? peer = null;
            if (header.PeerID != PROTOCOL_MAXIMUM_PEER_ID) //peer remains null if the first command is expected to be a connect
            {
                try
                {
                    peer = Peers[header.PeerID];
                    if (peer.Value.State == ENetPeerState.Disconnected || 
                        peer.Value.State == ENetPeerState.Zombie ||
                        //Don't include ENET_HOST_BROADCAST, it's meant for clients broadcasting the connect packet and communicating with any server that responds
                        !peer.Value.Address.Equals(fromAddr) /* && peer.Value.Address != ENET_HOST_BROADCAST */)
                    {
                        goto finalPacket; //The peer is disconnected, dead or the packets origin doesn't match the peer - Ignore them
                    }
                }
                catch (System.Collections.Generic.KeyNotFoundException)
                {
                    goto finalPacket; //The client doesn't exist and this doesn't follow connection protocol - Ignore them
                }
            }
            int currentDataOffset = ((flag & PROTOCOL_HEADER_FLAG_SENT_TIME) != 0) ? sizeof(ENetProtocolHeader) : sizeof(ENetProtocolHeader) - 2; //sentTime is 2 bytes
            while (currentDataOffset < data.Length)
            {
                ENetProtocol packet = (ENetProtocol)Marshal.PtrToStructure(dataStart + currentDataOffset, typeof(ENetProtocol));
                Util.ToHostOrder(ref packet.Header.ReliableSequenceNumber);
                if (packet.Header.ChannelID >= ChannelLayout.ChannelCount()) continue;
                ENetCommand command = (ENetCommand)(packet.Header.Command & (byte)ENetCommand.COMMAND_MASK);
                if(command >= ENetCommand.COUNT) continue;
                if (peer == null && command != ENetCommand.CONNECT) return; //Peer was following connection protocol but didn't send the connect first
                currentDataOffset += command.Size();
                if (currentDataOffset > data.Length) return; //The ENetCommand is larger than the remaining data
                switch (command)
                {
                    case ENetCommand.ACKNOWLEDGE:
                        Util.ToHostOrder(ref packet.Acknowledge.ReceivedReliableSequenceNumber);
                        Util.ToHostOrder(ref packet.Acknowledge.ReceivedSentTime);
                        //TODO: Handle Acknowledge
                        break;
                    case ENetCommand.BANDWIDTH_LIMIT:
                        Util.ToHostOrder(ref packet.BandwidthLimit.IncomingBandwidth);
                        Util.ToHostOrder(ref packet.BandwidthLimit.OutgoingBandwidth);
                        //TODO: Handle Bandwidth Limit
                        break;
                    case ENetCommand.CONNECT:
                        Console.WriteLine("A connected peer sent a connect packet. WTF are they doing?");
                        Util.ToHostOrder(ref packet.Connect.MTU);
                        Util.ToHostOrder(ref packet.Connect.WindowSize);
                        Util.ToHostOrder(ref packet.Connect.ChannelCount);
                        Util.ToHostOrder(ref packet.Connect.IncomingBandwidth);
                        Util.ToHostOrder(ref packet.Connect.OutgoingBandwidth);
                        Util.ToHostOrder(ref packet.Connect.PacketThrottleInterval);
                        Util.ToHostOrder(ref packet.Connect.PacketThrottleAcceleration);
                        Util.ToHostOrder(ref packet.Connect.PacketThrottleDeceleration);
                        Util.ToHostOrder(ref packet.Connect.SessionID);
                        peer = HandleConnect(fromAddr, packet.Connect);
                        break;
                    case ENetCommand.DISCONNECT:
                        Util.ToHostOrder(ref packet.Disconnect.Data);
                        //TODO: Handle Disconnect
                        break;
                    case ENetCommand.PING:
                        //Ping has no handling in the real ENet
                        break;
                    case ENetCommand.SEND_FRAGMENT:
                        Util.ToHostOrder(ref packet.SendFragment.DataLength); //We have to assume the fragment is the right type for the channel until I figure out how it indicates it
                        Util.ToHostOrder(ref packet.SendFragment.StartSequenceNumber);
                        Util.ToHostOrder(ref packet.SendFragment.FragmentCount);
                        Util.ToHostOrder(ref packet.SendFragment.FragmentNumber);
                        Util.ToHostOrder(ref packet.SendFragment.TotalLength);
                        Util.ToHostOrder(ref packet.SendFragment.FragmentOffset);
                        byte[] fragmentData = new byte[packet.SendFragment.DataLength];
                        Marshal.Copy(dataStart + currentDataOffset, fragmentData, 0, packet.SendFragment.DataLength);
                        currentDataOffset += packet.SendFragment.DataLength;
                        HandleReliable(peer.Value, packet, true, fragmentData);
                        break;
                    case ENetCommand.SEND_RELIABLE:
                        Util.ToHostOrder(ref packet.SendReliable.DataLength);
                        if ((ChannelLayout[packet.Header.ChannelID] & ENetSendType.RELIABLE) == 0) //Each of the data handlers uses this to quickly discard any data not matching the channels send type
                        {
                            currentDataOffset += packet.SendReliable.DataLength;
                            break;
                        }
                        byte[] reliableData = new byte[packet.SendReliable.DataLength];
                        Marshal.Copy(dataStart + currentDataOffset, reliableData, 0, packet.SendReliable.DataLength);
                        currentDataOffset += packet.SendReliable.DataLength;
                        HandleReliable(peer.Value, packet, false, reliableData);
                        break;
                    case ENetCommand.SEND_UNRELIABLE:
                        Util.ToHostOrder(ref packet.SendUnreliable.DataLength);
                        if ((ChannelLayout[packet.Header.ChannelID] & ENetSendType.UNRELIABLE) == 0)
                        {
                            currentDataOffset += packet.SendUnreliable.DataLength;
                            break;
                        }
                        Util.ToHostOrder(ref packet.SendUnreliable.UnreliableSequenceNumber);
                        byte[] unreliableData = new byte[packet.SendUnreliable.DataLength];
                        Marshal.Copy(dataStart + currentDataOffset, unreliableData, 0, packet.SendUnreliable.DataLength);
                        currentDataOffset += packet.SendUnreliable.DataLength;
                        HandleUnreliable(peer.Value, packet.SendUnreliable, unreliableData);
                        break;
                    case ENetCommand.SEND_UNSEQUENCED:
                        Util.ToHostOrder(ref packet.SendUnsequenced.DataLength);
                        if ((ChannelLayout[packet.Header.ChannelID] & ENetSendType.UNSEQUENCED) == 0)
                        {
                            currentDataOffset += packet.SendUnsequenced.DataLength;
                            break;
                        }
                        Util.ToHostOrder(ref packet.SendUnsequenced.UnsequencedGroup);
                        byte[] unsequencedData = new byte[packet.SendUnsequenced.DataLength];
                        Marshal.Copy(dataStart + currentDataOffset, unsequencedData, 0, packet.SendUnsequenced.DataLength);
                        currentDataOffset += packet.SendUnsequenced.DataLength;
                        HandleUnsequenced(peer.Value, packet.SendUnsequenced, unsequencedData);
                        break;
                    case ENetCommand.THROTTLE_CONFIGURE:
                        Util.ToHostOrder(ref packet.ThrottleConfigure.PacketThrottleInterval);
                        Util.ToHostOrder(ref packet.ThrottleConfigure.PacketThrottleAcceleration);
                        Util.ToHostOrder(ref packet.ThrottleConfigure.PacketThrottleDeceleration);
                        //TODO: Handle Throttle Configure
                        break;
                    case ENetCommand.VERIFY_CONNECT:
                        Util.ToHostOrder(ref packet.VerifyConnect.MTU);
                        Util.ToHostOrder(ref packet.VerifyConnect.WindowSize);
                        Util.ToHostOrder(ref packet.VerifyConnect.ChannelCount);
                        Util.ToHostOrder(ref packet.VerifyConnect.IncomingBandwidth);
                        Util.ToHostOrder(ref packet.VerifyConnect.OutgoingBandwidth);
                        Util.ToHostOrder(ref packet.VerifyConnect.PacketThrottleInterval);
                        Util.ToHostOrder(ref packet.VerifyConnect.PacketThrottleAcceleration);
                        Util.ToHostOrder(ref packet.VerifyConnect.PacketThrottleDeceleration);
                        //TODO: Handle Verify Connect
                        break;
                    default:
                        goto finalPacket;
                }
            }
            finalPacket:
            handle.Free();
            #endregion

            if (shuttingDown) shutdownComplete.Set();
        }
コード例 #5
0
        /// <summary>
        /// Queues a packet to be sent.
        /// </summary>
        /// <param name="channelId">channel on which to send</param>
        /// <param name="packet">packet to send</param>
        /// <returns>
        /// 0 on success
        /// &lt; 0 on failure
        /// </returns>
        public int Send(byte channelId, ENetPacket packet)
        {
            ENetChannel channel = Channels[channelId];

            if (State != ENetPeerState.ENET_PEER_STATE_CONNECTED || channelId >= ChannelCount ||
                packet.DataLength > Host._maximumPacketSize)
            {
                return(-1);
            }

            uint fragmentLength = Mtu - ENetProtocolHeader.Size - ENetProtocolSendFragment.Size;

            if (Host._checksum != null)
            {
                fragmentLength -= 4; //sizeof(enet_uint32);
            }

            if (packet.DataLength > fragmentLength)
            {
                uint   fragmentCount = (packet.DataLength + fragmentLength - 1) / fragmentLength;
                byte   commandNumber;
                ushort startSequenceNumber;

                if (fragmentCount > ENetHost.ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
                {
                    return(-1);
                }

                if (
                    (packet.Flags & (ENetPacketFlags.ENET_PACKET_FLAG_RELIABLE |
                                     ENetPacketFlags.ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) ==
                    ENetPacketFlags.ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT &&
                    channel.OutgoingUnreliableSequenceNumber < 0xFFFF)
                {
                    commandNumber       = (byte)ENetProtocolCommand.ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT;
                    startSequenceNumber =
                        ENetSocket.ENET_HOST_TO_NET_16((ushort)(channel.OutgoingUnreliableSequenceNumber + 1));
                }
                else
                {
                    commandNumber = (byte)ENetProtocolCommand.ENET_PROTOCOL_COMMAND_SEND_FRAGMENT |
                                    (byte)ENetProtocolFlag.ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
                    startSequenceNumber =
                        ENetSocket.ENET_HOST_TO_NET_16((ushort)(channel.OutgoingReliableSequenceNumber + 1));
                }

                List <ENetOutgoingCommand> fragments = new List <ENetOutgoingCommand>();

                ENetOutgoingCommand fragment;
                uint fragmentNumber;
                uint fragmentOffset;

                for (fragmentNumber = 0,
                     fragmentOffset = 0;
                     fragmentOffset < packet.DataLength;
                     ++fragmentNumber,
                     fragmentOffset += fragmentLength)
                {
                    if (packet.DataLength - fragmentOffset < fragmentLength)
                    {
                        fragmentLength = packet.DataLength - fragmentOffset;
                    }

                    fragment = new ENetOutgoingCommand();
                    fragment.FragmentOffset           = fragmentOffset;
                    fragment.FragmentLength           = (ushort)fragmentLength;
                    fragment.Packet                   = packet;
                    fragment.Command.Header.Command   = commandNumber;
                    fragment.Command.Header.ChannelId = channelId;
                    fragment.Command.SendFragment.StartSequenceNumber = startSequenceNumber;
                    fragment.Command.SendFragment.DataLength          = ENetSocket.ENET_HOST_TO_NET_16((ushort)fragmentLength);
                    fragment.Command.SendFragment.FragmentCount       = ENetSocket.ENET_HOST_TO_NET_32(fragmentCount);
                    fragment.Command.SendFragment.FragmentNumber      = ENetSocket.ENET_HOST_TO_NET_32(fragmentNumber);
                    fragment.Command.SendFragment.TotalLength         = ENetSocket.ENET_HOST_TO_NET_32(packet.DataLength);
                    fragment.Command.SendFragment.FragmentOffset      = ENetSocket.ENET_NET_TO_HOST_32(fragmentOffset);

                    fragments.Add(fragment);
                }

                packet.ReferenceCount += fragmentNumber;

                foreach (ENetOutgoingCommand currentFragment in fragments)
                {
                    Host.enet_peer_setup_outgoing_command(this, currentFragment);
                }

                return(0);
            }

            ENetProtocol command = new ENetProtocol();

            command.Header.ChannelId = channelId;

            if ((packet.Flags & (ENetPacketFlags.ENET_PACKET_FLAG_RELIABLE | ENetPacketFlags.ENET_PACKET_FLAG_UNSEQUENCED)) ==
                ENetPacketFlags.ENET_PACKET_FLAG_UNSEQUENCED)
            {
                // packetFlags.HasFlag(ENET_PACKET_FLAG_UNSEQUENCED) && !packetFlags.HasFlag(ENET_PACKET_FLAG_RELIABLE)
                command.Header.Command =
                    (byte)ENetProtocolCommand.ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | (byte)ENetProtocolFlag.ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
                command.SendUnsequenced.DataLength = ENetSocket.ENET_HOST_TO_NET_16((ushort)packet.DataLength);
            }
            else if ((packet.Flags & ENetPacketFlags.ENET_PACKET_FLAG_RELIABLE) != 0 || channel.OutgoingUnreliableSequenceNumber >= 0xFFFF)
            {
                // if(0) == if(false) / if(1) == if(true)
                // packetFlags.HasFlag(ENET_PACKET_FLAG_RELIABLE)
                command.Header.Command          = (byte)ENetProtocolCommand.ENET_PROTOCOL_COMMAND_SEND_RELIABLE | (byte)ENetProtocolFlag.ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
                command.SendReliable.DataLength = ENetSocket.ENET_HOST_TO_NET_16((ushort)packet.DataLength);
            }
            else
            {
                command.Header.Command            = (byte)ENetProtocolCommand.ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
                command.SendUnreliable.DataLength = ENetSocket.ENET_HOST_TO_NET_16((ushort)packet.DataLength);
            }

            if (Host.enet_peer_queue_outgoing_command(this, command, packet, 0, (ushort)packet.DataLength) == null)
            {
                return(-1);
            }

            return(0);
        }