/// <summary> /// Message Received event handler. Either tries to match incoming messages as replies to /// messages we've sent, or fires an event related to an incoming event, like device /// additions/removals, log messages, etc. /// </summary> /// <param name="aSender">Object sending the open event, unused.</param> /// <param name="aArgs">Event parameters, including the data received.</param> private async void MessageReceivedHandler(object aSender, MessageReceivedEventArgs aArgs) { var msg = aArgs.Message; switch (msg) { case Log l: Log?.Invoke(this, new LogEventArgs(l)); break; case DeviceAdded d: var dev = new ButtplugClientDevice(_bpLogManager, this, SendDeviceMessageAsync, d); _devices.Add(d.DeviceIndex, dev); DeviceAdded?.Invoke(this, new DeviceAddedEventArgs(dev)); break; case DeviceRemoved d: if (!_devices.ContainsKey(d.DeviceIndex)) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs( new ButtplugDeviceException(_bpLogger, "Got device removed message for unknown device.", msg.Id))); return; } var oldDev = _devices[d.DeviceIndex]; _devices.Remove(d.DeviceIndex); DeviceRemoved?.Invoke(this, new DeviceRemovedEventArgs(oldDev)); break; case ScanningFinished _: // The scanning finished event is self explanatory and doesn't require extra arguments. ScanningFinished?.Invoke(this, new EventArgs()); break; case Error e: // This will both log the error and fire it from our ErrorReceived event handler. ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(ButtplugException.FromError(_bpLogger, e))); if (e.ErrorCode == Error.ErrorClass.ERROR_PING) { PingTimeout?.Invoke(this, EventArgs.Empty); await DisconnectAsync().ConfigureAwait(false); } break; default: ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs( new ButtplugMessageException(_bpLogger, $"Got unhandled message: {msg}", msg.Id))); break; } }
private DeadPeerDetectorEntry CreateEntry(PeerDescriptor descriptor) { var entry = new DeadPeerDetectorEntry(descriptor, _configuration, _bus, TaskScheduler); entry.PeerTimeoutDetected += OnPeerTimeout; entry.PeerRespondingDetected += OnPeerResponding; entry.PingTimeout += (detectorEntry, time) => PingTimeout?.Invoke(detectorEntry.Descriptor.PeerId, time); return(entry); }
public void OnTimeout(PingTimeout timeout) { ConsoleDisplay.Timeout(timeout.SequenceNumber); if (Attributes.BeepMode == 1) { try { Console.Beep(); } catch (Exception) { } } }
public static void SaveSetting() { reader.SetNodeText("PingTimeout", PingTimeout.ToString()); reader.SetNodeText("RequestTimeout", RequestTimeout.ToString()); reader.SetNodeText("TcpPort", TcpPort.ToString()); reader.SetNodeText("UdpPort", UdpPort.ToString()); reader.SetNodeText("ClientPort", ClientPort.ToString()); reader.SetNodeText("Adapter", Adapter); reader.SetNodeText("PlayerID", PlayerID); reader.SetNodeText("DataMode", dataMode); reader.SetNodeText("SyncMode", syncMode); reader.Save("setting.xml"); }
private async void PingTimeoutHandler([NotNull] object aObj) { // Stop the timer by specifying an infinite due period (See: https://msdn.microsoft.com/en-us/library/yz1c7148(v=vs.110).aspx) _pingTimer?.Change(Timeout.Infinite, (int)_maxPingTime); // Since this happens in an event handler, output a message, not an exception // TODO Once server has ErrorReceived event handlers, change this to throwing an exception through that. MessageReceived?.Invoke(this, new MessageReceivedEventArgs(new Error("Ping timed out.", Error.ErrorClass.ERROR_PING, ButtplugConsts.SystemMsgId))); await SendMessageAsync(new StopAllDevices()).ConfigureAwait(false); _pingTimedOut = true; PingTimeout?.Invoke(this, new EventArgs()); _clientName = null; }
protected bool Equals(RequestData other) => RequestTimeout.Equals(other.RequestTimeout) && PingTimeout.Equals(other.PingTimeout) && KeepAliveTime == other.KeepAliveTime && KeepAliveInterval == other.KeepAliveInterval && Pipelined == other.Pipelined && HttpCompression == other.HttpCompression && Equals(Headers, other.Headers) && string.Equals(ProxyAddress, other.ProxyAddress) && string.Equals(ProxyUsername, other.ProxyUsername) && string.Equals(ProxyPassword, other.ProxyPassword) && DisableAutomaticProxyDetection == other.DisableAutomaticProxyDetection && Equals(BasicAuthorizationCredentials, other.BasicAuthorizationCredentials) && Equals(ConnectionSettings, other.ConnectionSettings) && Equals(MemoryStreamFactory, other.MemoryStreamFactory);
public void Ping(DateTime timestampUtc) { lock (_lock) { if (_oldestUnansweredPingTimeUtc == null) { _oldestUnansweredPingTimeUtc = timestampUtc; } var elapsedTimeSinceFirstPing = SystemDateTime.UtcNow - _oldestUnansweredPingTimeUtc; if (elapsedTimeSinceFirstPing > _configuration.PeerPingInterval) { PingTimeout?.Invoke(this, timestampUtc); } } SendPingCommand(timestampUtc); }
public override int GetHashCode() { unchecked { var hashCode = RequestTimeout.GetHashCode(); hashCode = (hashCode * 397) ^ PingTimeout.GetHashCode(); hashCode = (hashCode * 397) ^ KeepAliveTime; hashCode = (hashCode * 397) ^ KeepAliveInterval; hashCode = (hashCode * 397) ^ Pipelined.GetHashCode(); hashCode = (hashCode * 397) ^ HttpCompression.GetHashCode(); hashCode = (hashCode * 397) ^ (Headers?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (ProxyAddress?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (ProxyUsername?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (ProxyPassword?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ DisableAutomaticProxyDetection.GetHashCode(); hashCode = (hashCode * 397) ^ (BasicAuthorizationCredentials?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (ConnectionSettings?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (MemoryStreamFactory?.GetHashCode() ?? 0); return(hashCode); } }
public void SorterCallback(UIntPtr buf, int buf_length) { Span <byte> byteArray; unsafe { byteArray = new Span <byte>(buf.ToPointer(), buf_length); } var server_message = ButtplugFFIServerMessage.Parser.ParseFrom(byteArray.ToArray()); if (server_message.Id > 0) { _messageSorter.CheckMessage(server_message); } else if (server_message.Message.MsgCase == ButtplugFFIServerMessage.Types.FFIMessage.MsgOneofCase.ServerMessage) { if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceAdded) { var device_added_message = server_message.Message.ServerMessage.DeviceAdded; var device_handle = ButtplugFFI.SendCreateDevice(_clientHandle, device_added_message.Index); var attribute_dict = new Dictionary <ServerMessage.Types.MessageAttributeType, ButtplugMessageAttributes>(); for (var i = 0; i < device_added_message.MessageAttributes.Count; ++i) { var attributes = device_added_message.MessageAttributes[i]; var device_message_attributes = new ButtplugMessageAttributes(attributes.FeatureCount, attributes.StepCount.ToArray(), attributes.Endpoints.ToArray(), attributes.MaxDuration.ToArray(), null, null); attribute_dict.Add(attributes.MessageType, device_message_attributes); } var device = new ButtplugClientDevice(_messageSorter, device_handle, device_added_message.Index, device_added_message.Name, attribute_dict); _devices.Add(device_added_message.Index, device); DeviceAdded.Invoke(this, new DeviceAddedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceRemoved) { var device_removed_message = server_message.Message.ServerMessage.DeviceRemoved; var device = _devices[device_removed_message.Index]; _devices.Remove(device_removed_message.Index); DeviceRemoved.Invoke(this, new DeviceRemovedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Disconnect) { Connected = false; ServerDisconnect?.Invoke(this, null); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Error) { var errorMsg = server_message.Message.ServerMessage.Error; var error = ButtplugException.FromError(errorMsg); if (error is ButtplugPingException) { PingTimeout?.Invoke(this, null); } ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(error)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.ScanningFinished) { ScanningFinished?.Invoke(this, null); } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } }
protected void SorterCallbackHandler(IntPtr buf, int buf_length) { // Process the data BEFORE we throw to the C# executor, otherwise // Rust will clean up the memory and we'll have nothing to read // from, meaning a null message at best and a crash at worst. Span <byte> byteArray; unsafe { byteArray = new Span <byte>(buf.ToPointer(), buf_length); } var server_message = ButtplugFFIServerMessage.Parser.ParseFrom(byteArray.ToArray()); // Run the response in the context of the C# executor, not the Rust // thread. This means that if something goes wrong we at least // aren't blocking a rust executor thread. Task.Run(() => { if (server_message.Id > 0) { _messageSorter.CheckMessage(server_message); } else if (server_message.Message.MsgCase == ButtplugFFIServerMessage.Types.FFIMessage.MsgOneofCase.ServerMessage) { if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceAdded) { var device_added_message = server_message.Message.ServerMessage.DeviceAdded; if (_devices.ContainsKey(device_added_message.Index)) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(new ButtplugDeviceException("A duplicate device index was received. This is most likely a bug, please file at https://github.com/buttplugio/b******g-rs-ffi"))); return; } var device_handle = ButtplugFFI.SendCreateDevice(_clientHandle, device_added_message.Index); var attribute_dict = new Dictionary <ServerMessage.Types.MessageAttributeType, ButtplugMessageAttributes>(); for (var i = 0; i < device_added_message.MessageAttributes.Count; ++i) { var attributes = device_added_message.MessageAttributes[i]; var device_message_attributes = new ButtplugMessageAttributes(attributes.FeatureCount, attributes.StepCount.ToArray(), attributes.Endpoints.ToArray(), attributes.MaxDuration.ToArray(), null, null); attribute_dict.Add(attributes.MessageType, device_message_attributes); } var device = new ButtplugClientDevice(_messageSorter, device_handle, device_added_message.Index, device_added_message.Name, attribute_dict, SorterCallbackDelegate, GCHandle.ToIntPtr(_indexHandle)); _devices.Add(device_added_message.Index, device); DeviceAdded?.Invoke(this, new DeviceAddedEventArgs(device)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.DeviceRemoved) { var device_removed_message = server_message.Message.ServerMessage.DeviceRemoved; if (!_devices.ContainsKey(device_removed_message.Index)) { // Device was removed from our dict before we could remove it ourselves. return; } try { var device = _devices[device_removed_message.Index]; _devices.Remove(device_removed_message.Index); DeviceRemoved?.Invoke(this, new DeviceRemovedEventArgs(device)); } catch (KeyNotFoundException) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(new ButtplugDeviceException($"Cannot remove device index {device_removed_message.Index}, device not found."))); } } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Disconnect) { Connected = false; _devices.Clear(); ServerDisconnect?.Invoke(this, null); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.Error) { var errorMsg = server_message.Message.ServerMessage.Error; var error = ButtplugException.FromError(errorMsg); if (error is ButtplugPingException) { PingTimeout?.Invoke(this, null); } ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(error)); } else if (server_message.Message.ServerMessage.MsgCase == ServerMessage.MsgOneofCase.ScanningFinished) { IsScanning = false; ScanningFinished?.Invoke(this, null); } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } } else { // We should probably do something here with unhandled events, but I'm not particularly sure what. I miss pattern matching. :( } }); }