コード例 #1
0
        public override void SendRaw(byte eventId, PacketFlags flags, byte[] rawData, long?presetPacketId = null)
        {
            byte[] buffer   = new byte[12 + rawData.Length];
            long   packetId = presetPacketId.HasValue ? presetPacketId.Value : DateTime.UtcNow.Ticks;

            // PACKET HEADER CONSTRUCTION: 12 BYTES
            /* 0x00 1           EVENT_ID    */ buffer[0] = eventId;
            /* 0x01 1           FLAGS       */ buffer[1] = (byte)flags;
            /* 0x02 8           PACKET_ID   */ BitConverter.GetBytes(packetId).CopyTo(buffer, 2);
            /* 0x0A 2           DATA_LENGTH */ BitConverter.GetBytes((ushort)rawData.Length).CopyTo(buffer, 10);

            /* 0x0C DATA_LENGTH DATA        */ rawData.CopyTo(buffer, 12);

            try
            {
                socket.BeginSendTo(buffer, 0, buffer.Length, SocketFlags.None, endPoint, new AsyncCallback(SendToEvent), null);
                NetBase.WriteDebug($"Send data to {IPEndPoint}: {PacketToStringRep(buffer)}");

                if (flags.HasFlag(PacketFlags.Reliable) && !flags.HasFlag(PacketFlags.ReservedA))
                {
                    lock (sentReliableDataLock)
                    {
                        sentReliablePacketInfo.Add(packetId);
                    }
                    new Task(() => ResendReliable(new ReliablePacketInfo(eventId, flags, rawData, packetId))).Start();
                }
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
            }
        }
コード例 #2
0
        internal static object[] GetInstancesFromData(byte[] data, ByteConverter converter, params Type[] types)
        {
            if (types.Any(x => !converter.HasConverterOfType(x)))
            {
                NetBase.WriteDebug($"The given converter couldn't parse one of the provided types!{Environment.NewLine}{string.Join(Environment.NewLine, types.AsEnumerable())}", true);
            }

            if (types.Count() == 0)
            {
                return(new object[0]);
            }

            if (types.Count() == 1)
            {
                return new[] { converter.ObjectFromBytes(types[0], data).Instance }
            }
            ;

            // types.Count() > 1

            object[] objects   = new object[types.Count()];
            byte[]   dataClone = data.Clone() as byte[];

            for (int i = 0; i < objects.Length; ++i)
            {
                (object Instance, int BytesParsed)t = converter.ObjectFromBytes(types[i], dataClone, 2);
                objects[i] = t.Instance;
                dataClone  = dataClone.Skip(t.BytesParsed).ToArray();
            }

            return(objects);
        }
    }
コード例 #3
0
 public override void SendRaw(byte packetId, PacketFlags flags, byte[] rawData, long?presetPacketId = null)
 {
     for (int i = 0; i < clientList.Count; ++i)
     {
         try
         {
             clientList[i].SendRaw(packetId, flags, rawData, presetPacketId);
         }
         catch (Exception ex)
         {
             NetBase.WriteDebug(ex.ToString());
         }
     }
 }
コード例 #4
0
 public bool StartServer(IPAddress bindIp, int bindPort)
 {
     try
     {
         endPoint = new IPEndPoint(bindIp, bindPort);
         socket.Bind(endPoint);
         dataBuffer = new byte[bufferSize];
         socket.BeginReceiveFrom(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, ref endPoint, new AsyncCallback(DataReceivedEvent), null);
     }
     catch (Exception ex)
     {
         NetBase.WriteDebug(ex.ToString());
         return(false);
     }
     new Task(async() => await PingLoop(), cancellationToken.Token).Start();
     return(true);
 }
コード例 #5
0
        private void DataReceivedEvent(IAsyncResult ar)
        {
            try
            {
                int    i      = socket.EndReceive(ar);
                byte[] buffer = dataBuffer.Take(i).ToArray();
#if DEBUG
                // Simulated packet loss
                if (DropChance < rand.NextDouble())
                {
                    new Task(async() => await ProcessData(buffer), cancellationToken.Token).Start();
                }
                else
                {
                    Console.WriteLine("Packet Dropped...");
                }
#else
                new Task(async() => await ProcessData(buffer), cancellationToken.Token).Start();
#endif
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
                Close();
                return;
            }

            dataBuffer = new byte[bufferSize];
            try
            {
                socket.BeginReceiveFrom(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, ref endPoint, new AsyncCallback(DataReceivedEvent), null);
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
                Close();
            }
        }
コード例 #6
0
        internal byte[] GetRawData(ByteConverter converter)
        {
            if (dataCollection.Any(x => !converter.HasConverterOfType(x.GetType())))
            {
                NetBase.WriteDebug($"The given converter couldn't parse one of the types of data provided!{Environment.NewLine}{string.Join(Environment.NewLine, dataCollection.Select(x => x.GetType()))}", true);
            }

            if (dataCollection.Count == 0)
            {
                return(new byte[0]);
            }

            if (dataCollection.Count == 1)
            {
                return(converter.ConvertToBytes(dataCollection[0], false));
            }

            // dataCollection.Count > 1
            List <byte> data = new List <byte>();

            dataCollection.ForEach(o => data.AddRange(converter.ConvertToBytes(o)));
            return(data.ToArray());
        }
コード例 #7
0
        private void DataReceivedEvent(IAsyncResult ar)
        {
            EndPoint ep = new IPEndPoint(IPAddress.Any, 0);

            try
            {
                int    i      = socket.EndReceiveFrom(ar, ref ep);
                byte[] buffer = dataBuffer.Take(i).ToArray();
                new Task(async() => await ProcessData(buffer, ep), cancellationToken.Token).Start();
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());

                UdpClient eCl = clientList.Find(c => c.EndPoint.Equals(ep));
                if (eCl != null)
                {
                    eCl.Close();
                }
                return;
            }

            dataBuffer = new byte[bufferSize];
            try
            {
                socket.BeginReceiveFrom(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, ref endPoint, new AsyncCallback(DataReceivedEvent), null);
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
                UdpClient eCl = clientList.Find(c => c.EndPoint.Equals(ep));
                if (eCl != null)
                {
                    eCl.Close();
                }
            }
        }
コード例 #8
0
        public void AddNetEventsFromAssembly(Assembly asm, int eventGroupIdentifier = 0)
        {
            List <MethodInfo> netEventGroupMethods = (from t in asm.GetTypes()
                                                      from m in t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
                                                      where m.GetCustomAttribute <NetDataEventAttribute>() != null
                                                      where m.GetCustomAttribute <NetDataEventAttribute>().EventGroupIdentifier == eventGroupIdentifier
                                                      where m.GetParameters().Length > 0
                                                      where m.GetParameters()[0].ParameterType == typeof(NetBase) || m.GetParameters()[0].ParameterType.BaseType == typeof(NetBase)
                                                      select m).ToList();

            for (int i = 0; i < netEventGroupMethods.Count; ++i)
            {
                MethodInfo            nem    = netEventGroupMethods[i];
                NetDataEventAttribute attrib = nem.GetCustomAttribute <NetDataEventAttribute>();
                if (!netDataEvents.ContainsKey(attrib.EventId))
                {
                    netDataEvents.Add(attrib.EventId, nem);
                }
                else
                {
                    NetBase.WriteDebug($"Attempted to add a new net event to this object with event id {attrib.EventId}, but there is already an event with this ID! Make sure you're not adding the same event twice within the same group ID, and that no events use id 254 or 255!", true);
                }
            }
        }
コード例 #9
0
        private async Task ProcessData(byte[] data, EndPoint clientEndPoint)
        {
            try
            {
                NetBase.WriteDebug($"Server received data: {PacketToStringRep(data)}");

                UdpClient clientRef = clientList.Find(c => c.EndPoint.Equals(clientEndPoint));
                if (clientRef == null)
                {
                    if (data.Length != 4 || BitConverter.ToUInt32(data, 0) != Secret)
                    {
                        NetBase.WriteDebug($"Client attempted to connect from {clientEndPoint} with a bad secret.");

                        return;
                    }
                    UdpClient rCl = new UdpClient(socket, clientEndPoint);

                    rCl.ReliableResendDelay        = this.ReliableResendDelay;
                    rCl.MaxResendAttempts          = this.MaxResendAttempts;
                    rCl.DisconnectOnFailedResponse = this.DisconnectOnFailedResponse;

                    rCl.ClientDisconnected += c => DisconnectEventHandler(c);
                    rCl.SendRaw(254, PacketFlags.None, BitConverter.GetBytes(Secret));
                    clientList.Add(rCl);

                    if (ClientConnected != null)
                    {
                        Array.ForEach(ClientConnected.GetInvocationList(), d => d.DynamicInvoke(rCl));
                    }
                }
                else
                {
                    if (data.Length < 12)
                    {
                        return;
                    }

                    byte        eventId     = data[0];
                    PacketFlags packetFlags = (PacketFlags)data[1];
                    long        packetId    = BitConverter.ToInt64(data, 2);
                    ushort      dataLength  = BitConverter.ToUInt16(data, 10);
                    byte[]      netData     = data.Skip(12).ToArray();

                    if (dataLength != netData.Length)
                    {
                        return;
                    }

                    Dictionary <byte, MethodInfo> eventsRef = packetFlags.HasFlag(PacketFlags.SystemMessage) ? systemDataEvents : netDataEvents;

                    if (packetFlags.HasFlag(PacketFlags.Reliable))
                    {
                        clientRef.SendF(2, PacketFlags.SystemMessage, packetId);
                    }


                    if (eventsRef.ContainsKey(eventId) && !clientRef.receivedReliablePacketInfo.Contains(packetId))
                    {
                        if (packetFlags.HasFlag(PacketFlags.Reliable))
                        {
                            if (!clientRef.receivedReliablePacketInfo.Contains(packetId))
                            {
                                lock (clientRef.receivedReliableDataLock)
                                {
                                    clientRef.receivedReliablePacketInfo.Add(packetId);
                                }
                            }
                        }

                        clientRef.lastMessageReceived = DateTime.UtcNow;

                        MethodInfo      netEventMethod = eventsRef[eventId];
                        ParameterInfo[] parameters     = netEventMethod.GetParameters().Skip(1).ToArray();
                        Type[]          parameterTypes = (from p in parameters
                                                          select p.ParameterType).ToArray();

                        object[] instances            = DynamicPacket.GetInstancesFromData(netData, converterInstance, parameterTypes);
                        object[] instancesWithNetBase = new object[1 + instances.Length];
                        instancesWithNetBase[0] = clientRef;
                        instances.CopyTo(instancesWithNetBase, 1);
                        netEventMethod.Invoke(netEventMethod.IsStatic ? null : this, instancesWithNetBase);
                    }
                }
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
            }
        }
コード例 #10
0
        public bool VerifyAndListen(IPAddress remoteIp, int port)
        {
            try
            {
                endPoint = new IPEndPoint(remoteIp, port);
                byte[] verification = BitConverter.GetBytes(Secret);
                socket.SendTo(verification, 0, verification.Length, SocketFlags.None, endPoint);

                int           attempts = 0;
                List <byte[]> nonData  = new List <byte[]>(); // Used to store non-verif data that may be received first
                while (attempts <= 5)
                {
                    attempts++;
                    byte[] response      = new byte[bufferSize];
                    int    bytesReceived = socket.ReceiveFrom(response, 0, response.Length, SocketFlags.None, ref endPoint);
                    byte[] usableData    = response.Take(bytesReceived).ToArray();

                    if (usableData[0] != 254 && BitConverter.ToUInt16(usableData, 1) != 4)
                    {
                        NetBase.WriteDebug($"Non-verification data received, will store for future processing. ({attempts}/5 attempts)");
                        nonData.Add(usableData);
                        continue;
                    }

                    if (BitConverter.ToUInt32(usableData.Skip(12).ToArray(), 0) == Secret)
                    {
                        NetBase.WriteDebug($"Verification successful, will now listen for other data...");

                        dataBuffer = new byte[bufferSize];
                        try
                        {
                            socket.BeginReceiveFrom(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, ref endPoint, new AsyncCallback(DataReceivedEvent), null);
                        }
                        catch (Exception ex)
                        {
                            NetBase.WriteDebug(ex.ToString());
                            return(false);
                        }
                        new Task(async() => await TimeoutLoop(), cancellationToken.Token).Start();

                        // Process the non-verif data received beforehand
                        nonData.ForEach(d =>
                        {
                            new Task(async() => await ProcessData(d), cancellationToken.Token).Start();
                        });

                        return(true);
                    }
                    else
                    {
                        NetBase.WriteDebug($"Verification response was incorrect! Received: {string.Join(" ", response)}");
                        return(false);
                    }
                }
                NetBase.WriteDebug($"Verification attempt limit reached!");
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
            }

            return(false);
        }
コード例 #11
0
        private async Task ProcessData(byte[] data)
        {
            try
            {
                NetBase.WriteDebug($"Client received data: {PacketToStringRep(data)}");

                if (data.Length < 12)
                {
                    return;
                }

                byte        eventId     = data[0];
                PacketFlags packetFlags = (PacketFlags)data[1];
                long        packetId    = BitConverter.ToInt64(data, 2);
                ushort      dataLength  = BitConverter.ToUInt16(data, 10);
                byte[]      netData     = data.Skip(12).ToArray();

                if (dataLength != netData.Length)
                {
                    return;
                }

                Dictionary <byte, MethodInfo> eventsRef = packetFlags.HasFlag(PacketFlags.SystemMessage) ? systemDataEvents : netDataEvents;

                if (packetFlags.HasFlag(PacketFlags.Reliable))
                {
                    SendF(2, PacketFlags.SystemMessage, packetId);
                }

                if (eventsRef.ContainsKey(eventId) && !receivedReliablePacketInfo.Contains(packetId))
                {
                    if (packetFlags.HasFlag(PacketFlags.Reliable))
                    {
                        if (!receivedReliablePacketInfo.Contains(packetId))
                        {
                            lock (receivedReliableDataLock)
                            {
                                receivedReliablePacketInfo.Add(packetId);
                            }
                        }
                    }

                    lastMessageReceived = DateTime.UtcNow;

                    MethodInfo      netEventMethod = eventsRef[eventId];
                    ParameterInfo[] parameters     = netEventMethod.GetParameters().Skip(1).ToArray();
                    Type[]          parameterTypes = (from p in parameters
                                                      select p.ParameterType).ToArray();

                    object[] instances = DynamicPacket.GetInstancesFromData(netData, converterInstance, parameterTypes);

                    object[] instancesWithNetBase = new object[1 + instances.Length];
                    instancesWithNetBase[0] = this;
                    instances.CopyTo(instancesWithNetBase, 1);
                    netEventMethod.Invoke(netEventMethod.IsStatic ? null : this, instancesWithNetBase);
                }
            }
            catch (Exception ex)
            {
                NetBase.WriteDebug(ex.ToString());
            }
        }