/// <summary> /// Reads data from incoming stream (if bytes exist in buffer). Tries to construct /// one or more game packets. Fires event for each valid game packet. /// </summary> private void ReadData() { try { //vars List <byte[]> packets = new List <byte[]>(); //lock queue lock (_incomingQueue) { //return if zero bytes if (_incomingQueue.Count == 0) { return; } //queue overflow? if (_incomingQueue.Count > 100000) { Log.Write($"ReadData: Incoming byte queue overflow"); _incomingQueue.Clear(); } //loop while (true) { //break if zero bytes if (_incomingQueue.Count == 0) { break; } //find first four matching footer bytes (terminator) int firstIndex = FindToken(_incomingQueue, PacketBase.PACKET_FOOTER); //break if no footer if (firstIndex == -1) { Log.Write($"ReadData: Incomplete data ({_incomingQueue.Count} bytes) left in buffer"); break; } //dequeue bytes int count = firstIndex + 4; byte[] bytes = _incomingQueue.Dequeue(count).ToArray(); //add to list packets.Add(bytes); } } //return if no new packets if (packets.Count <= 0) { return; } //loop through packet (candidates) foreach (byte[] bytes in packets) { //reject if invalid PacketBase packet = PacketBase.FromBytes(bytes); if (packet == null) { Log.Write($"ReadData: Invalid packet from '{_remoteIP}' with {bytes.Length} bytes was discarded"); continue; } //fire event PacketReceived?.InvokeFromTask(this, packet); //WARNING, CHANGED THIS!! } } catch (Exception ex) { _stop = true; Log.Write("ReadData: Error reading or processing data"); ErrorHandler.LogError(ex); } }