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()); } }
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); } }
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()); } } }
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); }
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(); } }
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()); }
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(); } } }
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); } } }
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()); } }
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); }
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()); } }