From 40371a1c376177f45ca6d4d0ffa25a9bad9a973e Mon Sep 17 00:00:00 2001 From: wwwfeng <952529160@qq.com> Date: Sun, 16 Aug 2026 23:56:20 -0700 Subject: [PATCH] feat:kaipro support --- .../src/device/protocol_impl/honeyplaybox.rs | 40 ++++++++++++- .../buttplug-device-config-v5.json | 56 ++++++++++++++++++- .../device-config/protocols/honeyplaybox.yml | 34 ++++++++++- .../device-config/version.yaml | 2 +- 4 files changed, 127 insertions(+), 5 deletions(-) diff --git a/crates/buttplug_server/src/device/protocol_impl/honeyplaybox.rs b/crates/buttplug_server/src/device/protocol_impl/honeyplaybox.rs index e2254f65f..540c17961 100644 --- a/crates/buttplug_server/src/device/protocol_impl/honeyplaybox.rs +++ b/crates/buttplug_server/src/device/protocol_impl/honeyplaybox.rs @@ -45,6 +45,9 @@ const HONEY_PLAYBOX_KEEPALIVE_DELAY: u64 = 500; const HONEY_PLAYBOX_COMMAND_RETRY: u64 = 3; const HONEY_PLAYBOX_PROTOCOL_UUID: Uuid = uuid!("0d1598bd-6845-4950-8aa0-416b1115fc7c"); +type ConstrictCommandHandler = + fn(&HoneyPlayBox, u32, u32) -> Result, ButtplugDeviceError>; + // The secret key used for MD5 signing. const SECRET: [u8; 16] = [ 0x8b, 0xe3, 0xfd, 0x04, 0x68, 0x35, 0x09, 0x86, 0x12, 0x1a, 0xbf, 0x03, 0x30, 0xe9, 0xe3, 0xc5, @@ -62,6 +65,10 @@ impl ProtocolInitializer for HoneyPlayBoxInitializer { hardware: Arc, device_definition: &ServerDeviceDefinition, ) -> Result, ButtplugDeviceError> { + let constrict_handler: Option = match hardware.name().as_str() { + "HPB-274" => Some(HoneyPlayBox::handle_kaipro_constrict_cmd), + _ => None, + }; let feature_count = device_definition .features() .values() @@ -104,7 +111,7 @@ impl ProtocolInitializer for HoneyPlayBoxInitializer { trace!("HoneyPlayBox handshake success on attempt {}", count+1); if let Some(rand) = FrameCodec::extract_random(&frame) { info!("HoneyPlayBox handshake random token {:?}", rand.clone()); - return Ok(Arc::new(HoneyPlayBox::new(hardware, rand, feature_count, counter))); + return Ok(Arc::new(HoneyPlayBox::new(hardware, rand, feature_count, counter, constrict_handler))); } warn!("HoneyPlayBox: No random token in frame (handshake attempt {})", count+1); } @@ -150,6 +157,7 @@ pub struct HoneyPlayBox { last_command: Arc>, packet_id: Arc, last_send: Arc>, + constrict_handler: Option, } async fn hpb_keepalive( @@ -209,7 +217,13 @@ async fn hpb_keepalive( } impl HoneyPlayBox { - fn new(hardware: Arc, random_key: [u8; 16], feature_count: usize, count: u8) -> Self { + fn new( + hardware: Arc, + random_key: [u8; 16], + feature_count: usize, + count: u8, + constrict_handler: Option, + ) -> Self { let last_command = Arc::new( (0..feature_count) .map(|_| AtomicU8::new(0)) @@ -233,9 +247,18 @@ impl HoneyPlayBox { last_command, packet_id, last_send, + constrict_handler, } } + fn handle_kaipro_constrict_cmd( + &self, + feature_index: u32, + level: u32, + ) -> Result, ButtplugDeviceError> { + self.send_command(feature_index, if level == 0 { 0 } else { level + 100 }) + } + fn send_command( &self, feature_index: u32, @@ -305,6 +328,19 @@ impl ProtocolHandler for HoneyPlayBox { self.send_command(feature_index, speed.unsigned_abs()) } + fn handle_output_constrict_cmd( + &self, + feature_index: u32, + _feature_id: Uuid, + level: u32, + ) -> Result, ButtplugDeviceError> { + if let Some(handler) = self.constrict_handler { + handler(self, feature_index, level) + } else { + self.command_unimplemented("OutputCmd (Constrict Actuator)") + } + } + fn handle_battery_level_cmd( &self, device_index: u32, diff --git a/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json b/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json index a1aeeeaa0..47ed8b504 100644 --- a/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json +++ b/crates/buttplug_server_device_config/build-config/buttplug-device-config-v5.json @@ -1,7 +1,7 @@ { "version": { "major": 5, - "minor": 30 + "minor": 31 }, "protocols": { "activejoy": { @@ -4878,6 +4878,7 @@ "btle": { "names": [ "JXT002", + "HPB-274", "HPB-393-1", "HPB-0520", "HONEY-835", @@ -4932,6 +4933,59 @@ ], "name": "Honey Play Box Pleasure Pivot" }, + { + "features": [ + { + "description": "Vibrator", + "id": "06456fc9-9ab6-425b-9cf1-9f875d21bcf3", + "index": 0, + "output": { + "vibrate": { + "value": [ + 0, + 100 + ] + } + } + }, + { + "description": "Suction Pump", + "id": "09817707-f6b8-44de-8708-58101999396a", + "index": 1, + "output": { + "constrict": { + "value": [ + 0, + 4 + ] + } + } + }, + { + "description": "Battery Level", + "id": "97528990-df35-4fa1-8f3c-f6f78b1b8538", + "index": 2, + "input": { + "battery": { + "command": [ + "Read" + ], + "value": [ + [ + 0, + 100 + ] + ] + } + } + } + ], + "id": "b33a5de9-d0c6-448b-8150-e402dd29ed4d", + "identifier": [ + "HPB-274" + ], + "name": "Honey Play Box Kaipro" + }, { "id": "0a9c43fb-2d58-4af9-aef2-60f48c6e7707", "identifier": [ diff --git a/crates/buttplug_server_device_config/device-config/protocols/honeyplaybox.yml b/crates/buttplug_server_device_config/device-config/protocols/honeyplaybox.yml index 3781103c3..d59932616 100644 --- a/crates/buttplug_server_device_config/device-config/protocols/honeyplaybox.yml +++ b/crates/buttplug_server_device_config/device-config/protocols/honeyplaybox.yml @@ -32,6 +32,37 @@ configurations: - HPB-398 name: Honey Play Box Pleasure Pivot id: c205e707-9561-4016-97aa-0bde609b0edc + - identifier: + - HPB-274 + name: Honey Play Box Kaipro + features: + - description: Vibrator + id: 06456fc9-9ab6-425b-9cf1-9f875d21bcf3 + output: + vibrate: + value: + - 0 + - 100 + index: 0 + - description: Suction Pump + id: 09817707-f6b8-44de-8708-58101999396a + output: + constrict: + value: + - 0 + - 4 + index: 1 + - description: Battery Level + id: 97528990-df35-4fa1-8f3c-f6f78b1b8538 + input: + battery: + value: + - - 0 + - 100 + command: + - Read + index: 2 + id: b33a5de9-d0c6-448b-8150-e402dd29ed4d - identifier: - HPB-296 name: Honey Play Box Anello @@ -485,6 +516,7 @@ communication: - btle: names: - JXT002 + - HPB-274 - HPB-393-1 - HPB-0520 - HONEY-835 @@ -509,4 +541,4 @@ communication: tx: 0000ff03-0000-1000-8000-00805f9b34fb rx: 0000ff02-0000-1000-8000-00805f9b34fb 0000180f-0000-1000-8000-00805f9b34fb: - rxblebattery: 00002a19-0000-1000-8000-00805f9b34fb \ No newline at end of file + rxblebattery: 00002a19-0000-1000-8000-00805f9b34fb diff --git a/crates/buttplug_server_device_config/device-config/version.yaml b/crates/buttplug_server_device_config/device-config/version.yaml index 03b91ac4b..9ef9fc504 100644 --- a/crates/buttplug_server_device_config/device-config/version.yaml +++ b/crates/buttplug_server_device_config/device-config/version.yaml @@ -1,3 +1,3 @@ version: major: 5 - minor: 30 + minor: 31