private async void Receive() { var state = new StateObject { WorkSocket = _socket }; _disconnectionType = null; _socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state); while (_socket.Connected && _keepRunning) { int timeoutClient = (int)(DateTime.Now - _packetSent).TotalSeconds; int timeoutServer = (int)(DateTime.Now - _packetReceived).TotalSeconds; if (timeoutClient >= 5) { if (timeoutServer >= 20) { Disconnect(BattlEyeDisconnectionType.ConnectionLost); _keepRunning = true; } else { if (_packetQueue.Count == 0) { SendCommandPacket(null, false); } } } if (_socket.Connected && _packetQueue.Count > 0 && _socket.Available == 0) { try { int key = _packetQueue.First().Key; if (_currentPacket == -1 || !_packetQueue.ContainsKey(_currentPacket)) { _currentPacket = key; string value = _packetQueue[key][0]; SendPacket(ConstructPacket(BattlEyePacketType.Command, key, value)); } } catch { // Prevent possible crash when packet is received at the same moment it's trying to resend it. } } await Task.Delay(250); } if (!_socket.Connected) { if (ReconnectOnPacketLoss && _keepRunning) { Connect(); } else if (!_keepRunning) { //let the thread finish without further action } else { OnDisconnect(_loginCredentials, BattlEyeDisconnectionType.ConnectionLost); } } }
private void ReceiveCallback(IAsyncResult ar) { try { StateObject state = (StateObject)ar.AsyncState; Socket client = state.WorkSocket; // this method can be called from the middle of a .Disconnect() call // test with Debug > Exception > CLR exs on if (!client.Connected) { return; } int bytesRead = client.EndReceive(ar); if (state.Buffer[7] == 0x02) { SendAcknowledgePacket(Helpers.Bytes2String(new[] { state.Buffer[8] })); OnBattlEyeMessage(Helpers.Bytes2String(state.Buffer, 9, bytesRead - 9), 256); } else if (state.Buffer[7] == 0x01) { if (bytesRead > 9) { if (state.Buffer[7] == 0x01 && state.Buffer[9] == 0x00) { if (state.Buffer[11] == 0) { state.PacketsTodo = state.Buffer[10]; } if (state.PacketsTodo > 0) { state.Message.Append(Helpers.Bytes2String(state.Buffer, 12, bytesRead - 12)); state.PacketsTodo--; } if (state.PacketsTodo == 0) { OnBattlEyeMessage(state.Message.ToString(), state.Buffer[8]); state.Message = new StringBuilder(); state.PacketsTodo = 0; } } else { // Temporary fix to avoid infinite loops with multi-packet server messages state.Message = new StringBuilder(); state.PacketsTodo = 0; OnBattlEyeMessage(Helpers.Bytes2String(state.Buffer, 9, bytesRead - 9), state.Buffer[8]); } } if (_packetQueue.ContainsKey(state.Buffer[8]) && state.PacketsTodo == 0) { _packetQueue.Remove(state.Buffer[8]); } } _packetReceived = DateTime.Now; client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state); } catch { // do nothing } }
private void Receive() { StateObject state = new StateObject(); state.WorkSocket = socket; disconnectionType = null; socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); new Thread(delegate() { while (socket.Connected && keepRunning) { int timeoutClient = (int)(DateTime.Now - packetSent).TotalSeconds; int timeoutServer = (int)(DateTime.Now - packetReceived).TotalSeconds; if (timeoutClient >= 5) { if (timeoutServer >= 20) { Disconnect(BattlEyeDisconnectionType.ConnectionLost); keepRunning = true; } else { if (packetQueue.Count == 0) { SendCommandPacket(null, false); } } } if (socket.Connected && packetQueue.Count > 0 && socket.Available == 0) { try { int key = packetQueue.First().Key; string value = packetQueue[key][0]; DateTime date = DateTime.Parse(packetQueue[key][1]); int timeDiff = (int)(DateTime.Now - date).TotalSeconds; if (timeDiff > 4) { SendCommandPacket(value, false); packetQueue.Remove(key); } } catch { // Prevent possible crash when packet is received at the same moment it's trying to resend it. } } Thread.Sleep(1000); } if (!socket.Connected) { if (ReconnectOnPacketLoss && keepRunning) { Connect(); } else if (!keepRunning) { //let the thread finish without further action } else { OnDisconnect(loginCredentials, BattlEyeDisconnectionType.ConnectionLost); } } }).Start(); }