Buttplug sex toy control library

fix: Correct the Galaku multi feature support

authored by

blackspherefollower and committed by qdot.tngl.sh 8899252a 69b8b90f

+99 -66
+91 -58
crates/buttplug_server/src/device/protocol_impl/galaku.rs
··· 114 114 if hardware.name() == "AC695X_1(BLE)" { 115 115 protocol.is_caiping_pump_device = true; 116 116 } 117 + for _ in 0..def.features().iter().filter(|f| f.output().is_some()).count() { 118 + protocol.speeds.push(AtomicU8::new(0)); 119 + } 117 120 Ok(Arc::new(protocol)) 118 121 } 119 122 } 120 123 121 124 pub struct Galaku { 122 125 is_caiping_pump_device: bool, 123 - speeds: [AtomicU8; 2], 126 + speeds: Vec<AtomicU8>, 124 127 } 125 128 126 129 impl Default for Galaku { 127 - fn default() -> Self { 128 - Self { 129 - is_caiping_pump_device: false, 130 - speeds: [AtomicU8::new(0), AtomicU8::new(0)], 130 + fn default() -> Self { 131 + Self { 132 + is_caiping_pump_device: false, 133 + speeds: vec![], 134 + } 135 + } 136 + } 137 + impl Galaku { 138 + fn handle_local_output_cmd( 139 + &self, 140 + feature_index: u32, 141 + _feature_id: Uuid, 142 + speed: u32, 143 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 144 + if self.speeds.len() == 1 { 145 + if self.is_caiping_pump_device { 146 + let data: Vec<u8> = vec![ 147 + 0xAA, 148 + 1, 149 + 10, 150 + 3, 151 + speed as u8, 152 + if speed == 0 { 0 } else { 1 }, 153 + 0, 154 + 0, 155 + 0, 156 + 0, 157 + 0, 158 + 0, 159 + 0, 160 + 0, 161 + 0, 162 + 0, 163 + ]; 164 + Ok(vec![HardwareWriteCmd::new( 165 + &[GALAKU_PROTOCOL_UUID], 166 + Endpoint::Tx, 167 + data, 168 + false, 169 + ) 170 + .into()]) 171 + } else { 172 + let data = vec![90, 0, 0, 1, 49, speed, 0, 0, 0, 0]; 173 + 174 + Ok(vec![HardwareWriteCmd::new( 175 + &[GALAKU_PROTOCOL_UUID], 176 + Endpoint::Tx, 177 + send_bytes(data), 178 + false, 179 + ) 180 + .into()]) 181 + } 182 + } else { 183 + if feature_index < self.speeds.len() as u32 { 184 + self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed); 185 + } else { 186 + error!("Tried to set value on out-of-bounds index {} (size {})", feature_index, self.speeds.len()); 187 + } 188 + 189 + let data: Vec<u32> = vec![ 190 + 90, 191 + 0, 192 + 0, 193 + 1, 194 + 64, 195 + 3, 196 + self.speeds[0].load(Ordering::Relaxed) as u32, 197 + self.speeds[1].load(Ordering::Relaxed) as u32, 198 + 0, 199 + 0, 200 + ]; 201 + Ok(vec![HardwareWriteCmd::new( 202 + &[GALAKU_PROTOCOL_UUID], 203 + Endpoint::Tx, 204 + send_bytes(data), 205 + false, 206 + ) 207 + .into()]) 208 + } 131 209 } 132 - } 133 210 } 134 211 135 212 impl ProtocolHandler for Galaku { 136 - fn handle_output_vibrate_cmd( 137 - &self, 138 - feature_index: u32, 139 - _feature_id: Uuid, 140 - speed: u32, 141 - ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 142 - if self.is_caiping_pump_device { 143 - let data: Vec<u8> = vec![ 144 - 0xAA, 145 - 1, 146 - 10, 147 - 3, 148 - speed as u8, 149 - if speed == 0 { 0 } else { 1 }, 150 - 0, 151 - 0, 152 - 0, 153 - 0, 154 - 0, 155 - 0, 156 - 0, 157 - 0, 158 - 0, 159 - 0, 160 - ]; 161 - Ok(vec![ 162 - HardwareWriteCmd::new(&[GALAKU_PROTOCOL_UUID], Endpoint::Tx, data, false).into(), 163 - ]) 164 - } else { 165 - self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed); 166 - let data: Vec<u32> = vec![ 167 - 90, 168 - 0, 169 - 0, 170 - 1, 171 - 49, 172 - self.speeds[0].load(Ordering::Relaxed) as u32, 173 - self.speeds[1].load(Ordering::Relaxed) as u32, 174 - 0, 175 - 0, 176 - 0, 177 - ]; 178 - Ok(vec![ 179 - HardwareWriteCmd::new( 180 - &[GALAKU_PROTOCOL_UUID], 181 - Endpoint::Tx, 182 - send_bytes(data), 183 - false, 184 - ) 185 - .into(), 186 - ]) 213 + fn handle_output_oscillate_cmd(&self, feature_index: u32, feature_id: Uuid, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 214 + self.handle_local_output_cmd(feature_index, feature_id, speed) 215 + } 216 + fn handle_output_vibrate_cmd(&self, feature_index: u32, feature_id: Uuid, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 217 + self.handle_local_output_cmd(feature_index, feature_id, speed) 218 + } 219 + fn handle_output_constrict_cmd(&self, feature_index: u32, feature_id: Uuid, level: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 220 + self.handle_local_output_cmd(feature_index, feature_id, level) 187 221 } 188 - } 189 222 190 223 fn handle_input_subscribe_cmd( 191 224 &self,
+3 -3
crates/buttplug_server_device_config/build-config/buttplug-device-config-v4.json
··· 1 1 { 2 2 "version": { 3 3 "major": 4, 4 - "minor": 64 4 + "minor": 69 5 5 }, 6 6 "protocols": { 7 7 "activejoy": { ··· 1876 1876 "identifier": [ 1877 1877 "G312" 1878 1878 ], 1879 - "name": "Galaku Mecha-Original Owner's Aircraft Cup" 1879 + "name": "Galaku Mecha" 1880 1880 }, 1881 1881 { 1882 1882 "features": [ ··· 2326 2326 "identifier": [ 2327 2327 "G354" 2328 2328 ], 2329 - "name": "Galaku Double-A Aircraft Cup" 2329 + "name": "Galaku Armoured-ONE" 2330 2330 }, 2331 2331 { 2332 2332 "features": [
+4 -4
crates/buttplug_server_device_config/device-config-v4/protocols/galaku.yml
··· 296 296 id: 58de185f-a52c-42e0-b06f-bb7a293a9d40 297 297 - identifier: 298 298 - G312 299 - name: Galaku Mecha-Original Owner's Aircraft Cup 299 + name: Galaku Mecha 300 300 features: 301 301 - description: oscillate 302 302 id: 9a04b080-4956-499c-894d-d7538322160e ··· 548 548 id: 5d47e890-6093-4eae-b7e8-e637dc82a2ea 549 549 - identifier: 550 550 - G354 551 - name: Galaku Double-A Aircraft Cup 551 + name: Galaku Armoured-ONE 552 552 features: 553 - - description: vibrate 553 + - description: Oscillate 554 554 id: dc4348f2-7788-4b63-96f8-80ed74e4f9c2 555 555 output: 556 - vibrate: 556 + oscillate: 557 557 value: 558 558 - 0 559 559 - 100
+1 -1
crates/buttplug_server_device_config/device-config-v4/version.yaml
··· 1 1 version: 2 2 major: 4 3 - minor: 64 3 + minor: 69