private async Task <bool> EnsureConnectedAsync(bool reconnect) { if (_socket == null || !_socket.Connected) { if (!reconnect || _lastConnectionAttempt?.ElapsedMilliseconds < 3000) { return(false); } Logging.Debug("Close socket before reconnecting…"); CloseSocket(); try { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _killer = KillerOrder.Create(_socket, TimeSpan.FromSeconds(1)); await _socket.ConnectTaskAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), OptionSocketPort)).ConfigureAwait(false); Logging.Debug("Connected to CM in-game app"); _killer?.Pause(); } catch (Exception e) { Logging.Warning(e); CloseSocket(); } } return(_socket != null); }
private async Task <AppResponse> SendRequestAsync(string firstString, string secondString, byte firstValue, byte secondValue) { if (!await EnsureConnectedAsync(true)) { return(AppResponse.None); } var offset = 0; if (!SetString(firstString, 64, ref _lastFirst) & !SetString(secondString, 32, ref _lastSecond) & !SetByte(firstValue) & !SetByte(secondValue) & string.IsNullOrEmpty(firstString)) { return(AppResponse.None); } try { _killer?.Delay(); var sent = await _socket.SendTaskAsync(_sendBuffer, 0, offset).ConfigureAwait(false); if (sent != offset) { Warn($"Failed to sent all data, only {sent} out of {offset}"); return(AppResponse.None); } _killer?.Delay(); var received = await _socket.ReceiveTaskAsync(_receiveBuffer).ConfigureAwait(false); if (received != 1) { Warn($"Failed to receive data, only {received} out of {_receiveBuffer.Length}"); return(AppResponse.None); } _killer?.Pause(); return((AppResponse)_receiveBuffer[0]); } catch (ObjectDisposedException e) { Logging.Warning(e.Message); CloseSocket(); return(AppResponse.None); } catch (Exception e) { Logging.Error(e); CloseSocket(); return(AppResponse.None); } bool ToBytes(string s, int maxLength, ref Tuple <int, string, byte[]> last, out byte[] result) { if (s == null) { s = ""; } if (last?.Item2 != s || last.Item1 != offset) { var v = s.Length > maxLength?s.Substring(0, maxLength) : s; result = Encoding.UTF8.GetBytes(v); if (result.Length > maxLength * 2) { Array.Resize(ref result, maxLength * 2); } last = Tuple.Create(offset, s, result); return(true); } result = last.Item3; return(false); } bool SetString(string s, int maxLength, ref Tuple <int, string, byte[]> last) { var result = ToBytes(s, maxLength, ref last, out var data); if (result) { _sendBuffer[offset] = (byte)data.Length; Array.Copy(data, 0, _sendBuffer, offset + 1, data.Length); } offset += data.Length + 1; return(result); } bool SetByte(byte b) { var o = offset++; if (_sendBuffer[o] == b) { return(false); } _sendBuffer[o] = b; return(true); } void Warn(string warning) { if (!_warn) { _warn = true; Logging.Warning(warning); } } }