+1
-1
crates/buttplug/src/lib.rs
+1
-1
crates/buttplug/src/lib.rs
+22
-7
crates/buttplug_client/src/device/command.rs
+22
-7
crates/buttplug_client/src/device/command.rs
···
49
49
}
50
50
51
51
impl ClientDeviceOutputCommand {
52
-
pub fn from_command_value_float(output_type: OutputType, value: f64) -> Result<Self, ButtplugClientError> {
52
+
pub fn from_command_value_float(
53
+
output_type: OutputType,
54
+
value: f64,
55
+
) -> Result<Self, ButtplugClientError> {
53
56
match output_type {
54
57
OutputType::Vibrate => Ok(ClientDeviceOutputCommand::VibrateFloat(value)),
55
58
OutputType::Oscillate => Ok(ClientDeviceOutputCommand::OscillateFloat(value)),
···
59
62
OutputType::Led => Ok(ClientDeviceOutputCommand::LedFloat(value)),
60
63
OutputType::Spray => Ok(ClientDeviceOutputCommand::SprayFloat(value)),
61
64
OutputType::Position => Ok(ClientDeviceOutputCommand::PositionFloat(value)),
62
-
_ => Err(ButtplugClientError::ButtplugOutputCommandConversionError("Cannot use PositionWithDuration with this method".to_owned()))
65
+
_ => Err(ButtplugClientError::ButtplugOutputCommandConversionError(
66
+
"Cannot use PositionWithDuration with this method".to_owned(),
67
+
)),
63
68
}
64
69
}
65
70
}
···
67
72
impl Into<OutputType> for &ClientDeviceOutputCommand {
68
73
fn into(self) -> OutputType {
69
74
match self {
70
-
ClientDeviceOutputCommand::Vibrate(_) | ClientDeviceOutputCommand::VibrateFloat(_) => OutputType::Vibrate,
71
-
ClientDeviceOutputCommand::Oscillate(_) | ClientDeviceOutputCommand::OscillateFloat(_) => OutputType::Oscillate,
72
-
ClientDeviceOutputCommand::Rotate(_) | ClientDeviceOutputCommand::RotateFloat(_) => OutputType::Rotate,
73
-
ClientDeviceOutputCommand::Constrict(_) | ClientDeviceOutputCommand::ConstrictFloat(_) => OutputType::Constrict,
74
-
ClientDeviceOutputCommand::Heater(_) | ClientDeviceOutputCommand::HeaterFloat(_) => OutputType::Heater,
75
+
ClientDeviceOutputCommand::Vibrate(_) | ClientDeviceOutputCommand::VibrateFloat(_) => {
76
+
OutputType::Vibrate
77
+
}
78
+
ClientDeviceOutputCommand::Oscillate(_) | ClientDeviceOutputCommand::OscillateFloat(_) => {
79
+
OutputType::Oscillate
80
+
}
81
+
ClientDeviceOutputCommand::Rotate(_) | ClientDeviceOutputCommand::RotateFloat(_) => {
82
+
OutputType::Rotate
83
+
}
84
+
ClientDeviceOutputCommand::Constrict(_) | ClientDeviceOutputCommand::ConstrictFloat(_) => {
85
+
OutputType::Constrict
86
+
}
87
+
ClientDeviceOutputCommand::Heater(_) | ClientDeviceOutputCommand::HeaterFloat(_) => {
88
+
OutputType::Heater
89
+
}
75
90
ClientDeviceOutputCommand::Led(_) | ClientDeviceOutputCommand::LedFloat(_) => OutputType::Led,
76
91
ClientDeviceOutputCommand::Spray(_) | ClientDeviceOutputCommand::SprayFloat(_) => {
77
92
OutputType::Spray
+62
-57
crates/buttplug_client/src/device/feature.rs
+62
-57
crates/buttplug_client/src/device/feature.rs
···
89
89
))
90
90
} else {
91
91
let mut val = float_amt * feature_output.step_count() as f64;
92
-
val = if val > 0.000001f64 { val.ceil() } else { val.floor() };
92
+
val = if val > 0.000001f64 {
93
+
val.ceil()
94
+
} else {
95
+
val.floor()
96
+
};
93
97
Ok(val as i32)
94
98
}
95
99
}
···
267
271
pub fn subscribe_sensor(&self, sensor_type: InputType) -> ButtplugClientResultFuture {
268
272
if let Some(sensor_map) = self.feature.input()
269
273
&& let Some(sensor) = sensor_map.get(sensor_type)
270
-
&& sensor
271
-
.input_commands()
272
-
.contains(&InputCommandType::Subscribe)
273
-
{
274
-
let msg = InputCmdV4::new(
275
-
self.device_index,
276
-
self.feature_index,
277
-
sensor_type,
278
-
InputCommandType::Subscribe,
279
-
)
280
-
.into();
281
-
return self.event_loop_sender.send_message_expect_ok(msg);
282
-
}
274
+
&& sensor
275
+
.input_commands()
276
+
.contains(&InputCommandType::Subscribe)
277
+
{
278
+
let msg = InputCmdV4::new(
279
+
self.device_index,
280
+
self.feature_index,
281
+
sensor_type,
282
+
InputCommandType::Subscribe,
283
+
)
284
+
.into();
285
+
return self.event_loop_sender.send_message_expect_ok(msg);
286
+
}
283
287
create_boxed_future_client_error(
284
288
ButtplugDeviceError::MessageNotSupported(ButtplugDeviceMessageNameV4::InputCmd.to_string())
285
289
.into(),
···
289
293
pub fn unsubscribe_sensor(&self, sensor_type: InputType) -> ButtplugClientResultFuture {
290
294
if let Some(sensor_map) = self.feature.input()
291
295
&& let Some(sensor) = sensor_map.get(sensor_type)
292
-
&& sensor
293
-
.input_commands()
294
-
.contains(&InputCommandType::Subscribe)
295
-
{
296
-
let msg = InputCmdV4::new(
297
-
self.device_index,
298
-
self.feature_index,
299
-
sensor_type,
300
-
InputCommandType::Unsubscribe,
301
-
)
302
-
.into();
303
-
return self.event_loop_sender.send_message_expect_ok(msg);
304
-
}
296
+
&& sensor
297
+
.input_commands()
298
+
.contains(&InputCommandType::Subscribe)
299
+
{
300
+
let msg = InputCmdV4::new(
301
+
self.device_index,
302
+
self.feature_index,
303
+
sensor_type,
304
+
InputCommandType::Unsubscribe,
305
+
)
306
+
.into();
307
+
return self.event_loop_sender.send_message_expect_ok(msg);
308
+
}
305
309
create_boxed_future_client_error(
306
310
ButtplugDeviceError::MessageNotSupported(ButtplugDeviceMessageNameV4::InputCmd.to_string())
307
311
.into(),
···
311
315
fn read_sensor(&self, sensor_type: InputType) -> ButtplugClientResultFuture<InputTypeData> {
312
316
if let Some(sensor_map) = self.feature.input()
313
317
&& let Some(sensor) = sensor_map.get(sensor_type)
314
-
&& sensor.input_commands().contains(&InputCommandType::Read) {
315
-
let msg = InputCmdV4::new(
316
-
self.device_index,
317
-
self.feature_index,
318
-
sensor_type,
319
-
InputCommandType::Read,
320
-
)
321
-
.into();
322
-
let reply = self.event_loop_sender.send_message(msg);
323
-
return async move {
324
-
if let ButtplugServerMessageV4::InputReading(data) = reply.await? {
325
-
if sensor_type == data.data().as_input_type() {
326
-
Ok(data.data())
327
-
} else {
328
-
Err(
329
-
ButtplugError::ButtplugMessageError(ButtplugMessageError::UnexpectedMessageType(
330
-
"InputReading".to_owned(),
331
-
))
332
-
.into(),
333
-
)
334
-
}
335
-
} else {
336
-
Err(
337
-
ButtplugError::ButtplugMessageError(ButtplugMessageError::UnexpectedMessageType(
338
-
"InputReading".to_owned(),
339
-
))
340
-
.into(),
341
-
)
342
-
}
318
+
&& sensor.input_commands().contains(&InputCommandType::Read)
319
+
{
320
+
let msg = InputCmdV4::new(
321
+
self.device_index,
322
+
self.feature_index,
323
+
sensor_type,
324
+
InputCommandType::Read,
325
+
)
326
+
.into();
327
+
let reply = self.event_loop_sender.send_message(msg);
328
+
return async move {
329
+
if let ButtplugServerMessageV4::InputReading(data) = reply.await? {
330
+
if sensor_type == data.data().as_input_type() {
331
+
Ok(data.data())
332
+
} else {
333
+
Err(
334
+
ButtplugError::ButtplugMessageError(ButtplugMessageError::UnexpectedMessageType(
335
+
"InputReading".to_owned(),
336
+
))
337
+
.into(),
338
+
)
343
339
}
344
-
.boxed();
340
+
} else {
341
+
Err(
342
+
ButtplugError::ButtplugMessageError(ButtplugMessageError::UnexpectedMessageType(
343
+
"InputReading".to_owned(),
344
+
))
345
+
.into(),
346
+
)
345
347
}
348
+
}
349
+
.boxed();
350
+
}
346
351
create_boxed_future_client_error(
347
352
ButtplugDeviceError::MessageNotSupported(ButtplugDeviceMessageNameV4::InputCmd.to_string())
348
353
.into(),
+3
-1
crates/buttplug_core/src/message/device_feature.rs
+3
-1
crates/buttplug_core/src/message/device_feature.rs
···
11
11
use serde::{Deserialize, Serialize, Serializer, ser::SerializeSeq};
12
12
use std::{collections::HashSet, hash::Hash, ops::RangeInclusive};
13
13
14
-
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, EnumIter, EnumString)]
14
+
#[derive(
15
+
Debug, Display, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, EnumIter, EnumString,
16
+
)]
15
17
pub enum OutputType {
16
18
Unknown,
17
19
#[serde(alias = "vibrate")]
+10
-9
crates/buttplug_core/src/message/serializer/json_serializer.rs
+10
-9
crates/buttplug_core/src/message/serializer/json_serializer.rs
···
53
53
match msg {
54
54
Ok(json_msg) => {
55
55
if let Some(validator) = validator
56
-
&& !validator.is_valid(&json_msg) {
57
-
// If is_valid fails, re-run validation to get our error message.
58
-
let e = validator
59
-
.validate(&json_msg)
60
-
.expect_err("We can't get here without validity checks failing.");
61
-
return Err(ButtplugSerializerError::JsonSerializerError(format!(
62
-
"Error during JSON Schema Validation - Message: {json_msg} - Error: {e:?}"
63
-
)));
64
-
}
56
+
&& !validator.is_valid(&json_msg)
57
+
{
58
+
// If is_valid fails, re-run validation to get our error message.
59
+
let e = validator
60
+
.validate(&json_msg)
61
+
.expect_err("We can't get here without validity checks failing.");
62
+
return Err(ButtplugSerializerError::JsonSerializerError(format!(
63
+
"Error during JSON Schema Validation - Message: {json_msg} - Error: {e:?}"
64
+
)));
65
+
}
65
66
match serde_json::from_value::<Vec<T>>(json_msg) {
66
67
Ok(mut msg_vec) => {
67
68
for msg in msg_vec.iter_mut() {
+1
-6
crates/buttplug_core/src/message/v4/mod.rs
+1
-6
crates/buttplug_core/src/message/v4/mod.rs
···
19
19
device_message_info::DeviceMessageInfoV4,
20
20
input_cmd::{InputCmdV4, InputCommandType},
21
21
input_reading::{InputData, InputReadingV4, InputTypeData},
22
-
output_cmd::{
23
-
OutputCmdV4,
24
-
OutputCommand,
25
-
OutputPositionWithDuration,
26
-
OutputValue,
27
-
},
22
+
output_cmd::{OutputCmdV4, OutputCommand, OutputPositionWithDuration, OutputValue},
28
23
request_server_info::RequestServerInfoV4,
29
24
server_info::ServerInfoV4,
30
25
spec_enums::{ButtplugClientMessageV4, ButtplugDeviceMessageNameV4, ButtplugServerMessageV4},
+3
-1
crates/buttplug_core/src/message/v4/spec_enums.rs
+3
-1
crates/buttplug_core/src/message/v4/spec_enums.rs
+8
-5
crates/buttplug_core/src/util/range_serialize.rs
+8
-5
crates/buttplug_core/src/util/range_serialize.rs
···
1
1
use std::ops::RangeInclusive;
2
2
3
-
use serde::{Serializer, Serialize, ser::SerializeSeq};
3
+
use serde::{Serialize, Serializer, ser::SerializeSeq};
4
4
5
-
pub fn option_range_serialize<S, T>(range: &Option<RangeInclusive<T>>, serializer: S) -> Result<S::Ok, S::Error>
5
+
pub fn option_range_serialize<S, T>(
6
+
range: &Option<RangeInclusive<T>>,
7
+
serializer: S,
8
+
) -> Result<S::Ok, S::Error>
6
9
where
7
10
S: Serializer,
8
-
T: Serialize
11
+
T: Serialize,
9
12
{
10
13
if let Some(r) = range {
11
14
range_serialize(r, serializer)
···
17
20
pub fn range_serialize<S, T>(range: &RangeInclusive<T>, serializer: S) -> Result<S::Ok, S::Error>
18
21
where
19
22
S: Serializer,
20
-
T: Serialize
23
+
T: Serialize,
21
24
{
22
25
let mut seq = serializer.serialize_seq(Some(2))?;
23
26
seq.serialize_element(&range.start())?;
···
25
28
seq.end()
26
29
}
27
30
28
-
pub fn range_sequence_serialize<S,T>(
31
+
pub fn range_sequence_serialize<S, T>(
29
32
range_vec: &Vec<RangeInclusive<T>>,
30
33
serializer: S,
31
34
) -> Result<S::Ok, S::Error>
+49
-21
crates/buttplug_server/src/device/protocol.rs
+49
-21
crates/buttplug_server/src/device/protocol.rs
···
226
226
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
227
227
let output_command = cmd.output_command();
228
228
match output_command {
229
-
OutputCommand::Constrict(x) => {
230
-
self.handle_output_constrict_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
231
-
}
232
-
OutputCommand::Spray(x) => {
233
-
self.handle_output_spray_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
234
-
}
235
-
OutputCommand::Oscillate(x) => {
236
-
self.handle_output_oscillate_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
237
-
}
229
+
OutputCommand::Constrict(x) => self.handle_output_constrict_cmd(
230
+
cmd.feature_index(),
231
+
cmd.feature_id(),
232
+
x.value()
233
+
.try_into()
234
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
235
+
),
236
+
OutputCommand::Spray(x) => self.handle_output_spray_cmd(
237
+
cmd.feature_index(),
238
+
cmd.feature_id(),
239
+
x.value()
240
+
.try_into()
241
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
242
+
),
243
+
OutputCommand::Oscillate(x) => self.handle_output_oscillate_cmd(
244
+
cmd.feature_index(),
245
+
cmd.feature_id(),
246
+
x.value()
247
+
.try_into()
248
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
249
+
),
238
250
OutputCommand::Rotate(x) => {
239
251
self.handle_output_rotate_cmd(cmd.feature_index(), cmd.feature_id(), x.value())
240
252
}
241
-
OutputCommand::Vibrate(x) => {
242
-
self.handle_output_vibrate_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
243
-
}
244
-
OutputCommand::Position(x) => {
245
-
self.handle_output_position_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
246
-
}
247
-
OutputCommand::Heater(x) => {
248
-
self.handle_output_heater_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
249
-
}
250
-
OutputCommand::Led(x) => {
251
-
self.handle_output_led_cmd(cmd.feature_index(), cmd.feature_id(), x.value().try_into().map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?)
252
-
}
253
+
OutputCommand::Vibrate(x) => self.handle_output_vibrate_cmd(
254
+
cmd.feature_index(),
255
+
cmd.feature_id(),
256
+
x.value()
257
+
.try_into()
258
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
259
+
),
260
+
OutputCommand::Position(x) => self.handle_output_position_cmd(
261
+
cmd.feature_index(),
262
+
cmd.feature_id(),
263
+
x.value()
264
+
.try_into()
265
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
266
+
),
267
+
OutputCommand::Heater(x) => self.handle_output_heater_cmd(
268
+
cmd.feature_index(),
269
+
cmd.feature_id(),
270
+
x.value()
271
+
.try_into()
272
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
273
+
),
274
+
OutputCommand::Led(x) => self.handle_output_led_cmd(
275
+
cmd.feature_index(),
276
+
cmd.feature_id(),
277
+
x.value()
278
+
.try_into()
279
+
.map_err(|_| ButtplugDeviceError::DeviceCommandSignError)?,
280
+
),
253
281
OutputCommand::PositionWithDuration(x) => self.handle_position_with_duration_cmd(
254
282
cmd.feature_index(),
255
283
cmd.feature_id(),
+111
-39
crates/buttplug_server/src/device/protocol_impl/fredorch.rs
+111
-39
crates/buttplug_server/src/device/protocol_impl/fredorch.rs
···
185
185
}
186
186
187
187
const SPEED_MATRIX: [[u32; 20]; 15] = [
188
-
// distance, speed 1-20
189
-
/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
190
-
/* 1*/ [1000, 800, 400, 235, 200, 172, 155, 92, 60, 45, 38, 34, 32, 28, 27, 26, 25, 24, 23, 22 ],
191
-
/* 2*/ [1500, 1000, 800, 680, 600, 515, 425, 265, 165, 115, 80, 70, 50, 48, 45, 35, 34, 33, 32, 30 ],
192
-
/* 3*/ [2500, 2310, 1135, 925, 792, 695, 565, 380, 218, 155, 105, 82, 70, 68, 65, 60, 48, 45, 43, 40 ],
193
-
/* 4*/ [3000, 2800, 1500, 1155, 965, 810, 690, 465, 260, 195, 140, 110, 85, 75, 74, 73, 70, 65, 60, 55 ],
194
-
/* 5*/ [3400, 3232, 2305, 1380, 1200, 1165, 972, 565, 328, 235, 162, 132, 98, 78, 75, 74, 73, 72, 71, 70 ],
195
-
/* 6*/ [3500, 3350, 2500, 1640, 1250, 1210, 1010, 645, 385, 275, 175, 160, 115, 95, 91, 90, 85, 80, 77, 75 ],
196
-
/* 7*/ [3600, 3472, 2980, 2060, 1560, 1275, 1132, 738, 430, 310, 230, 170, 128, 122, 110, 108, 105, 103, 101, 100],
197
-
/* 8*/ [3800, 3500, 3055, 2105, 1740, 1370, 1290, 830, 490, 355, 235, 195, 150, 140, 135, 132, 130, 125, 120, 119],
198
-
/* 9*/ [3900, 3518, 3190, 2315, 2045, 1510, 1442, 1045, 552, 392, 280, 225, 172, 145, 140, 138, 135, 134, 132, 130],
199
-
/*10*/ [6000, 5755, 3240, 2530, 2135, 1605, 1500, 1200, 595, 425, 285, 245, 175, 170, 160, 155, 150, 145, 142, 140],
200
-
/*11*/ [6428, 5872, 3335, 2780, 2270, 1782, 1590, 1310, 648, 470, 315, 255, 182, 180, 175, 172, 170, 162, 160, 155],
201
-
/*12*/ [6730, 5950, 3490, 2995, 2395, 1890, 1650, 1350, 700, 500, 350, 290, 220, 190, 185, 180, 175, 170, 165, 160],
202
-
/*13*/ [6962, 6122, 3880, 3205, 2465, 1900, 1700, 1400, 835, 545, 375, 310, 228, 195, 190, 185, 182, 181, 180, 175],
203
-
/*14*/ [7945, 6365, 4130, 3470, 2505, 1910, 1755, 1510, 855, 580, 400, 330, 235, 210, 205, 200, 195, 190, 185, 180],
204
-
/*15*/ [8048, 7068, 4442, 3708, 2668, 1930, 1800, 1520, 878, 618, 428, 365, 260, 255, 250, 240, 230, 220, 210, 200],
188
+
// distance, speed 1-20
189
+
/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
190
+
/* 1*/
191
+
[
192
+
1000, 800, 400, 235, 200, 172, 155, 92, 60, 45, 38, 34, 32, 28, 27, 26, 25, 24, 23, 22,
193
+
],
194
+
/* 2*/
195
+
[
196
+
1500, 1000, 800, 680, 600, 515, 425, 265, 165, 115, 80, 70, 50, 48, 45, 35, 34, 33, 32, 30,
197
+
],
198
+
/* 3*/
199
+
[
200
+
2500, 2310, 1135, 925, 792, 695, 565, 380, 218, 155, 105, 82, 70, 68, 65, 60, 48, 45, 43, 40,
201
+
],
202
+
/* 4*/
203
+
[
204
+
3000, 2800, 1500, 1155, 965, 810, 690, 465, 260, 195, 140, 110, 85, 75, 74, 73, 70, 65, 60, 55,
205
+
],
206
+
/* 5*/
207
+
[
208
+
3400, 3232, 2305, 1380, 1200, 1165, 972, 565, 328, 235, 162, 132, 98, 78, 75, 74, 73, 72, 71,
209
+
70,
210
+
],
211
+
/* 6*/
212
+
[
213
+
3500, 3350, 2500, 1640, 1250, 1210, 1010, 645, 385, 275, 175, 160, 115, 95, 91, 90, 85, 80, 77,
214
+
75,
215
+
],
216
+
/* 7*/
217
+
[
218
+
3600, 3472, 2980, 2060, 1560, 1275, 1132, 738, 430, 310, 230, 170, 128, 122, 110, 108, 105,
219
+
103, 101, 100,
220
+
],
221
+
/* 8*/
222
+
[
223
+
3800, 3500, 3055, 2105, 1740, 1370, 1290, 830, 490, 355, 235, 195, 150, 140, 135, 132, 130,
224
+
125, 120, 119,
225
+
],
226
+
/* 9*/
227
+
[
228
+
3900, 3518, 3190, 2315, 2045, 1510, 1442, 1045, 552, 392, 280, 225, 172, 145, 140, 138, 135,
229
+
134, 132, 130,
230
+
],
231
+
/*10*/
232
+
[
233
+
6000, 5755, 3240, 2530, 2135, 1605, 1500, 1200, 595, 425, 285, 245, 175, 170, 160, 155, 150,
234
+
145, 142, 140,
235
+
],
236
+
/*11*/
237
+
[
238
+
6428, 5872, 3335, 2780, 2270, 1782, 1590, 1310, 648, 470, 315, 255, 182, 180, 175, 172, 170,
239
+
162, 160, 155,
240
+
],
241
+
/*12*/
242
+
[
243
+
6730, 5950, 3490, 2995, 2395, 1890, 1650, 1350, 700, 500, 350, 290, 220, 190, 185, 180, 175,
244
+
170, 165, 160,
245
+
],
246
+
/*13*/
247
+
[
248
+
6962, 6122, 3880, 3205, 2465, 1900, 1700, 1400, 835, 545, 375, 310, 228, 195, 190, 185, 182,
249
+
181, 180, 175,
250
+
],
251
+
/*14*/
252
+
[
253
+
7945, 6365, 4130, 3470, 2505, 1910, 1755, 1510, 855, 580, 400, 330, 235, 210, 205, 200, 195,
254
+
190, 185, 180,
255
+
],
256
+
/*15*/
257
+
[
258
+
8048, 7068, 4442, 3708, 2668, 1930, 1800, 1520, 878, 618, 428, 365, 260, 255, 250, 240, 230,
259
+
220, 210, 200,
260
+
],
205
261
];
206
262
207
263
fn calculate_speed(distance: u32, duration: u32) -> u8 {
208
-
let distance = distance.clamp(0,15);
209
-
if distance == 0 {return 0;}
264
+
let distance = distance.clamp(0, 15);
265
+
if distance == 0 {
266
+
return 0;
267
+
}
210
268
211
-
let mut speed= 1;
269
+
let mut speed = 1;
212
270
while speed < 20 {
213
271
if SPEED_MATRIX[distance as usize - 1][speed as usize - 1] < duration {
214
272
return speed;
···
244
302
let crc = crc16(&data);
245
303
data.push(crc[0]);
246
304
data.push(crc[1]);
247
-
self.previous_position.store(position as u8, Ordering::Relaxed);
248
-
Ok(vec![HardwareWriteCmd::new(
249
-
&[FREDORCH_PROTOCOL_UUID],
250
-
Endpoint::Tx,
251
-
data,
252
-
false,
253
-
)
254
-
.into()])
305
+
self
306
+
.previous_position
307
+
.store(position as u8, Ordering::Relaxed);
308
+
Ok(vec![
309
+
HardwareWriteCmd::new(&[FREDORCH_PROTOCOL_UUID], Endpoint::Tx, data, false).into(),
310
+
])
255
311
}
256
-
312
+
257
313
// TODO: Something is off... I think we need to program in both directions independently
258
-
fn handle_output_oscillate_cmd(&self, _feature_index: u32, _feature_id: Uuid, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
314
+
fn handle_output_oscillate_cmd(
315
+
&self,
316
+
_feature_index: u32,
317
+
_feature_id: Uuid,
318
+
speed: u32,
319
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
259
320
// If we ever get oscillate with range, these should be loaded from the last set range
260
321
let min_pos = if speed == 0 { 0 } else { 0 };
261
322
let max_pos = if speed == 0 { 0 } else { 15 };
262
323
let mut data: Vec<u8> = vec![
263
-
0x01, 0x10, 0x00, 0x6B, 0x00, 0x05, 0x0a, 0x00, speed as u8, 0x00, speed as u8, 0x00, min_pos * 15, 0x00, max_pos * 15,
264
-
0x00, 0x01,
324
+
0x01,
325
+
0x10,
326
+
0x00,
327
+
0x6B,
328
+
0x00,
329
+
0x05,
330
+
0x0a,
331
+
0x00,
332
+
speed as u8,
333
+
0x00,
334
+
speed as u8,
335
+
0x00,
336
+
min_pos * 15,
337
+
0x00,
338
+
max_pos * 15,
339
+
0x00,
340
+
0x01,
265
341
];
266
342
let crc = crc16(&data);
267
343
data.push(crc[0]);
268
344
data.push(crc[1]);
269
-
Ok(vec![HardwareWriteCmd::new(
270
-
&[FREDORCH_PROTOCOL_UUID],
271
-
Endpoint::Tx,
272
-
data,
273
-
false,
274
-
)
275
-
.into()])
345
+
Ok(vec![
346
+
HardwareWriteCmd::new(&[FREDORCH_PROTOCOL_UUID], Endpoint::Tx, data, false).into(),
347
+
])
276
348
}
277
349
}
+110
-86
crates/buttplug_server/src/device/protocol_impl/galaku.rs
+110
-86
crates/buttplug_server/src/device/protocol_impl/galaku.rs
···
119
119
if hardware.name() == "AC695X_1(BLE)" {
120
120
protocol.is_caiping_pump_device = true;
121
121
}
122
-
for _ in 0..def.features().iter().filter(|f| f.output().is_some()).count() {
123
-
protocol.speeds.push(AtomicU8::new(0));
124
-
}
122
+
for _ in 0..def
123
+
.features()
124
+
.iter()
125
+
.filter(|f| f.output().is_some())
126
+
.count()
127
+
{
128
+
protocol.speeds.push(AtomicU8::new(0));
129
+
}
125
130
Ok(Arc::new(protocol))
126
131
}
127
132
}
···
132
137
}
133
138
134
139
impl Default for Galaku {
135
-
fn default() -> Self {
136
-
Self {
137
-
is_caiping_pump_device: false,
138
-
speeds: vec![],
139
-
}
140
+
fn default() -> Self {
141
+
Self {
142
+
is_caiping_pump_device: false,
143
+
speeds: vec![],
140
144
}
145
+
}
141
146
}
142
147
impl Galaku {
143
-
fn handle_local_output_cmd(
144
-
&self,
145
-
feature_index: u32,
146
-
_feature_id: Uuid,
147
-
speed: u32,
148
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
149
-
if self.speeds.len() == 1 {
150
-
if self.is_caiping_pump_device {
151
-
let data: Vec<u8> = vec![
152
-
0xAA,
153
-
1,
154
-
10,
155
-
3,
156
-
speed as u8,
157
-
if speed == 0 { 0 } else { 1 },
158
-
0,
159
-
0,
160
-
0,
161
-
0,
162
-
0,
163
-
0,
164
-
0,
165
-
0,
166
-
0,
167
-
0,
168
-
];
169
-
Ok(vec![HardwareWriteCmd::new(
170
-
&[GALAKU_PROTOCOL_UUID],
171
-
Endpoint::Tx,
172
-
data,
173
-
false,
174
-
)
175
-
.into()])
176
-
} else {
177
-
let data = vec![90, 0, 0, 1, 49, speed, 0, 0, 0, 0];
148
+
fn handle_local_output_cmd(
149
+
&self,
150
+
feature_index: u32,
151
+
_feature_id: Uuid,
152
+
speed: u32,
153
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
154
+
if self.speeds.len() == 1 {
155
+
if self.is_caiping_pump_device {
156
+
let data: Vec<u8> = vec![
157
+
0xAA,
158
+
1,
159
+
10,
160
+
3,
161
+
speed as u8,
162
+
if speed == 0 { 0 } else { 1 },
163
+
0,
164
+
0,
165
+
0,
166
+
0,
167
+
0,
168
+
0,
169
+
0,
170
+
0,
171
+
0,
172
+
0,
173
+
];
174
+
Ok(vec![
175
+
HardwareWriteCmd::new(&[GALAKU_PROTOCOL_UUID], Endpoint::Tx, data, false).into(),
176
+
])
177
+
} else {
178
+
let data = vec![90, 0, 0, 1, 49, speed, 0, 0, 0, 0];
178
179
179
-
Ok(vec![HardwareWriteCmd::new(
180
-
&[GALAKU_PROTOCOL_UUID],
181
-
Endpoint::Tx,
182
-
send_bytes(data),
183
-
false,
184
-
)
185
-
.into()])
186
-
}
187
-
} else {
188
-
if feature_index < self.speeds.len() as u32 {
189
-
self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed);
190
-
} else {
191
-
error!("Tried to set value on out-of-bounds index {} (size {})", feature_index, self.speeds.len());
192
-
}
180
+
Ok(vec![
181
+
HardwareWriteCmd::new(
182
+
&[GALAKU_PROTOCOL_UUID],
183
+
Endpoint::Tx,
184
+
send_bytes(data),
185
+
false,
186
+
)
187
+
.into(),
188
+
])
189
+
}
190
+
} else {
191
+
if feature_index < self.speeds.len() as u32 {
192
+
self.speeds[feature_index as usize].store(speed as u8, Ordering::Relaxed);
193
+
} else {
194
+
error!(
195
+
"Tried to set value on out-of-bounds index {} (size {})",
196
+
feature_index,
197
+
self.speeds.len()
198
+
);
199
+
}
193
200
194
-
let data: Vec<u32> = vec![
195
-
90,
196
-
0,
197
-
0,
198
-
1,
199
-
64,
200
-
3,
201
-
self.speeds[0].load(Ordering::Relaxed) as u32,
202
-
self.speeds[1].load(Ordering::Relaxed) as u32,
203
-
0,
204
-
0,
205
-
];
206
-
Ok(vec![HardwareWriteCmd::new(
207
-
&[GALAKU_PROTOCOL_UUID],
208
-
Endpoint::Tx,
209
-
send_bytes(data),
210
-
false,
211
-
)
212
-
.into()])
213
-
}
201
+
let data: Vec<u32> = vec![
202
+
90,
203
+
0,
204
+
0,
205
+
1,
206
+
64,
207
+
3,
208
+
self.speeds[0].load(Ordering::Relaxed) as u32,
209
+
self.speeds[1].load(Ordering::Relaxed) as u32,
210
+
0,
211
+
0,
212
+
];
213
+
Ok(vec![
214
+
HardwareWriteCmd::new(
215
+
&[GALAKU_PROTOCOL_UUID],
216
+
Endpoint::Tx,
217
+
send_bytes(data),
218
+
false,
219
+
)
220
+
.into(),
221
+
])
214
222
}
223
+
}
215
224
}
216
225
217
226
impl ProtocolHandler for Galaku {
218
-
fn handle_output_oscillate_cmd(&self, feature_index: u32, feature_id: Uuid, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
219
-
self.handle_local_output_cmd(feature_index, feature_id, speed)
220
-
}
221
-
fn handle_output_vibrate_cmd(&self, feature_index: u32, feature_id: Uuid, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
222
-
self.handle_local_output_cmd(feature_index, feature_id, speed)
223
-
}
224
-
fn handle_output_constrict_cmd(&self, feature_index: u32, feature_id: Uuid, level: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
225
-
self.handle_local_output_cmd(feature_index, feature_id, level)
226
-
}
227
+
fn handle_output_oscillate_cmd(
228
+
&self,
229
+
feature_index: u32,
230
+
feature_id: Uuid,
231
+
speed: u32,
232
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
233
+
self.handle_local_output_cmd(feature_index, feature_id, speed)
234
+
}
235
+
fn handle_output_vibrate_cmd(
236
+
&self,
237
+
feature_index: u32,
238
+
feature_id: Uuid,
239
+
speed: u32,
240
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
241
+
self.handle_local_output_cmd(feature_index, feature_id, speed)
242
+
}
243
+
fn handle_output_constrict_cmd(
244
+
&self,
245
+
feature_index: u32,
246
+
feature_id: Uuid,
247
+
level: u32,
248
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
249
+
self.handle_local_output_cmd(feature_index, feature_id, level)
250
+
}
227
251
228
252
fn handle_input_subscribe_cmd(
229
253
&self,
+7
-7
crates/buttplug_server/src/device/protocol_impl/hgod.rs
+7
-7
crates/buttplug_server/src/device/protocol_impl/hgod.rs
···
85
85
false,
86
86
))
87
87
.await
88
-
{
89
-
error!(
90
-
"Got an error from a hgod device, exiting control loop: {:?}",
91
-
e
92
-
);
93
-
break;
94
-
}
88
+
{
89
+
error!(
90
+
"Got an error from a hgod device, exiting control loop: {:?}",
91
+
e
92
+
);
93
+
break;
94
+
}
95
95
sleep(Duration::from_millis(HGOD_COMMAND_DELAY_MS)).await;
96
96
}
97
97
}
+6
-1
crates/buttplug_server/src/device/protocol_impl/hismith_mini.rs
+6
-1
crates/buttplug_server/src/device/protocol_impl/hismith_mini.rs
···
188
188
HardwareWriteCmd::new(
189
189
&[feature_id],
190
190
Endpoint::Tx,
191
-
vec![0xCC, 0x03, speed.unsigned_abs() as u8, speed.unsigned_abs() as u8 + 3],
191
+
vec![
192
+
0xCC,
193
+
0x03,
194
+
speed.unsigned_abs() as u8,
195
+
speed.unsigned_abs() as u8 + 3,
196
+
],
192
197
false,
193
198
)
194
199
.into(),
+38
-43
crates/buttplug_server/src/device/protocol_impl/kgoal_boost.rs
+38
-43
crates/buttplug_server/src/device/protocol_impl/kgoal_boost.rs
···
89
89
return;
90
90
}
91
91
if let HardwareEvent::Notification(_, endpoint, data) = info
92
-
&& endpoint == Endpoint::RxPressure {
93
-
if data.len() < 7 {
94
-
// Not even sure how this would happen, error and continue on.
95
-
error!("KGoal Boost data not expected length!");
96
-
continue;
97
-
}
98
-
// Extract our two pressure values.
99
-
let normalized = (data[3] as u32) << 8 | data[4] as u32;
100
-
let unnormalized = (data[5] as u32) << 8 | data[6] as u32;
101
-
if stream_sensors.contains(&0)
102
-
&& sender
103
-
.send(
104
-
InputReadingV4::new(
105
-
device_index,
106
-
feature_index,
107
-
buttplug_core::message::InputTypeData::Pressure(InputData::new(normalized)),
108
-
)
109
-
.into(),
92
+
&& endpoint == Endpoint::RxPressure
93
+
{
94
+
if data.len() < 7 {
95
+
// Not even sure how this would happen, error and continue on.
96
+
error!("KGoal Boost data not expected length!");
97
+
continue;
98
+
}
99
+
// Extract our two pressure values.
100
+
let normalized = (data[3] as u32) << 8 | data[4] as u32;
101
+
let unnormalized = (data[5] as u32) << 8 | data[6] as u32;
102
+
if stream_sensors.contains(&0)
103
+
&& sender
104
+
.send(
105
+
InputReadingV4::new(
106
+
device_index,
107
+
feature_index,
108
+
buttplug_core::message::InputTypeData::Pressure(InputData::new(normalized)),
110
109
)
111
-
.is_err()
112
-
{
113
-
debug!(
114
-
"Hardware device listener for KGoal Boost shut down, returning from task."
115
-
);
116
-
return;
117
-
}
118
-
if stream_sensors.contains(&1)
119
-
&& sender
120
-
.send(
121
-
InputReadingV4::new(
122
-
device_index,
123
-
feature_index,
124
-
buttplug_core::message::InputTypeData::Pressure(InputData::new(
125
-
unnormalized,
126
-
)),
127
-
)
128
-
.into(),
110
+
.into(),
111
+
)
112
+
.is_err()
113
+
{
114
+
debug!("Hardware device listener for KGoal Boost shut down, returning from task.");
115
+
return;
116
+
}
117
+
if stream_sensors.contains(&1)
118
+
&& sender
119
+
.send(
120
+
InputReadingV4::new(
121
+
device_index,
122
+
feature_index,
123
+
buttplug_core::message::InputTypeData::Pressure(InputData::new(unnormalized)),
129
124
)
130
-
.is_err()
131
-
{
132
-
debug!(
133
-
"Hardware device listener for KGoal Boost shut down, returning from task."
134
-
);
135
-
return;
136
-
}
125
+
.into(),
126
+
)
127
+
.is_err()
128
+
{
129
+
debug!("Hardware device listener for KGoal Boost shut down, returning from task.");
130
+
return;
137
131
}
132
+
}
138
133
}
139
134
});
140
135
}
+27
-20
crates/buttplug_server/src/device/protocol_impl/kiiroo_powershot.rs
+27
-20
crates/buttplug_server/src/device/protocol_impl/kiiroo_powershot.rs
···
7
7
8
8
use crate::device::{
9
9
hardware::{Hardware, HardwareCommand, HardwareReadCmd, HardwareWriteCmd},
10
-
protocol::{generic_protocol_setup, ProtocolHandler},
10
+
protocol::{ProtocolHandler, generic_protocol_setup},
11
11
};
12
12
use buttplug_core::{
13
13
errors::ButtplugDeviceError,
14
14
message::{self, InputData, InputReadingV4, InputTypeData},
15
15
};
16
16
use buttplug_server_device_config::Endpoint;
17
-
use futures::{future::BoxFuture, FutureExt};
18
-
use std::{default::Default, sync::Arc};
17
+
use futures::{FutureExt, future::BoxFuture};
19
18
use std::sync::atomic::{AtomicU8, Ordering};
20
-
use uuid::{uuid, Uuid};
19
+
use std::{default::Default, sync::Arc};
20
+
use uuid::{Uuid, uuid};
21
21
const KIIROO_POWERSHUOT_PROTOCOL_UUID: Uuid = uuid!("06f49eb9-0dca-42a8-92f0-58634cc017d0");
22
22
23
23
generic_protocol_setup!(KiirooPowerShot, "kiiroo-powershot");
24
24
25
25
#[derive(Default)]
26
26
pub struct KiirooPowerShot {
27
-
last_cmds: [AtomicU8; 2]
27
+
last_cmds: [AtomicU8; 2],
28
28
}
29
29
30
30
impl KiirooPowerShot {
31
-
fn form_hardware_command(&self, index: u32, speed: u32) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
31
+
fn form_hardware_command(
32
+
&self,
33
+
index: u32,
34
+
speed: u32,
35
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
32
36
self.last_cmds[index as usize].store(speed as u8, Ordering::Relaxed);
33
-
Ok(vec![HardwareWriteCmd::new(
34
-
&[KIIROO_POWERSHUOT_PROTOCOL_UUID],
35
-
Endpoint::Tx,
36
-
vec![
37
-
0x01,
38
-
0x00,
39
-
0x00,
40
-
self.last_cmds[0].load(Ordering::Relaxed),
41
-
self.last_cmds[1].load(Ordering::Relaxed),
42
-
0x00,
43
-
],
44
-
true,
45
-
).into()])
37
+
Ok(vec![
38
+
HardwareWriteCmd::new(
39
+
&[KIIROO_POWERSHUOT_PROTOCOL_UUID],
40
+
Endpoint::Tx,
41
+
vec![
42
+
0x01,
43
+
0x00,
44
+
0x00,
45
+
self.last_cmds[0].load(Ordering::Relaxed),
46
+
self.last_cmds[1].load(Ordering::Relaxed),
47
+
0x00,
48
+
],
49
+
true,
50
+
)
51
+
.into(),
52
+
])
46
53
}
47
54
}
48
55
···
72
79
let battery_reading = message::InputReadingV4::new(
73
80
device_index,
74
81
feature_index,
75
-
InputTypeData::Battery(InputData::new(data[0]))
82
+
InputTypeData::Battery(InputData::new(data[0])),
76
83
);
77
84
debug!("Got battery reading: {}", data[0]);
78
85
Ok(battery_reading)
+3
-5
crates/buttplug_server/src/device/protocol_impl/kiiroo_v3.rs
+3
-5
crates/buttplug_server/src/device/protocol_impl/kiiroo_v3.rs
···
8
8
use crate::device::{
9
9
hardware::Hardware,
10
10
protocol::{
11
-
generic_protocol_initializer_setup,
12
11
ProtocolHandler,
13
12
ProtocolIdentifier,
14
13
ProtocolInitializer,
14
+
generic_protocol_initializer_setup,
15
15
},
16
16
protocol_impl::kiiroo_v21::KiirooV21,
17
17
};
18
18
use async_trait::async_trait;
19
19
use buttplug_core::errors::ButtplugDeviceError;
20
20
use buttplug_server_device_config::{
21
-
ServerDeviceDefinition,
22
21
ProtocolCommunicationSpecifier,
22
+
ServerDeviceDefinition,
23
23
UserDeviceIdentifier,
24
24
};
25
-
use std::sync::{
26
-
Arc,
27
-
};
25
+
use std::sync::Arc;
28
26
29
27
generic_protocol_initializer_setup!(KiirooV3, "kiiroo-v3");
30
28
+4
-1
crates/buttplug_server/src/device/protocol_impl/lovense/lovense_multi_actuator.rs
+4
-1
crates/buttplug_server/src/device/protocol_impl/lovense/lovense_multi_actuator.rs
···
42
42
feature_id: Uuid,
43
43
speed: u32,
44
44
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
45
-
debug!("Lovense multi-actuator command: {}", format!("Vibrate{}:{};", feature_index + 1, speed));
45
+
debug!(
46
+
"Lovense multi-actuator command: {}",
47
+
format!("Vibrate{}:{};", feature_index + 1, speed)
48
+
);
46
49
let lovense_cmd = format!("Vibrate{}:{};", feature_index + 1, speed)
47
50
.as_bytes()
48
51
.to_vec();
+3
-3
crates/buttplug_server/src/device/protocol_impl/lovense/mod.rs
+3
-3
crates/buttplug_server/src/device/protocol_impl/lovense/mod.rs
···
562
562
.into(),
563
563
);
564
564
}
565
-
let lovense_cmd = format!("Rotate:{speed};").as_bytes().to_vec();
566
-
hardware_cmds
567
-
.push(HardwareWriteCmd::new(&[LOVENSE_ROTATE_UUID], Endpoint::Tx, lovense_cmd, false).into());
565
+
let lovense_cmd = format!("Rotate:{speed};").as_bytes().to_vec();
566
+
hardware_cmds
567
+
.push(HardwareWriteCmd::new(&[LOVENSE_ROTATE_UUID], Endpoint::Tx, lovense_cmd, false).into());
568
568
trace!("{:?}", hardware_cmds);
569
569
Ok(hardware_cmds)
570
570
}
+34
-21
crates/buttplug_server/src/device/protocol_impl/luvmazer.rs
+34
-21
crates/buttplug_server/src/device/protocol_impl/luvmazer.rs
···
26
26
feature_id: Uuid,
27
27
speed: u32,
28
28
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
29
-
Ok(vec![HardwareWriteCmd::new(
30
-
&[feature_id],
31
-
Endpoint::Tx,
32
-
vec![0xa0, 0x01, 0x00, feature_index as u8, 0x64, speed as u8],
33
-
false,
34
-
)
35
-
.into()])
29
+
Ok(vec![
30
+
HardwareWriteCmd::new(
31
+
&[feature_id],
32
+
Endpoint::Tx,
33
+
vec![0xa0, 0x01, 0x00, feature_index as u8, 0x64, speed as u8],
34
+
false,
35
+
)
36
+
.into(),
37
+
])
36
38
}
37
39
38
40
fn handle_output_rotate_cmd(
···
58
60
feature_id: Uuid,
59
61
speed: u32,
60
62
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
61
-
Ok(vec![HardwareWriteCmd::new(
62
-
&[feature_id],
63
-
Endpoint::Tx,
64
-
vec![0xa0, 0x06, 0x01, 0x00, 0x64, speed as u8],
65
-
false,
66
-
)
67
-
.into()])
63
+
Ok(vec![
64
+
HardwareWriteCmd::new(
65
+
&[feature_id],
66
+
Endpoint::Tx,
67
+
vec![0xa0, 0x06, 0x01, 0x00, 0x64, speed as u8],
68
+
false,
69
+
)
70
+
.into(),
71
+
])
68
72
}
69
73
70
74
fn handle_output_constrict_cmd(
···
73
77
feature_id: Uuid,
74
78
speed: u32,
75
79
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
76
-
Ok(vec![HardwareWriteCmd::new(
77
-
&[feature_id],
78
-
Endpoint::Tx,
79
-
vec![0xa0, 0x0d, 0x00, 0x00, if speed == 0 { 0x00} else { 0x14 }, speed as u8],
80
-
false,
81
-
)
82
-
.into()])
80
+
Ok(vec![
81
+
HardwareWriteCmd::new(
82
+
&[feature_id],
83
+
Endpoint::Tx,
84
+
vec![
85
+
0xa0,
86
+
0x0d,
87
+
0x00,
88
+
0x00,
89
+
if speed == 0 { 0x00 } else { 0x14 },
90
+
speed as u8,
91
+
],
92
+
false,
93
+
)
94
+
.into(),
95
+
])
83
96
}
84
97
}
+21
-21
crates/buttplug_server/src/device/protocol_impl/mod.rs
+21
-21
crates/buttplug_server/src/device/protocol_impl/mod.rs
···
37
37
pub mod kiiroo_prowand;
38
38
pub mod kiiroo_spot;
39
39
pub mod kiiroo_v2;
40
-
pub mod kiiroo_v3;
41
40
pub mod kiiroo_v21;
42
41
pub mod kiiroo_v21_initialized;
43
42
pub mod kiiroo_v2_vibrator;
43
+
pub mod kiiroo_v3;
44
44
pub mod kizuna;
45
45
pub mod lelo_harmony;
46
46
pub mod lelof1s;
···
420
420
&mut map,
421
421
sexverse_lg389::setup::SexverseLG389IdentifierFactory::default(),
422
422
);
423
-
add_to_protocol_map(
424
-
&mut map,
425
-
sexverse_v1::setup::SexverseV1IdentifierFactory::default(),
426
-
);
427
-
add_to_protocol_map(
428
-
&mut map,
429
-
sexverse_v2::setup::SexverseV2IdentifierFactory::default(),
430
-
);
431
-
add_to_protocol_map(
432
-
&mut map,
433
-
sexverse_v3::setup::SexverseV3IdentifierFactory::default(),
434
-
);
435
-
add_to_protocol_map(
436
-
&mut map,
437
-
sexverse_v4::setup::SexverseV4IdentifierFactory::default(),
438
-
);
439
-
add_to_protocol_map(
440
-
&mut map,
441
-
sexverse_v5::setup::SexverseV5IdentifierFactory::default(),
442
-
);
423
+
add_to_protocol_map(
424
+
&mut map,
425
+
sexverse_v1::setup::SexverseV1IdentifierFactory::default(),
426
+
);
427
+
add_to_protocol_map(
428
+
&mut map,
429
+
sexverse_v2::setup::SexverseV2IdentifierFactory::default(),
430
+
);
431
+
add_to_protocol_map(
432
+
&mut map,
433
+
sexverse_v3::setup::SexverseV3IdentifierFactory::default(),
434
+
);
435
+
add_to_protocol_map(
436
+
&mut map,
437
+
sexverse_v4::setup::SexverseV4IdentifierFactory::default(),
438
+
);
439
+
add_to_protocol_map(
440
+
&mut map,
441
+
sexverse_v5::setup::SexverseV5IdentifierFactory::default(),
442
+
);
443
443
add_to_protocol_map(&mut map, serveu::setup::ServeUIdentifierFactory::default());
444
444
add_to_protocol_map(
445
445
&mut map,
+5
-1
crates/buttplug_server/src/device/protocol_impl/motorbunny.rs
+5
-1
crates/buttplug_server/src/device/protocol_impl/motorbunny.rs
···
61
61
command_vec = vec![0xa0, 0x00, 0x00, 0x00, 0x00, 0xec];
62
62
} else {
63
63
command_vec = vec![0xaf];
64
-
let mut rotate_command = [if speed >= 0 { 0x2a } else { 0x29 }, speed.unsigned_abs() as u8].repeat(7);
64
+
let mut rotate_command = [
65
+
if speed >= 0 { 0x2a } else { 0x29 },
66
+
speed.unsigned_abs() as u8,
67
+
]
68
+
.repeat(7);
65
69
let crc = rotate_command
66
70
.iter()
67
71
.fold(0u8, |a, b| a.overflowing_add(*b).0);
+5
-5
crates/buttplug_server/src/device/protocol_impl/nexus_revo.rs
+5
-5
crates/buttplug_server/src/device/protocol_impl/nexus_revo.rs
···
38
38
}
39
39
40
40
fn handle_output_rotate_cmd(
41
-
&self,
42
-
_feature_index: u32,
43
-
feature_id: Uuid,
44
-
speed: i32,
45
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
41
+
&self,
42
+
_feature_index: u32,
43
+
feature_id: Uuid,
44
+
speed: i32,
45
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
46
46
Ok(vec![
47
47
HardwareWriteCmd::new(
48
48
&[feature_id],
+1
-4
crates/buttplug_server/src/device/protocol_impl/nintendo_joycon.rs
+1
-4
crates/buttplug_server/src/device/protocol_impl/nintendo_joycon.rs
···
15
15
},
16
16
};
17
17
use async_trait::async_trait;
18
-
use buttplug_core::{
19
-
errors::ButtplugDeviceError,
20
-
util::async_manager,
21
-
};
18
+
use buttplug_core::{errors::ButtplugDeviceError, util::async_manager};
22
19
use buttplug_server_device_config::{
23
20
Endpoint,
24
21
ProtocolCommunicationSpecifier,
+4
-3
crates/buttplug_server/src/device/protocol_impl/sensee_v2.rs
+4
-3
crates/buttplug_server/src/device/protocol_impl/sensee_v2.rs
···
70
70
.enumerate()
71
71
.for_each(|(i, x)| {
72
72
if let Some(output_map) = x.output()
73
-
&& output_map.contains(output_type) {
74
-
map.insert(i as u32, AtomicU8::new(0));
75
-
}
73
+
&& output_map.contains(output_type)
74
+
{
75
+
map.insert(i as u32, AtomicU8::new(0));
76
+
}
76
77
});
77
78
map
78
79
};
+3
-7
crates/buttplug_server/src/device/protocol_impl/sexverse_v1.rs
+3
-7
crates/buttplug_server/src/device/protocol_impl/sexverse_v1.rs
···
97
97
}
98
98
data.push(crc);
99
99
100
-
Ok(vec![HardwareWriteCmd::new(
101
-
&[SEXVERSE_PROTOCOL_UUID],
102
-
Endpoint::Tx,
103
-
data,
104
-
false,
105
-
)
106
-
.into()])
100
+
Ok(vec![
101
+
HardwareWriteCmd::new(&[SEXVERSE_PROTOCOL_UUID], Endpoint::Tx, data, false).into(),
102
+
])
107
103
}
108
104
}
109
105
+5
-5
crates/buttplug_server/src/device/protocol_impl/synchro.rs
+5
-5
crates/buttplug_server/src/device/protocol_impl/synchro.rs
···
21
21
22
22
impl ProtocolHandler for Synchro {
23
23
fn handle_output_rotate_cmd(
24
-
&self,
25
-
_feature_index: u32,
26
-
feature_id: Uuid,
27
-
speed: i32,
28
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
24
+
&self,
25
+
_feature_index: u32,
26
+
feature_id: Uuid,
27
+
speed: i32,
28
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
29
29
Ok(vec![
30
30
HardwareWriteCmd::new(
31
31
&[feature_id],
+5
-5
crates/buttplug_server/src/device/protocol_impl/tryfun_meta2.rs
+5
-5
crates/buttplug_server/src/device/protocol_impl/tryfun_meta2.rs
···
55
55
}
56
56
57
57
fn handle_output_rotate_cmd(
58
-
&self,
59
-
_feature_index: u32,
60
-
feature_id: Uuid,
61
-
speed: i32,
62
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
58
+
&self,
59
+
_feature_index: u32,
60
+
feature_id: Uuid,
61
+
speed: i32,
62
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
63
63
let mut speed = speed as i8;
64
64
if speed >= 0 {
65
65
speed += 1;
+5
-5
crates/buttplug_server/src/device/protocol_impl/vorze_sa/dual_rotator.rs
+5
-5
crates/buttplug_server/src/device/protocol_impl/vorze_sa/dual_rotator.rs
···
27
27
28
28
impl ProtocolHandler for VorzeSADualRotator {
29
29
fn handle_output_rotate_cmd(
30
-
&self,
31
-
feature_index: u32,
32
-
_feature_id: Uuid,
33
-
speed: i32,
34
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
30
+
&self,
31
+
feature_index: u32,
32
+
_feature_id: Uuid,
33
+
speed: i32,
34
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
35
35
self.speeds[feature_index as usize].store(speed as i8, Ordering::Relaxed);
36
36
let speed_left = self.speeds[0].load(Ordering::Relaxed);
37
37
let data_left = ((speed_left >= 0) as u8) << 7 | (speed_left.unsigned_abs());
+1
-3
crates/buttplug_server/src/device/protocol_impl/vorze_sa/piston.rs
+1
-3
crates/buttplug_server/src/device/protocol_impl/vorze_sa/piston.rs
+6
-6
crates/buttplug_server/src/device/protocol_impl/vorze_sa/single_rotator.rs
+6
-6
crates/buttplug_server/src/device/protocol_impl/vorze_sa/single_rotator.rs
···
26
26
27
27
impl ProtocolHandler for VorzeSASingleRotator {
28
28
fn handle_output_rotate_cmd(
29
-
&self,
30
-
_feature_index: u32,
31
-
feature_id: uuid::Uuid,
32
-
speed: i32,
33
-
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
34
-
let clockwise = if speed >=0 { 1u8 } else { 0 };
29
+
&self,
30
+
_feature_index: u32,
31
+
feature_id: uuid::Uuid,
32
+
speed: i32,
33
+
) -> Result<Vec<HardwareCommand>, ButtplugDeviceError> {
34
+
let clockwise = if speed >= 0 { 1u8 } else { 0 };
35
35
let data: u8 = (clockwise) << 7 | (speed.unsigned_abs() as u8);
36
36
Ok(vec![
37
37
HardwareWriteCmd::new(
+15
-12
crates/buttplug_server/src/device/server_device.rs
+15
-12
crates/buttplug_server/src/device/server_device.rs
···
221
221
strategy,
222
222
ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(_)
223
223
))
224
-
&& let Err(e) = device.handle_stop_device_cmd().await {
225
-
return Err(ButtplugDeviceError::DeviceConnectionError(format!(
226
-
"Error setting up keepalive: {e}"
227
-
)));
228
-
}
224
+
&& let Err(e) = device.handle_stop_device_cmd().await
225
+
{
226
+
return Err(ButtplugDeviceError::DeviceConnectionError(format!(
227
+
"Error setting up keepalive: {e}"
228
+
)));
229
+
}
229
230
230
231
Ok(device)
231
232
}
···
271
272
strategy,
272
273
ProtocolKeepaliveStrategy::RepeatLastPacketStrategyWithTiming(_)
273
274
))
274
-
&& let HardwareCommand::Write(command) = command {
275
-
*keepalive_packet.lock().await = Some(command);
276
-
};
275
+
&& let HardwareCommand::Write(command) = command
276
+
{
277
+
*keepalive_packet.lock().await = Some(command);
278
+
};
277
279
};
278
280
loop {
279
281
let requires_keepalive = hardware.requires_keepalive();
···
556
558
557
559
fn handle_outputcmd_v4(&self, msg: &CheckedOutputCmdV4) -> ButtplugServerResultFuture {
558
560
if let Some(last_msg) = self.last_output_command.get(&msg.feature_id())
559
-
&& *last_msg == *msg {
560
-
trace!("No commands generated for incoming device packet, skipping and returning success.");
561
-
return future::ready(Ok(message::OkV0::default().into())).boxed();
562
-
}
561
+
&& *last_msg == *msg
562
+
{
563
+
trace!("No commands generated for incoming device packet, skipping and returning success.");
564
+
return future::ready(Ok(message::OkV0::default().into())).boxed();
565
+
}
563
566
self
564
567
.last_output_command
565
568
.insert(msg.feature_id(), msg.clone());
+1
-5
crates/buttplug_server/src/device/server_device_manager_event_loop.rs
+1
-5
crates/buttplug_server/src/device/server_device_manager_event_loop.rs
···
322
322
323
323
// After that, we can send out to the server's event listeners to let
324
324
// them know a device has been added.
325
-
if self
326
-
.server_sender
327
-
.send(device_update_message)
328
-
.is_err()
329
-
{
325
+
if self.server_sender.send(device_update_message).is_err() {
330
326
debug!("Server not currently available, dropping Device Added event.");
331
327
}
332
328
}
+52
-46
crates/buttplug_server/src/message/v3/client_device_message_attributes.rs
+52
-46
crates/buttplug_server/src/message/v3/client_device_message_attributes.rs
···
10
10
v2::{ClientDeviceMessageAttributesV2, GenericDeviceMessageAttributesV2},
11
11
};
12
12
use buttplug_core::message::{
13
-
DeviceFeature, DeviceFeatureOutputValueProperties, InputCommandType, InputType, OutputType
13
+
DeviceFeature,
14
+
DeviceFeatureOutputValueProperties,
15
+
InputCommandType,
16
+
InputType,
17
+
OutputType,
14
18
};
15
19
use getset::{Getters, MutGetters, Setters};
16
20
use serde::{Deserialize, Serialize, Serializer, ser::SerializeSeq};
···
253
257
};
254
258
actuator_vec.push(attrs)
255
259
};
256
-
if let Some(x) = output_map
257
-
.constrict()
258
-
.as_ref() { create_actuator(OutputType::Constrict, x) }
259
-
if let Some(x) = output_map
260
-
.heater()
261
-
.as_ref() { create_actuator(OutputType::Heater, x) }
262
-
if let Some(x) = output_map
263
-
.led()
264
-
.as_ref() { create_actuator(OutputType::Led, x) }
265
-
if let Some(x) = output_map
266
-
.oscillate()
267
-
.as_ref() { create_actuator(OutputType::Oscillate, x) }
268
-
if let Some(x) = output_map
269
-
.position()
270
-
.as_ref() { create_actuator(OutputType::Position, x) }
271
-
if let Some(x) = output_map
272
-
.rotate()
273
-
.as_ref() { create_actuator(OutputType::Rotate, x) }
274
-
if let Some(x) = output_map
275
-
.spray()
276
-
.as_ref() { create_actuator(OutputType::Spray, x) }
277
-
if let Some(x) = output_map
278
-
.vibrate()
279
-
.as_ref() { create_actuator(OutputType::Vibrate, x) }
260
+
if let Some(x) = output_map.constrict().as_ref() {
261
+
create_actuator(OutputType::Constrict, x)
262
+
}
263
+
if let Some(x) = output_map.heater().as_ref() {
264
+
create_actuator(OutputType::Heater, x)
265
+
}
266
+
if let Some(x) = output_map.led().as_ref() {
267
+
create_actuator(OutputType::Led, x)
268
+
}
269
+
if let Some(x) = output_map.oscillate().as_ref() {
270
+
create_actuator(OutputType::Oscillate, x)
271
+
}
272
+
if let Some(x) = output_map.position().as_ref() {
273
+
create_actuator(OutputType::Position, x)
274
+
}
275
+
if let Some(x) = output_map.rotate().as_ref() {
276
+
create_actuator(OutputType::Rotate, x)
277
+
}
278
+
if let Some(x) = output_map.spray().as_ref() {
279
+
create_actuator(OutputType::Spray, x)
280
+
}
281
+
if let Some(x) = output_map.vibrate().as_ref() {
282
+
create_actuator(OutputType::Vibrate, x)
283
+
}
280
284
}
281
285
actuator_vec
282
286
})
···
289
293
.flat_map(|feature| {
290
294
let mut actuator_vec = vec![];
291
295
if let Some(output_map) = feature.output()
292
-
&& let Some(actuator) = output_map.rotate()
293
-
&& *actuator.value().start() < 0 {
294
-
let actuator_type = OutputType::Rotate;
295
-
let attrs = ClientGenericDeviceMessageAttributesV3 {
296
-
feature_descriptor: feature.description().to_owned(),
297
-
actuator_type,
298
-
step_count: actuator.step_count(),
299
-
index: 0,
300
-
};
301
-
actuator_vec.push(attrs)
302
-
}
296
+
&& let Some(actuator) = output_map.rotate()
297
+
&& *actuator.value().start() < 0
298
+
{
299
+
let actuator_type = OutputType::Rotate;
300
+
let attrs = ClientGenericDeviceMessageAttributesV3 {
301
+
feature_descriptor: feature.description().to_owned(),
302
+
actuator_type,
303
+
step_count: actuator.step_count(),
304
+
index: 0,
305
+
};
306
+
actuator_vec.push(attrs)
307
+
}
303
308
actuator_vec
304
309
})
305
310
.collect();
···
309
314
.flat_map(|feature| {
310
315
let mut actuator_vec = vec![];
311
316
if let Some(output_map) = feature.output()
312
-
&& let Some(actuator) = output_map.position_with_duration() {
313
-
let actuator_type = OutputType::Position;
314
-
let attrs = ClientGenericDeviceMessageAttributesV3 {
315
-
feature_descriptor: feature.description().to_owned(),
316
-
actuator_type,
317
-
step_count: actuator.step_count(),
318
-
index: 0,
319
-
};
320
-
actuator_vec.push(attrs)
321
-
}
317
+
&& let Some(actuator) = output_map.position_with_duration()
318
+
{
319
+
let actuator_type = OutputType::Position;
320
+
let attrs = ClientGenericDeviceMessageAttributesV3 {
321
+
feature_descriptor: feature.description().to_owned(),
322
+
actuator_type,
323
+
step_count: actuator.step_count(),
324
+
index: 0,
325
+
};
326
+
actuator_vec.push(attrs)
327
+
}
322
328
actuator_vec
323
329
})
324
330
.collect();
+63
-60
crates/buttplug_server/src/message/v3/server_device_message_attributes.rs
+63
-60
crates/buttplug_server/src/message/v3/server_device_message_attributes.rs
···
72
72
};
73
73
// TODO oh come on just make a fucking iterator here. At least, once we figure out the
74
74
// unifying trait we can use to make an iterator on this.
75
-
if let Some(attr) = output_map
76
-
.constrict()
77
-
.as_ref() { create_attribute(OutputType::Constrict, attr.value().step_count()) }
78
-
if let Some(attr) = output_map
79
-
.oscillate()
80
-
.as_ref() { create_attribute(OutputType::Oscillate, attr.value().step_count()) }
81
-
if let Some(attr) = output_map
82
-
.position()
83
-
.as_ref() { create_attribute(OutputType::Position, attr.position().step_count()) }
84
-
if let Some(attr) = output_map
85
-
.rotate()
86
-
.as_ref() { create_attribute(OutputType::Rotate, attr.value().step_count()) }
87
-
if let Some(attr) = output_map
88
-
.heater()
89
-
.as_ref() { create_attribute(OutputType::Heater, attr.value().step_count()) }
90
-
if let Some(attr) = output_map
91
-
.led()
92
-
.as_ref() { create_attribute(OutputType::Led, attr.value().step_count()) }
93
-
if let Some(attr) = output_map
94
-
.vibrate()
95
-
.as_ref() { create_attribute(OutputType::Vibrate, attr.value().step_count()) }
96
-
if let Some(attr) = output_map
97
-
.spray()
98
-
.as_ref() { create_attribute(OutputType::Spray, attr.value().step_count()) }
75
+
if let Some(attr) = output_map.constrict().as_ref() {
76
+
create_attribute(OutputType::Constrict, attr.value().step_count())
77
+
}
78
+
if let Some(attr) = output_map.oscillate().as_ref() {
79
+
create_attribute(OutputType::Oscillate, attr.value().step_count())
80
+
}
81
+
if let Some(attr) = output_map.position().as_ref() {
82
+
create_attribute(OutputType::Position, attr.position().step_count())
83
+
}
84
+
if let Some(attr) = output_map.rotate().as_ref() {
85
+
create_attribute(OutputType::Rotate, attr.value().step_count())
86
+
}
87
+
if let Some(attr) = output_map.heater().as_ref() {
88
+
create_attribute(OutputType::Heater, attr.value().step_count())
89
+
}
90
+
if let Some(attr) = output_map.led().as_ref() {
91
+
create_attribute(OutputType::Led, attr.value().step_count())
92
+
}
93
+
if let Some(attr) = output_map.vibrate().as_ref() {
94
+
create_attribute(OutputType::Vibrate, attr.value().step_count())
95
+
}
96
+
if let Some(attr) = output_map.spray().as_ref() {
97
+
create_attribute(OutputType::Spray, attr.value().step_count())
98
+
}
99
99
}
100
100
actuator_vec
101
101
})
···
108
108
.flat_map(|feature| {
109
109
let mut actuator_vec = vec![];
110
110
if let Some(output_map) = feature.output()
111
-
&& let Some(actuator) = output_map.rotate()
112
-
&& *actuator.value().base().start() < 0 {
113
-
let actuator_type = OutputType::Rotate;
114
-
let step_count = actuator.value().step_count();
115
-
let attrs = ServerGenericDeviceMessageAttributesV3 {
116
-
feature_descriptor: feature.description().to_owned(),
117
-
actuator_type,
118
-
step_count,
119
-
feature: feature.clone(),
120
-
index: 0,
121
-
};
122
-
actuator_vec.push(attrs)
123
-
}
111
+
&& let Some(actuator) = output_map.rotate()
112
+
&& *actuator.value().base().start() < 0
113
+
{
114
+
let actuator_type = OutputType::Rotate;
115
+
let step_count = actuator.value().step_count();
116
+
let attrs = ServerGenericDeviceMessageAttributesV3 {
117
+
feature_descriptor: feature.description().to_owned(),
118
+
actuator_type,
119
+
step_count,
120
+
feature: feature.clone(),
121
+
index: 0,
122
+
};
123
+
actuator_vec.push(attrs)
124
+
}
124
125
actuator_vec
125
126
})
126
127
.collect();
···
130
131
.flat_map(|feature| {
131
132
let mut actuator_vec = vec![];
132
133
if let Some(output_map) = feature.output()
133
-
&& let Some(actuator) = output_map.position_with_duration() {
134
-
let actuator_type = OutputType::Position;
135
-
let step_count = actuator.position().step_count();
136
-
let attrs = ServerGenericDeviceMessageAttributesV3 {
137
-
feature_descriptor: feature.description().to_owned(),
138
-
actuator_type,
139
-
step_count,
140
-
feature: feature.clone(),
141
-
index: 0,
142
-
};
143
-
actuator_vec.push(attrs)
144
-
}
134
+
&& let Some(actuator) = output_map.position_with_duration()
135
+
{
136
+
let actuator_type = OutputType::Position;
137
+
let step_count = actuator.position().step_count();
138
+
let attrs = ServerGenericDeviceMessageAttributesV3 {
139
+
feature_descriptor: feature.description().to_owned(),
140
+
actuator_type,
141
+
step_count,
142
+
feature: feature.clone(),
143
+
index: 0,
144
+
};
145
+
actuator_vec.push(attrs)
146
+
}
145
147
actuator_vec
146
148
})
147
149
.collect();
···
152
154
.map(|feature| {
153
155
let mut sensor_vec = vec![];
154
156
if let Some(sensor_map) = feature.input()
155
-
&& let Some(battery) = sensor_map.battery() {
156
-
// Only convert Battery backwards. Other sensors weren't really built for v3 and we
157
-
// never recommended using them or implemented much for them.
158
-
sensor_vec.push(ServerSensorDeviceMessageAttributesV3 {
159
-
feature_descriptor: feature.description().to_owned(),
160
-
sensor_type: InputType::Battery,
161
-
sensor_range: battery.value_range().clone(),
162
-
feature: feature.clone(),
163
-
index: 0,
164
-
});
165
-
}
157
+
&& let Some(battery) = sensor_map.battery()
158
+
{
159
+
// Only convert Battery backwards. Other sensors weren't really built for v3 and we
160
+
// never recommended using them or implemented much for them.
161
+
sensor_vec.push(ServerSensorDeviceMessageAttributesV3 {
162
+
feature_descriptor: feature.description().to_owned(),
163
+
sensor_type: InputType::Battery,
164
+
sensor_range: battery.value_range().clone(),
165
+
feature: feature.clone(),
166
+
index: 0,
167
+
});
168
+
}
166
169
sensor_vec
167
170
})
168
171
.flatten()
+2
-1
crates/buttplug_server/src/message/v4/checked_output_vec_cmd.rs
+2
-1
crates/buttplug_server/src/message/v4/checked_output_vec_cmd.rs
···
387
387
ButtplugError::from(ButtplugMessageError::InvalidMessageContents(
388
388
"Position should be 0.0 < x < 1.0".to_owned(),
389
389
))
390
-
})? as i32 * (if cmd.clockwise() { 1 } else { -1 })
390
+
})? as i32
391
+
* (if cmd.clockwise() { 1 } else { -1 }),
391
392
)),
392
393
));
393
394
}
+6
-14
crates/buttplug_server/src/server_message_conversion.rs
+6
-14
crates/buttplug_server/src/server_message_conversion.rs
···
105
105
.collect();
106
106
self.device_indexes.remove(&disconnected_indexes[0]);
107
107
match version {
108
-
ButtplugMessageSpecVersion::Version0 => {
109
-
ButtplugServerMessageVariant::V0(ButtplugServerMessageV0::DeviceRemoved(
110
-
DeviceRemovedV0::new(disconnected_indexes[0]),
111
-
))
112
-
}
108
+
ButtplugMessageSpecVersion::Version0 => ButtplugServerMessageVariant::V0(
109
+
ButtplugServerMessageV0::DeviceRemoved(DeviceRemovedV0::new(disconnected_indexes[0])),
110
+
),
113
111
ButtplugMessageSpecVersion::Version1 => {
114
-
ButtplugServerMessageVariant::V1(
115
-
DeviceRemovedV0::new(disconnected_indexes[0]).into(),
116
-
)
112
+
ButtplugServerMessageVariant::V1(DeviceRemovedV0::new(disconnected_indexes[0]).into())
117
113
}
118
114
ButtplugMessageSpecVersion::Version2 => {
119
-
ButtplugServerMessageVariant::V2(
120
-
DeviceRemovedV0::new(disconnected_indexes[0]).into(),
121
-
)
115
+
ButtplugServerMessageVariant::V2(DeviceRemovedV0::new(disconnected_indexes[0]).into())
122
116
}
123
117
ButtplugMessageSpecVersion::Version3 => {
124
-
ButtplugServerMessageVariant::V3(
125
-
DeviceRemovedV0::new(disconnected_indexes[0]).into(),
126
-
)
118
+
ButtplugServerMessageVariant::V3(DeviceRemovedV0::new(disconnected_indexes[0]).into())
127
119
}
128
120
ButtplugMessageSpecVersion::Version4 => {
129
121
ButtplugServerMessageVariant::V4(list.clone().into())
+27
-10
crates/buttplug_server_device_config/src/device_config_file/feature.rs
+27
-10
crates/buttplug_server_device_config/src/device_config_file/feature.rs
···
11
11
ServerDeviceFeatureOutputPositionWithDurationProperties,
12
12
ServerDeviceFeatureOutputValueProperties,
13
13
};
14
-
use buttplug_core::{message::InputCommandType, util::range_serialize::{range_serialize, range_sequence_serialize, option_range_serialize}};
14
+
use buttplug_core::{
15
+
message::InputCommandType,
16
+
util::range_serialize::{option_range_serialize, range_sequence_serialize, range_serialize},
17
+
};
15
18
use getset::{CopyGetters, Getters, MutGetters, Setters};
16
19
use serde::{Deserialize, Serialize};
17
20
use uuid::Uuid;
···
31
34
32
35
#[derive(Serialize, Deserialize, Clone, Debug)]
33
36
struct BaseDeviceFeatureOutputValueProperties {
34
-
#[serde(serialize_with="range_serialize")]
37
+
#[serde(serialize_with = "range_serialize")]
35
38
value: RangeInclusive<i32>,
36
39
}
37
40
···
43
46
44
47
#[derive(Serialize, Deserialize, Clone, Debug)]
45
48
struct BaseDeviceFeatureOutputPositionProperties {
46
-
#[serde(serialize_with="range_serialize")]
49
+
#[serde(serialize_with = "range_serialize")]
47
50
value: RangeInclusive<i32>,
48
51
}
49
52
···
57
60
58
61
#[derive(Serialize, Deserialize, Clone, Debug)]
59
62
struct BaseDeviceFeatureOutputPositionWithDurationProperties {
60
-
#[serde(serialize_with="range_serialize")]
63
+
#[serde(serialize_with = "range_serialize")]
61
64
position: RangeInclusive<i32>,
62
-
#[serde(serialize_with="range_serialize")]
65
+
#[serde(serialize_with = "range_serialize")]
63
66
duration: RangeInclusive<i32>,
64
67
}
65
68
···
134
137
135
138
#[derive(Serialize, Deserialize, Clone, Debug)]
136
139
struct UserDeviceFeatureOutputValueProperties {
137
-
#[serde(skip_serializing_if = "Option::is_none", serialize_with="option_range_serialize")]
140
+
#[serde(
141
+
skip_serializing_if = "Option::is_none",
142
+
serialize_with = "option_range_serialize"
143
+
)]
138
144
value: Option<RangeInclusive<u32>>,
139
145
#[serde(default)]
140
146
disabled: bool,
···
164
170
165
171
#[derive(Serialize, Deserialize, Clone, Debug)]
166
172
struct UserDeviceFeatureOutputPositionProperties {
167
-
#[serde(skip_serializing_if = "Option::is_none", serialize_with="option_range_serialize")]
173
+
#[serde(
174
+
skip_serializing_if = "Option::is_none",
175
+
serialize_with = "option_range_serialize"
176
+
)]
168
177
value: Option<RangeInclusive<u32>>,
169
178
#[serde(default)]
170
179
disabled: bool,
···
200
209
201
210
#[derive(Serialize, Deserialize, Clone, Debug)]
202
211
struct UserDeviceFeatureOutputPositionWithDurationProperties {
203
-
#[serde(skip_serializing_if = "Option::is_none", serialize_with="option_range_serialize")]
212
+
#[serde(
213
+
skip_serializing_if = "Option::is_none",
214
+
serialize_with = "option_range_serialize"
215
+
)]
204
216
position: Option<RangeInclusive<u32>>,
205
-
#[serde(skip_serializing_if = "Option::is_none", serialize_with="option_range_serialize")]
217
+
#[serde(
218
+
skip_serializing_if = "Option::is_none",
219
+
serialize_with = "option_range_serialize"
220
+
)]
206
221
duration: Option<RangeInclusive<u32>>,
207
222
#[serde(default)]
208
223
disabled: bool,
···
485
500
fn from(value: &ServerDeviceFeature) -> Self {
486
501
Self {
487
502
id: value.id(),
488
-
base_id: value.base_id().expect(&format!("Should have base id: {:?}", value)),
503
+
base_id: value
504
+
.base_id()
505
+
.expect(&format!("Should have base id: {:?}", value)),
489
506
output: value.output().as_ref().map(|x| x.into()),
490
507
}
491
508
}
+11
-10
crates/buttplug_server_device_config/src/device_config_file/mod.rs
+11
-10
crates/buttplug_server_device_config/src/device_config_file/mod.rs
···
13
13
14
14
use base::BaseConfigFile;
15
15
16
-
use crate::{device_config_file::{
16
+
use crate::device_config_file::{
17
17
protocol::ProtocolDefinition,
18
18
user::{UserConfigDefinition, UserConfigFile, UserDeviceConfigPair},
19
-
}};
19
+
};
20
20
21
21
use super::{BaseDeviceIdentifier, DeviceConfigurationManager, DeviceConfigurationManagerBuilder};
22
22
use buttplug_core::{
···
25
25
};
26
26
use dashmap::DashMap;
27
27
use getset::CopyGetters;
28
-
use serde::{
29
-
Deserialize,
30
-
Serialize
31
-
};
28
+
use serde::{Deserialize, Serialize};
32
29
use std::fmt::Display;
33
30
34
31
pub static DEVICE_CONFIGURATION_JSON: &str =
···
191
188
//let ident = BaseDeviceIdentifier::new(user_device_config_pair.identifier().protocol(), &None);
192
189
// Use device UUID instead of identifier to match here, otherwise we have to do really weird stuff with identifier hashes.
193
190
// TODO How do we deal with user configs derived from default here? We don't handle loading this correctly?
194
-
if let Some(base_config) = base_dcm.base_device_definitions().iter().find(|x| x.1.id() == user_device_config_pair.config().base_id())
191
+
if let Some(base_config) = base_dcm
192
+
.base_device_definitions()
193
+
.iter()
194
+
.find(|x| x.1.id() == user_device_config_pair.config().base_id())
195
195
{
196
196
if let Ok(loaded_user_config) = user_device_config_pair
197
197
.config()
198
-
.build_from_base_definition(base_config.1) {
199
-
if let Err(e) =
200
-
dcm_builder.user_device_definition(user_device_config_pair.identifier(), &loaded_user_config)
198
+
.build_from_base_definition(base_config.1)
199
+
{
200
+
if let Err(e) = dcm_builder
201
+
.user_device_definition(user_device_config_pair.identifier(), &loaded_user_config)
201
202
{
202
203
error!(
203
204
"Device definition not valid, skipping:\n{:?}\n{:?}",
-1
crates/buttplug_server_device_config/src/device_config_file/protocol.rs
-1
crates/buttplug_server_device_config/src/device_config_file/protocol.rs
+8
-2
crates/buttplug_server_device_config/src/device_config_manager.rs
+8
-2
crates/buttplug_server_device_config/src/device_config_manager.rs
···
189
189
}
190
190
}
191
191
192
-
pub fn add_user_device_definition(&self, identifier: &UserDeviceIdentifier, definition: &ServerDeviceDefinition) {
192
+
pub fn add_user_device_definition(
193
+
&self,
194
+
identifier: &UserDeviceIdentifier,
195
+
definition: &ServerDeviceDefinition,
196
+
) {
193
197
// TODO we should actually check validity of the definition we're adding here, i.e. does it have
194
198
// a base id, is that ID in our base selections, etc...
195
-
self.user_device_definitions.insert(identifier.clone(), definition.clone());
199
+
self
200
+
.user_device_definitions
201
+
.insert(identifier.clone(), definition.clone());
196
202
}
197
203
198
204
pub fn remove_user_device_definition(&self, identifier: &UserDeviceIdentifier) {
+12
-3
crates/buttplug_server_device_config/src/device_definitions.rs
+12
-3
crates/buttplug_server_device_config/src/device_definitions.rs
···
56
56
value.base_id = Some(value.id);
57
57
value.id = id;
58
58
if with_features {
59
-
value.features = value.features().iter().map(|x| x.as_new_user_feature()).collect();
59
+
value.features = value
60
+
.features()
61
+
.iter()
62
+
.map(|x| x.as_new_user_feature())
63
+
.collect();
60
64
} else {
61
-
value.features = vec!();
65
+
value.features = vec![];
62
66
}
63
67
ServerDeviceDefinitionBuilder { def: value }
64
68
}
···
113
117
}
114
118
115
119
pub fn replace_feature(&mut self, feature: &ServerDeviceFeature) -> &mut Self {
116
-
if let Some(f) = self.def.features.iter_mut().find(|x| x.id() == feature.id()) {
120
+
if let Some(f) = self
121
+
.def
122
+
.features
123
+
.iter_mut()
124
+
.find(|x| x.id() == feature.id())
125
+
{
117
126
*f = feature.clone();
118
127
}
119
128
self
+4
-3
crates/buttplug_server_hwmgr_hid/src/hidapi_async.rs
+4
-3
crates/buttplug_server_hwmgr_hid/src/hidapi_async.rs
···
71
71
72
72
// Wait for the reader thread to finish
73
73
if let Some(jh) = guard.read_thread.take()
74
-
&& jh.join().is_ok() {
75
-
info!("device read thread joined")
76
-
}
74
+
&& jh.join().is_ok()
75
+
{
76
+
info!("device read thread joined")
77
+
}
77
78
} else {
78
79
//error!("Failed to take lock on device");
79
80
}
+49
-44
crates/buttplug_server_hwmgr_lovense_dongle/src/lovense_dongle_state_machine.rs
+49
-44
crates/buttplug_server_hwmgr_lovense_dongle/src/lovense_dongle_state_machine.rs
···
348
348
IncomingMessage::Dongle(device_msg) => match device_msg.func {
349
349
LovenseDongleMessageFunc::IncomingStatus => {
350
350
if let Some(incoming_data) = device_msg.data
351
-
&& let Some(status) = incoming_data.status {
352
-
match status {
353
-
LovenseDongleResultCode::DeviceConnectSuccess => {
354
-
info!("Lovense dongle already connected to a device, registering in system.");
355
-
return Some(Box::new(LovenseDongleDeviceLoop::new(
356
-
self.hub,
357
-
incoming_data
358
-
.id
359
-
.expect("Dongle protocol shouldn't change, message always has ID."),
360
-
)));
361
-
}
362
-
_ => warn!(
363
-
"LovenseDongleIdle State cannot handle dongle status {:?}",
364
-
status
365
-
),
351
+
&& let Some(status) = incoming_data.status
352
+
{
353
+
match status {
354
+
LovenseDongleResultCode::DeviceConnectSuccess => {
355
+
info!("Lovense dongle already connected to a device, registering in system.");
356
+
return Some(Box::new(LovenseDongleDeviceLoop::new(
357
+
self.hub,
358
+
incoming_data
359
+
.id
360
+
.expect("Dongle protocol shouldn't change, message always has ID."),
361
+
)));
366
362
}
363
+
_ => warn!(
364
+
"LovenseDongleIdle State cannot handle dongle status {:?}",
365
+
status
366
+
),
367
367
}
368
+
}
368
369
}
369
370
LovenseDongleMessageFunc::Search => {
370
371
if let Some(result) = device_msg.result {
···
463
464
match device_msg.func {
464
465
LovenseDongleMessageFunc::IncomingStatus => {
465
466
if let Some(incoming_data) = device_msg.data
466
-
&& let Some(status) = incoming_data.status {
467
-
match status {
468
-
LovenseDongleResultCode::DeviceConnectSuccess => {
469
-
info!("Lovense dongle already connected to a device, registering in system.");
470
-
return Some(Box::new(LovenseDongleDeviceLoop::new(
471
-
self.hub,
472
-
incoming_data
473
-
.id
474
-
.expect("Dongle protocol shouldn't change, message always has ID."),
475
-
)));
476
-
}
477
-
_ => {
478
-
warn!(
479
-
"LovenseDongleScanning state cannot handle dongle status {:?}",
480
-
status
481
-
)
482
-
}
467
+
&& let Some(status) = incoming_data.status
468
+
{
469
+
match status {
470
+
LovenseDongleResultCode::DeviceConnectSuccess => {
471
+
info!("Lovense dongle already connected to a device, registering in system.");
472
+
return Some(Box::new(LovenseDongleDeviceLoop::new(
473
+
self.hub,
474
+
incoming_data
475
+
.id
476
+
.expect("Dongle protocol shouldn't change, message always has ID."),
477
+
)));
478
+
}
479
+
_ => {
480
+
warn!(
481
+
"LovenseDongleScanning state cannot handle dongle status {:?}",
482
+
status
483
+
)
483
484
}
484
485
}
486
+
}
485
487
}
486
488
LovenseDongleMessageFunc::Search => {
487
489
if let Some(result) = device_msg.result {
···
584
586
IncomingMessage::Dongle(device_msg) => match device_msg.func {
585
587
LovenseDongleMessageFunc::Search => {
586
588
if let Some(result) = device_msg.result
587
-
&& result == LovenseDongleResultCode::SearchStopped {
588
-
self.hub.set_scanning_status(false);
589
-
break;
590
-
}
589
+
&& result == LovenseDongleResultCode::SearchStopped
590
+
{
591
+
self.hub.set_scanning_status(false);
592
+
break;
593
+
}
591
594
}
592
595
LovenseDongleMessageFunc::StopSearch => {
593
596
if let Some(result) = device_msg.result
594
-
&& result == LovenseDongleResultCode::CommandSuccess {
595
-
// Just log and continue here.
596
-
debug!("Lovense dongle stop search command succeeded.");
597
-
}
597
+
&& result == LovenseDongleResultCode::CommandSuccess
598
+
{
599
+
// Just log and continue here.
600
+
debug!("Lovense dongle stop search command succeeded.");
601
+
}
598
602
}
599
603
_ => warn!(
600
604
"LovenseDongleStopScanningAndConnect cannot handle dongle function {:?}",
···
652
656
match dongle_msg.func {
653
657
LovenseDongleMessageFunc::IncomingStatus => {
654
658
if let Some(data) = dongle_msg.data
655
-
&& data.status == Some(LovenseDongleResultCode::DeviceDisconnected) {
656
-
// Device disconnected, emit and return to idle.
657
-
return Some(Box::new(LovenseDongleIdle::new(self.hub)));
658
-
}
659
+
&& data.status == Some(LovenseDongleResultCode::DeviceDisconnected)
660
+
{
661
+
// Device disconnected, emit and return to idle.
662
+
return Some(Box::new(LovenseDongleIdle::new(self.hub)));
663
+
}
659
664
}
660
665
_ => {
661
666
if device_read_sender.send(dongle_msg).await.is_err() {
+12
-10
crates/buttplug_server_hwmgr_serial/src/serialport_hardware.rs
+12
-10
crates/buttplug_server_hwmgr_serial/src/serialport_hardware.rs
···
185
185
let mut port_def = None;
186
186
for specifier in specifiers {
187
187
if let ProtocolCommunicationSpecifier::Serial(serial) = specifier
188
-
&& port_info.port_name == *serial.port() {
189
-
port_def = Some(serial.clone());
190
-
break;
191
-
}
188
+
&& port_info.port_name == *serial.port()
189
+
{
190
+
port_def = Some(serial.clone());
191
+
break;
192
+
}
192
193
}
193
194
let port_def = port_def.expect("We'll always have a port definition by this point");
194
195
···
251
252
&& let Err(err) = event_stream_clone.send(HardwareEvent::Disconnected(format!(
252
253
"{:?}",
253
254
&port_name_clone
254
-
))) {
255
-
error!(
256
-
"Cannot send notification, device object disappeared: {:?}",
257
-
err
258
-
);
259
-
}
255
+
)))
256
+
{
257
+
error!(
258
+
"Cannot send notification, device object disappeared: {:?}",
259
+
err
260
+
);
261
+
}
260
262
})
261
263
.expect("Should always be able to create thread");
262
264
+3
-1
crates/buttplug_tests/tests/util/device_test/client/client_v4/mod.rs
+3
-1
crates/buttplug_tests/tests/util/device_test/client/client_v4/mod.rs
···
94
94
.map(|(_, x)| x)
95
95
.collect();
96
96
let f = rotate_features[cmd.index() as usize].clone();
97
-
f.rotate(ClientDeviceCommandValue::Float(cmd.speed() * if cmd.clockwise() { 1f64 } else { -1f64 }))
97
+
f.rotate(ClientDeviceCommandValue::Float(
98
+
cmd.speed() * if cmd.clockwise() { 1f64 } else { -1f64 },
99
+
))
98
100
})
99
101
.collect();
100
102
futures::future::try_join_all(fut_vec).await.unwrap();
+5
-3
crates/intiface_engine/src/bin/main.rs
+5
-3
crates/intiface_engine/src/bin/main.rs
···
162
162
#[getset(get_copy = "pub")]
163
163
crash_main_thread: bool,
164
164
165
-
166
165
#[allow(dead_code)]
167
166
#[cfg(debug_assertions)]
168
167
/// crash the task thread (for testing logging/reporting)
···
222
221
match fs::read_to_string(userdeviceconfig) {
223
222
Ok(cfg) => {
224
223
builder.user_device_config_json(&cfg);
225
-
},
224
+
}
226
225
Err(err) => {
227
-
warn!("Error opening user device configuration, ignoring and creating new file: {:?}", err);
226
+
warn!(
227
+
"Error opening user device configuration, ignoring and creating new file: {:?}",
228
+
err
229
+
);
228
230
}
229
231
};
230
232
}
+4
-1
crates/intiface_engine/src/buttplug_server.rs
+4
-1
crates/intiface_engine/src/buttplug_server.rs
···
5
5
IntifaceEngineError, IntifaceError, remote_server::ButtplugRemoteServerEvent,
6
6
};
7
7
use buttplug_server::{
8
-
connector::ButtplugRemoteServerConnector, device::{ServerDeviceManager, ServerDeviceManagerBuilder}, message::serializer::ButtplugServerJSONSerializer, ButtplugServer, ButtplugServerBuilder
8
+
ButtplugServer, ButtplugServerBuilder,
9
+
connector::ButtplugRemoteServerConnector,
10
+
device::{ServerDeviceManager, ServerDeviceManagerBuilder},
11
+
message::serializer::ButtplugServerJSONSerializer,
9
12
};
10
13
use buttplug_server_device_config::{DeviceConfigurationManager, load_protocol_configs};
11
14
use buttplug_server_hwmgr_btleplug::BtlePlugCommunicationManagerBuilder;
+10
-2
crates/intiface_engine/src/engine.rs
+10
-2
crates/intiface_engine/src/engine.rs
···
1
1
use crate::{
2
-
ButtplugRemoteServer, ButtplugRepeater, backdoor_server::BackdoorServer, buttplug_server::{reset_buttplug_server, run_server, setup_buttplug_server}, error::IntifaceEngineError, frontend::{
2
+
ButtplugRemoteServer, ButtplugRepeater,
3
+
backdoor_server::BackdoorServer,
4
+
buttplug_server::{reset_buttplug_server, run_server, setup_buttplug_server},
5
+
error::IntifaceEngineError,
6
+
frontend::{
3
7
Frontend, frontend_external_event_loop, frontend_server_event_loop,
4
8
process_messages::EngineMessage,
5
-
}, mdns::IntifaceMdns, options::EngineOptions, remote_server::ButtplugRemoteServerEvent, rest_server::IntifaceRestServer
9
+
},
10
+
mdns::IntifaceMdns,
11
+
options::EngineOptions,
12
+
remote_server::ButtplugRemoteServerEvent,
13
+
rest_server::IntifaceRestServer,
6
14
};
7
15
8
16
use buttplug_server_device_config::{DeviceConfigurationManager, save_user_config};
-1
crates/intiface_engine/src/lib.rs
-1
crates/intiface_engine/src/lib.rs
+1
-1
crates/intiface_engine/src/options.rs
+1
-1
crates/intiface_engine/src/options.rs
+23
-9
crates/intiface_engine/src/rest_server.rs
+23
-9
crates/intiface_engine/src/rest_server.rs
···
1
-
use std::{collections::BTreeMap, convert::Infallible, io, net::SocketAddr, str::FromStr, sync::Arc};
1
+
use std::{
2
+
collections::BTreeMap, convert::Infallible, io, net::SocketAddr, str::FromStr, sync::Arc,
3
+
};
2
4
3
5
use axum::{
4
-
extract::{rejection::JsonRejection, Path, State}, http::StatusCode, response::{sse::{Event, KeepAlive}, IntoResponse, Response, Sse}, routing::{get, put}, Json, Router
6
+
Json, Router,
7
+
extract::{Path, State, rejection::JsonRejection},
8
+
http::StatusCode,
9
+
response::{
10
+
IntoResponse, Response, Sse,
11
+
sse::{Event, KeepAlive},
12
+
},
13
+
routing::{get, put},
5
14
};
6
15
use buttplug_client::{
7
-
device::{ClientDeviceFeature, ClientDeviceOutputCommand}, ButtplugClient, ButtplugClientDevice, ButtplugClientError, ButtplugClientEvent
16
+
ButtplugClient, ButtplugClientDevice, ButtplugClientError, ButtplugClientEvent,
17
+
device::{ClientDeviceFeature, ClientDeviceOutputCommand},
8
18
};
9
19
use buttplug_client_in_process::ButtplugInProcessClientConnectorBuilder;
10
20
use buttplug_core::message::{DeviceFeature, OutputType};
···
102
112
fn get_feature(
103
113
client: &ButtplugClient,
104
114
index: u32,
105
-
feature_index: u32
115
+
feature_index: u32,
106
116
) -> Result<ClientDeviceFeature, IntifaceRestError> {
107
117
get_device(client, index)?
108
118
.device_features()
···
152
162
State(client): State<Arc<ButtplugClient>>,
153
163
Path((index, command, level)): Path<(u32, OutputType, f64)>,
154
164
) -> Result<(), IntifaceRestError> {
155
-
let cmd = ClientDeviceOutputCommand::from_command_value_float(command, level)
165
+
let cmd = ClientDeviceOutputCommand::from_command_value_float(command, level)
156
166
.map_err(|e| IntifaceRestError::ButtplugClientError(e))?;
157
167
158
168
Ok(
···
167
177
State(client): State<Arc<ButtplugClient>>,
168
178
Path((index, feature_index, command, level)): Path<(u32, u32, OutputType, f64)>,
169
179
) -> Result<(), IntifaceRestError> {
170
-
let cmd = ClientDeviceOutputCommand::from_command_value_float(command, level)
180
+
let cmd = ClientDeviceOutputCommand::from_command_value_float(command, level)
171
181
.map_err(|e| IntifaceRestError::ButtplugClientError(e))?;
172
182
173
183
Ok(
···
250
260
Ok(())
251
261
}
252
262
253
-
async fn server_sse(State(client): State<Arc<ButtplugClient>>,) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
254
-
let stream = client.event_stream().map(|e| Ok(Event::default().data(format!("{:?}", e))));
263
+
async fn server_sse(
264
+
State(client): State<Arc<ButtplugClient>>,
265
+
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
266
+
let stream = client
267
+
.event_stream()
268
+
.map(|e| Ok(Event::default().data(format!("{:?}", e))));
255
269
256
-
Sse::new(stream).keep_alive(KeepAlive::default())
270
+
Sse::new(stream).keep_alive(KeepAlive::default())
257
271
}
258
272
259
273
impl IntifaceRestServer {
-1
examples/src/bin/device_control.rs
-1
examples/src/bin/device_control.rs