Buttplug sex toy control library
at dev 6.3 kB view raw
1use std::sync::Arc; 2 3use crate::{ 4 BackdoorServer, ButtplugRemoteServer, ButtplugServerConnectorError, EngineOptions, 5 IntifaceEngineError, IntifaceError, remote_server::ButtplugRemoteServerEvent, 6}; 7use buttplug_server::{ 8 ButtplugServer, ButtplugServerBuilder, 9 connector::ButtplugRemoteServerConnector, 10 device::{ServerDeviceManager, ServerDeviceManagerBuilder}, 11 message::serializer::ButtplugServerJSONSerializer, 12}; 13use buttplug_server_device_config::{DeviceConfigurationManager, load_protocol_configs}; 14use buttplug_server_hwmgr_btleplug::BtlePlugCommunicationManagerBuilder; 15use buttplug_server_hwmgr_lovense_connect::LovenseConnectServiceCommunicationManagerBuilder; 16use buttplug_server_hwmgr_websocket::WebsocketServerDeviceCommunicationManagerBuilder; 17use buttplug_transport_websocket_tungstenite::{ 18 ButtplugWebsocketClientTransport, ButtplugWebsocketServerTransportBuilder, 19}; 20use once_cell::sync::OnceCell; 21use tokio::sync::broadcast::Sender; 22// Device communication manager setup gets its own module because the includes and platform 23// specifics are such a mess. 24 25pub fn setup_server_device_comm_managers( 26 args: &EngineOptions, 27 server_builder: &mut ServerDeviceManagerBuilder, 28) { 29 if args.use_bluetooth_le() { 30 info!("Including Bluetooth LE (btleplug) Device Comm Manager Support"); 31 let mut command_manager_builder = BtlePlugCommunicationManagerBuilder::default(); 32 #[cfg(target_os = "ios")] 33 command_manager_builder.requires_keepalive(true); 34 #[cfg(not(target_os = "ios"))] 35 command_manager_builder.requires_keepalive(false); 36 server_builder.comm_manager(command_manager_builder); 37 } 38 if args.use_lovense_connect() { 39 info!("Including Lovense Connect App Support"); 40 server_builder.comm_manager(LovenseConnectServiceCommunicationManagerBuilder::default()); 41 } 42 #[cfg(not(any(target_os = "android", target_os = "ios")))] 43 { 44 use buttplug_server_hwmgr_hid::HidCommunicationManagerBuilder; 45 use buttplug_server_hwmgr_lovense_dongle::LovenseHIDDongleCommunicationManagerBuilder; 46 use buttplug_server_hwmgr_serial::SerialPortCommunicationManagerBuilder; 47 if args.use_lovense_dongle_hid() { 48 info!("Including Lovense HID Dongle Support"); 49 server_builder.comm_manager(LovenseHIDDongleCommunicationManagerBuilder::default()); 50 } 51 if args.use_serial_port() { 52 info!("Including Serial Port Support"); 53 server_builder.comm_manager(SerialPortCommunicationManagerBuilder::default()); 54 } 55 if args.use_hid() { 56 info!("Including Hid Support"); 57 server_builder.comm_manager(HidCommunicationManagerBuilder::default()); 58 } 59 #[cfg(target_os = "windows")] 60 { 61 use buttplug_server_hwmgr_xinput::XInputDeviceCommunicationManagerBuilder; 62 if args.use_xinput() { 63 info!("Including XInput Gamepad Support"); 64 server_builder.comm_manager(XInputDeviceCommunicationManagerBuilder::default()); 65 } 66 } 67 } 68 if args.use_device_websocket_server() { 69 info!("Including Websocket Server Device Support"); 70 let mut builder = 71 WebsocketServerDeviceCommunicationManagerBuilder::default().listen_on_all_interfaces(true); 72 if let Some(port) = args.device_websocket_server_port() { 73 builder = builder.server_port(port); 74 } 75 server_builder.comm_manager(builder); 76 } 77} 78 79pub async fn reset_buttplug_server( 80 options: &EngineOptions, 81 device_manager: &Arc<ServerDeviceManager>, 82 sender: &Sender<ButtplugRemoteServerEvent>, 83) -> Result<ButtplugRemoteServer, IntifaceEngineError> { 84 match ButtplugServerBuilder::with_shared_device_manager(device_manager.clone()) 85 .name(options.server_name()) 86 .max_ping_time(options.max_ping_time()) 87 .finish() 88 { 89 Ok(server) => Ok(ButtplugRemoteServer::new(server, &Some(sender.clone()))), 90 Err(e) => { 91 error!("Error starting server: {:?}", e); 92 Err(IntifaceEngineError::ButtplugServerError(e)) 93 } 94 } 95} 96 97pub async fn setup_buttplug_server( 98 options: &EngineOptions, 99 backdoor_server: &OnceCell<Arc<BackdoorServer>>, 100 dcm: &Option<Arc<DeviceConfigurationManager>>, 101) -> Result<ButtplugServer, IntifaceEngineError> { 102 let mut dm_builder = if let Some(dcm) = dcm { 103 ServerDeviceManagerBuilder::new_with_arc(dcm.clone()) 104 } else { 105 let mut dcm_builder = load_protocol_configs( 106 options.device_config_json(), 107 options.user_device_config_json(), 108 false, 109 ) 110 .map_err(|e| IntifaceEngineError::ButtplugError(e.into()))?; 111 112 ServerDeviceManagerBuilder::new( 113 dcm_builder 114 .finish() 115 .map_err(|e| IntifaceEngineError::ButtplugError(e.into()))?, 116 ) 117 }; 118 119 setup_server_device_comm_managers(options, &mut dm_builder); 120 let mut server_builder = ButtplugServerBuilder::new( 121 dm_builder 122 .finish() 123 .map_err(IntifaceEngineError::ButtplugServerError)?, 124 ); 125 126 server_builder 127 .name(options.server_name()) 128 .max_ping_time(options.max_ping_time()); 129 130 let core_server = match server_builder.finish() { 131 Ok(server) => server, 132 Err(e) => { 133 error!("Error starting server: {:?}", e); 134 return Err(IntifaceEngineError::ButtplugServerError(e)); 135 } 136 }; 137 if backdoor_server 138 .set(Arc::new(BackdoorServer::new(core_server.device_manager()))) 139 .is_err() 140 { 141 Err( 142 IntifaceError::new("BackdoorServer already initialized somehow! This should never happen!") 143 .into(), 144 ) 145 } else { 146 Ok(core_server) 147 } 148} 149 150pub async fn run_server( 151 server: &ButtplugRemoteServer, 152 options: &EngineOptions, 153) -> Result<(), ButtplugServerConnectorError> { 154 if let Some(port) = options.websocket_port() { 155 server 156 .start(ButtplugRemoteServerConnector::< 157 _, 158 ButtplugServerJSONSerializer, 159 >::new( 160 ButtplugWebsocketServerTransportBuilder::default() 161 .port(port) 162 .listen_on_all_interfaces(options.websocket_use_all_interfaces()) 163 .finish(), 164 )) 165 .await 166 } else if let Some(addr) = options.websocket_client_address() { 167 server 168 .start(ButtplugRemoteServerConnector::< 169 _, 170 ButtplugServerJSONSerializer, 171 >::new( 172 ButtplugWebsocketClientTransport::new_insecure_connector(addr), 173 )) 174 .await 175 } else { 176 panic!( 177 "Websocket port not set, cannot create transport. Please specify a websocket port in arguments." 178 ); 179 } 180}