···22use buttplug_core::errors::ButtplugDeviceError;
33use dashmap::DashMap;
44use getset::Getters;
55+use uuid::Uuid;
56use std::{
67 collections::HashMap,
78 fmt::{self, Debug},
89};
9101010-use crate::{BaseDeviceIdentifier, ProtocolCommunicationSpecifier, ServerDeviceDefinition, UserDeviceIdentifier};
1111+use crate::{BaseDeviceIdentifier, ButtplugDeviceConfigError, ProtocolCommunicationSpecifier, ServerDeviceDefinition, ServerDeviceDefinitionBuilder, UserDeviceIdentifier};
11121213#[derive(Default, Clone)]
1314pub struct DeviceConfigurationManagerBuilder {
···3132 self
3233 }
33343434- pub fn protocol_features(
3535+ pub fn base_device_definition(
3536 &mut self,
3637 identifier: &BaseDeviceIdentifier,
3738 features: &ServerDeviceDefinition,
···5556 self
5657 }
57585858- pub fn user_protocol_features(
5959+ pub fn user_device_definition(
5960 &mut self,
6061 identifier: &UserDeviceIdentifier,
6161- features: &ServerDeviceDefinition,
6262- ) -> &mut Self {
6363- if let Some((_, base_definition)) = self
6262+ device_definition: &ServerDeviceDefinition,
6363+ ) -> Result<&mut Self, ButtplugDeviceConfigError> {
6464+ if self
6465 .base_device_definitions
6566 .iter()
6666- .find(|(_, x)| x.id() == features.base_id())
6767+ .find(|(_, x)| x.id() == device_definition.base_id().unwrap_or_default())
6868+ .is_some()
6769 {
6870 self.user_device_definitions.insert(
6971 identifier.clone(),
7070- ServerDeviceDefinition::new(base_definition, features),
7272+ device_definition.clone()
7173 );
7474+ Ok(self)
7275 } else {
7376 error!(
7474- "Cannot find protocol with base id {} for user id {}",
7575- features.base_id(),
7676- features.id()
7777- )
7777+ "Cannot find protocol with base id {:?} for user id {}",
7878+ device_definition.base_id(),
7979+ device_definition.id()
8080+ );
8181+ Err(ButtplugDeviceConfigError::BaseIdNotFound(device_definition.id()))
7882 }
7979- self
8383+8084 }
81858286 pub fn finish(&mut self) -> Result<DeviceConfigurationManager, ButtplugDeviceError> {
···85898690 // Add all the defaults first, they won't have parent attributes.
8791 for (ident, attr) in &self.base_device_definitions {
8888- /*
8989- for feature in attr.features() {
9090- if let Err(e) = feature.is_valid() {
9191- error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
9292- continue;
9393- }
9494- }
9595- */
9692 attribute_tree_map.insert(ident.clone(), attr.clone());
9793 }
98949995 let user_attribute_tree_map = DashMap::new();
10096 // Finally, add in user configurations, which will have an address.
10197 for kv in &self.user_device_definitions {
102102- let (ident, attr) = (kv.key(), kv.value());
103103- for feature in attr.features() {
104104- if let Err(e) = feature.is_valid() {
105105- error!("Feature {attr:?} for ident {ident:?} is not valid, skipping addition: {e:?}");
106106- continue;
107107- }
108108- }
10998 user_attribute_tree_map.insert(kv.key().clone(), kv.value().clone());
11099 }
111100···131120/// information about what commands can be sent to the device (Vibrate, Rotate, etc...), and the
132121/// parameters for those commands (number of power levels, stroke distances, etc...).
133122#[derive(Getters)]
134134-#[getset(get = "pub")]
123123+#[getset(get = "pub(crate)")]
135124pub struct DeviceConfigurationManager {
136125 /// Communication specifiers from the base device config, mapped from protocol name to vector of
137126 /// specifiers. Should not change/update during a session.
···192181 }
193182 }
194183195195- pub fn add_user_device_definition(
196196- &self,
197197- identifier: &UserDeviceIdentifier,
198198- definition: &ServerDeviceDefinition,
199199- ) -> Result<(), ButtplugDeviceError> {
200200- //self.protocol_map.contains_key(identifier.protocol());
201201- // Check validity of device
202202- let mut index = definition.user_config().index();
203203- let indexes: Vec<u32> = self.user_device_definitions().iter().map(|x| x.value().user_config().index()).collect();
204204- // If we just added 1 to the maximum value of the current indexes, someone decides to set an
205205- // index to u32::MAX-1, then we'd have a problem. This is kind of a shit solution but it'll work
206206- // quickly for anyone that's not actively fucking with us by manually playing with user config files.
207207- while indexes.contains(&index) {
208208- index = index.wrapping_add(1);
209209- }
210210- let mut def = definition.clone();
211211- *def.user_device_mut().user_config_mut().index_mut() = index;
212212- self
213213- .user_device_definitions
214214- .entry(identifier.clone())
215215- .insert(def);
216216- Ok(())
217217- }
218218-219184 pub fn remove_user_device_definition(&self, identifier: &UserDeviceIdentifier) {
220185 self.user_device_definitions.remove(identifier);
221186 }
···225190 if self
226191 .user_device_definitions
227192 .iter()
228228- .any(|kv| kv.key().address() == address && kv.value().user_config().deny())
193193+ .any(|kv| kv.key().address() == address && kv.value().deny())
229194 {
230195 // If device is outright denied, deny
231196 info!(
···236201 } else if self
237202 .user_device_definitions
238203 .iter()
239239- .any(|kv| kv.value().user_config().allow())
204204+ .any(|kv| kv.value().allow())
240205 && !self
241206 .user_device_definitions
242207 .iter()
243243- .any(|kv| kv.key().address() == address && kv.value().user_config().allow())
208208+ .any(|kv| kv.key().address() == address && kv.value().allow())
244209 {
245210 // If device is not on allow list and allow list isn't empty, deny
246211 info!(
···256221 fn device_index(&self, identifier: &UserDeviceIdentifier) -> u32 {
257222 // See if we have a reserved or reusable device index here.
258223 if let Some(config) = self.user_device_definitions.get(identifier) {
259259- let index = config.user_config().index();
224224+ let index = config.index();
260225 debug!("Found index {index} for device {identifier:?}");
261226 return index;
262227 }
···264229 let current_indexes: Vec<u32> = self
265230 .user_device_definitions
266231 .iter()
267267- .map(|x| x.user_config().index())
232232+ .map(|x| x.index())
268233 .collect();
269234270235 // Someone is gonna make a max device index in their config file just to fuck with me, therefore
···280245 index
281246 }
282247283283- /// Provides read-only access to the internal protocol/identifier map. Mainly
284284- /// used for WebBluetooth filter construction, but could also be handy for
285285- /// listing capabilities in UI, etc.
286286- pub fn protocol_device_configurations(
287287- &self,
288288- ) -> HashMap<String, Vec<ProtocolCommunicationSpecifier>> {
289289- self.base_communication_specifiers.clone()
290290- }
291291-292292- pub fn device_definition(&self, identifier: &UserDeviceIdentifier) -> Option<DeviceDefinition> {
293293- let features = if let Some(attrs) = self.user_device_definitions.get(identifier) {
248248+ pub fn device_definition(&self, identifier: &UserDeviceIdentifier) -> Option<ServerDeviceDefinition> {
249249+ let features = if let Some(definition) = self.user_device_definitions.get(identifier) {
294250 debug!("User device config found for {:?}", identifier);
295295- attrs.clone()
296296- } else if let Some(attrs) = self.base_device_definitions.get(&BaseDeviceIdentifier::new(
251251+ definition.clone()
252252+ } else if let Some(definition) = self.base_device_definitions.get(&BaseDeviceIdentifier::new(
297253 identifier.protocol(),
298254 identifier.identifier(),
299255 )) {
300256 debug!(
301301- "Protocol + Identifier device config found for {:?}",
257257+ "Protocol + Identifier device config found for {:?}, creating new user device from configuration",
302258 identifier
303259 );
304304- DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
305305- } else if let Some(attrs) = self
260260+ let mut builder = ServerDeviceDefinitionBuilder::from_base(definition, Uuid::new_v4());
261261+ builder.index(self.device_index(identifier)).finish()
262262+ } else if let Some(definition) = self
306263 .base_device_definitions
307264 .get(&BaseDeviceIdentifier::new(identifier.protocol(), &None))
308265 {
309309- debug!("Protocol device config found for {:?}", identifier);
310310- DeviceDefinition::new_from_base_definition(attrs, self.device_index(identifier))
266266+ debug!("Protocol device config found for {:?}, creating new user device from protocol defaults", identifier);
267267+ let mut builder = ServerDeviceDefinitionBuilder::from_base(definition, Uuid::new_v4());
268268+ builder.index(self.device_index(identifier)).finish()
311269 } else {
312270 return None;
313271 };
···325283326284 Some(features)
327285 }
286286+328287}
···141141extern crate log;
142142143143mod device_config_file;
144144-pub use device_config_file::{load_protocol_configs, save_user_config};
144144+pub use device_config_file::{load_protocol_configs}; //, save_user_config};
145145mod device_config_manager;
146146pub use device_config_manager::*;
147147mod specifier;
···154154pub use device_feature::*;
155155mod endpoint;
156156pub use endpoint::*;
157157+use uuid::Uuid;
157158158159159159-use std::ops::RangeInclusive;
160160use thiserror::Error;
161161162162#[derive(Error, Debug)]
163163-pub enum ButtplugDeviceConfigError<T> {
163163+pub enum ButtplugDeviceConfigError {
164164 /// Conversion to client type not possible with requested property type
165165 #[error("Conversion of {0} to client type not possible with requested property type")]
166166 InvalidOutputTypeConversion(String),
167167 /// User set range exceeds bounds of possible configuration range
168168- #[error("User set range {0} exceeds bounds of possible configuration range {1}")]
169169- InvalidUserRange(RangeInclusive<T>, RangeInclusive<T>),
168168+ #[error("User set range exceeds bounds of possible configuration range")]
169169+ InvalidUserRange,
170170 /// Base range required
171171 #[error("Base range required for all feature outputs")]
172172 BaseRangeRequired,
173173+ /// Base ID not found, cannot match user device/feature to a base device/feature
174174+ #[error("Device definition with base id {0} not found")]
175175+ BaseIdNotFound(Uuid),
176176+ #[error("Feature vectors between base and user device definitions do not match")]
177177+ UserFeatureMismatch
173178}