Buttplug sex toy control library
20
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: Add support for Galaku Nebula

authored by

blackspherefollower and committed by
qDot
8bc883f3 33f9919d

+185
+41
buttplug/buttplug-device-config/buttplug-device-config.json
··· 6381 6381 "name": "The Unicorn" 6382 6382 } 6383 6383 ] 6384 + }, 6385 + "galaku-pump": { 6386 + "btle": { 6387 + "names": [ 6388 + "V415" 6389 + ], 6390 + "services": { 6391 + "00001000-0000-1000-8000-00805f9b34fb": { 6392 + "tx": "00001001-0000-1000-8000-00805f9b34fb" 6393 + } 6394 + } 6395 + }, 6396 + "defaults": { 6397 + "name": "Galaku Device", 6398 + "messages": { 6399 + "ScalarCmd": [ 6400 + { 6401 + "StepRange": [ 6402 + 0, 6403 + 100 6404 + ], 6405 + "ActuatorType": "Oscillate" 6406 + }, 6407 + { 6408 + "StepRange": [ 6409 + 0, 6410 + 100 6411 + ], 6412 + "ActuatorType": "Vibrate" 6413 + } 6414 + ] 6415 + } 6416 + }, 6417 + "configurations": [ 6418 + { 6419 + "identifier": [ 6420 + "V415" 6421 + ], 6422 + "name": "Galaku Nebula" 6423 + } 6424 + ] 6384 6425 } 6385 6426 } 6386 6427 }
+19
buttplug/buttplug-device-config/buttplug-device-config.yml
··· 3151 3151 - identifier: 3152 3152 - THE UNICORN 3153 3153 name: The Unicorn 3154 + galaku-pump: 3155 + btle: 3156 + names: 3157 + - V415 3158 + services: 3159 + 00001000-0000-1000-8000-00805f9b34fb: 3160 + tx: 00001001-0000-1000-8000-00805f9b34fb 3161 + defaults: 3162 + name: Galaku Device 3163 + messages: 3164 + ScalarCmd: 3165 + - StepRange: [0, 100] 3166 + ActuatorType: Oscillate 3167 + - StepRange: [0, 100] 3168 + ActuatorType: Vibrate 3169 + configurations: 3170 + - identifier: 3171 + - V415 3172 + name: Galaku Nebula 3154 3173 # nintendo-joycon: 3155 3174 # hid: 3156 3175 # vendor-id: 0x057e
+71
buttplug/src/server/device/protocol/galaku_pump.rs
··· 1 + // Buttplug Rust Source Code File - See https://buttplug.io for more info. 2 + // 3 + // Copyright 2016-2023 Nonpolynomial Labs LLC. All rights reserved. 4 + // 5 + // Licensed under the BSD 3-Clause license. See LICENSE file in the project root 6 + // for full license information. 7 + 8 + use crate::core::errors::ButtplugDeviceError::ProtocolSpecificError; 9 + use crate::core::message::ActuatorType; 10 + use crate::core::message::ActuatorType::{Oscillate, Vibrate}; 11 + use crate::{ 12 + core::{errors::ButtplugDeviceError, message::Endpoint}, 13 + server::device::{ 14 + hardware::{HardwareCommand, HardwareWriteCmd}, 15 + protocol::{generic_protocol_setup, ProtocolHandler}, 16 + }, 17 + }; 18 + use std::num::Wrapping; 19 + 20 + static KEY_TAB: [[u8; 12]; 4] = [ 21 + [0, 24, 0x98, 0xf7, 0xa5, 61, 13, 41, 37, 80, 68, 70], 22 + [0, 69, 110, 106, 111, 120, 32, 83, 45, 49, 46, 55], 23 + [0, 101, 120, 32, 84, 111, 121, 115, 10, 0x8e, 0x9d, 0xa3], 24 + [0, 0xc5, 0xd6, 0xe7, 0xf8, 10, 50, 32, 111, 98, 13, 10], 25 + ]; 26 + 27 + generic_protocol_setup!(GalakuPump, "galaku-pump"); 28 + 29 + #[derive(Default)] 30 + pub struct GalakuPump {} 31 + 32 + impl ProtocolHandler for GalakuPump { 33 + fn needs_full_command_set(&self) -> bool { 34 + true 35 + } 36 + 37 + fn handle_scalar_cmd( 38 + &self, 39 + commands: &[Option<(ActuatorType, u32)>], 40 + ) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> { 41 + if commands.len() != 2 { 42 + return Err(ProtocolSpecificError( 43 + "galaku-pump".to_owned(), 44 + format!("Expected 2 attributes, got {}", commands.len()), 45 + )); 46 + } 47 + 48 + let mut data: Vec<u8> = vec![ 49 + 0x23, 50 + 0x5a, 51 + 0x00, 52 + 0x00, 53 + 0x01, 54 + 0x60, 55 + 0x03, 56 + commands[0].unwrap_or((Oscillate, 0)).1 as u8, 57 + commands[1].unwrap_or((Vibrate, 0)).1 as u8, 58 + 0x00, 59 + 0x00, 60 + ]; 61 + data.push(data.iter().fold(0u8, |c, b| (Wrapping(c) + Wrapping(*b)).0)); 62 + 63 + let mut data2: Vec<u8> = vec![0x23]; 64 + for i in 1..data.len() { 65 + let k = KEY_TAB[(data2[i - 1] & 3) as usize][i]; 66 + data2.push((Wrapping((k ^ 0x23) ^ data[i]) + Wrapping(k)).0); 67 + } 68 + 69 + Ok(vec![HardwareWriteCmd::new(Endpoint::Tx, data2, true).into()]) 70 + } 71 + }
+6
buttplug/src/server/device/protocol/mod.rs
··· 19 19 pub mod cachito; 20 20 pub mod cowgirl; 21 21 pub mod fredorch; 22 + pub mod galaku_pump; 22 23 pub mod hgod; 23 24 pub mod hismith; 24 25 pub mod htk_bm; ··· 158 159 ); 159 160 160 161 add_to_protocol_map(&mut map, hgod::setup::HgodIdentifierFactory::default()); 162 + 163 + add_to_protocol_map( 164 + &mut map, 165 + galaku_pump::setup::GalakuPumpIdentifierFactory::default(), 166 + ); 161 167 162 168 add_to_protocol_map(&mut map, jejoue::setup::JeJoueIdentifierFactory::default()); 163 169 add_to_protocol_map(
+2
buttplug/tests/test_device_protocols.rs
··· 69 69 #[test_case("test_tryfun_protocol.yaml" ; "TryFun Protocol")] 70 70 #[test_case("test_metaxsire_rex.yaml" ; "metaXsire Protocol - Rex")] 71 71 #[test_case("test_cowgirl_protocol.yaml" ; "The Cowgirl Protocol")] 72 + #[test_case("test_galaku_nebula.yaml" ; "Galaku Pump Protocol - Nebula")] 72 73 fn test_device_protocols_embedded_v3(test_file: &str) { 73 74 //tracing_subscriber::fmt::init(); 74 75 async_manager::block_on(async { ··· 129 130 #[test_case("test_tryfun_protocol.yaml" ; "TryFun Protocol")] 130 131 #[test_case("test_metaxsire_rex.yaml" ; "metaXsire Protocol - Rex")] 131 132 #[test_case("test_cowgirl_protocol.yaml" ; "The Cowgirl Protocol")] 133 + #[test_case("test_galaku_nebula.yaml" ; "Galaku Pump Protocol - Nebula")] 132 134 fn test_device_protocols_json_v3(test_file: &str) { 133 135 //tracing_subscriber::fmt::init(); 134 136 async_manager::block_on(async {
+46
buttplug/tests/util/device_test/device_test_case/test_galaku_nebula.yaml
··· 1 + devices: 2 + - identifier: 3 + name: "V415" 4 + expected_name: "Galaku Nebula" 5 + device_commands: 6 + - !Messages 7 + device_index: 0 8 + messages: 9 + - !Vibrate 10 + - Index: 0 11 + Speed: 0.5 12 + - !Commands 13 + device_index: 0 14 + commands: 15 + - !Write 16 + endpoint: tx 17 + data: [0x23, 0x81, 0xBB, 0xAB, 0xD2, 0x9B, 0x44, 0x33, 0xED, 0x43, 0x3B, 0x44] 18 + write_with_response: true 19 + - !Messages 20 + device_index: 0 21 + messages: 22 + - !Scalar 23 + - Index: 0 24 + Scalar: 0.75 25 + ActuatorType: Oscillate 26 + - Index: 1 27 + Scalar: 0.5 28 + ActuatorType: Vibrate 29 + - !Commands 30 + device_index: 0 31 + commands: 32 + - !Write 33 + endpoint: tx 34 + data: [0x23, 0x81, 0xBB, 0xAB, 0xD2, 0x9B, 0x44, 0x6A, 0x25, 0x43, 0x3B, 0x81] 35 + write_with_response: true 36 + - !Messages 37 + device_index: 0 38 + messages: 39 + - !Stop 40 + - !Commands 41 + device_index: 0 42 + commands: 43 + - !Write 44 + endpoint: tx 45 + data: [0x23, 0x81, 0xBB, 0xAB, 0xD2, 0x9B, 0x44, 0x33, 0xBB, 0xA3, 0x3B, 0xD2] 46 + write_with_response: true