private void TryAddActionSet(string actionSetName) { Logger.Trace($"Registering action set '{actionSetName}'"); if (_actionSetNames.Contains(actionSetName)) { throw new InvalidOperationException($"Action set '{actionSetName}' has already been registered"); } try { _actionSetNames.Add(actionSetName); _actionSetHandles.Add(OpenVRWrapper.GetActionSetHandle(actionSetName)); } catch (OpenVRInputException ex) { Logger.Error($"An unexpected OpenVR error occurred when fetching handle for action set '{actionSetName}'."); Logger.Error(ex); } catch (NullReferenceException ex) { Logger.Error($"A null reference exception occured when fetching handle for action set '{actionSetName}'. This is most likely caused by an internal OpenVR issue. Action has been disabled."); Logger.Error(ex); } catch (Exception ex) { Logger.Error($"An unexpected error occurred when fetching handle for action set '{actionSetName}'."); Logger.Error(ex); } }
public void Initialize(string actionManifestPath) { if (initialized) { throw new InvalidOperationException("Already initialized"); } Logger.Info($"Initializing {nameof(OpenVRActionManager)}"); _actionManifestPath = actionManifestPath; CombineAndWriteManifest(); OpenVRWrapper.SetActionManifestPath(actionManifestPath); IEnumerable <string> actionSetNames = _actions.Values.Select(action => action.GetActionSetName()).Distinct(); foreach (string actionSetName in actionSetNames) { TryAddActionSet(actionSetName); } foreach (var action in _actions.Values.ToList()) { TryUpdateHandle(action); } initialized = true; }
private void TryUpdateHandle(OVRAction action) { Logger.Trace($"Updating handle for action '{action.name}' ({action.id})"); try { action.UpdateHandle(); } catch (OpenVRInputException ex) { Logger.Error($"An unexpected OpenVR error occurred when fetching handle for action '{action.name}'. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } catch (NullReferenceException ex) { Logger.Error($"A null reference exception occurred when fetching handle for action '{action.name}'. This is most likely caused by an internal OpenVR issue. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } catch (Exception ex) { Logger.Error($"An unexpected error occurred when fetching handle for action '{action.name}'. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } }
private List <ManifestDefaultBinding> CombineAndWriteBindings(int manifestVersion) { string bindingsFolder = Path.Combine(Directory.GetCurrentDirectory(), "DynamicOpenVR", "Bindings"); if (!Directory.Exists(bindingsFolder)) { Logger.Warn("Bindings folder does not exist!"); return(new List <ManifestDefaultBinding>()); } Logger.Trace($"Reading default bindings from '{bindingsFolder}'"); string[] bindingFiles = Directory.GetFiles(bindingsFolder); var defaultBindings = new List <DefaultBinding>(); foreach (string bindingFile in bindingFiles) { try { Logger.Trace($"Reading '{bindingFile}'"); using (var reader = new StreamReader(bindingFile)) { defaultBindings.Add(JsonConvert.DeserializeObject <DefaultBinding>(reader.ReadToEnd())); } } catch (Exception ex) { Logger.Error($"An error of type {ex.GetType().FullName} occured when trying to parse '{bindingFile}': {ex.Message}"); } } var combinedBindings = new List <ManifestDefaultBinding>(); foreach (string controllerType in defaultBindings.Select(b => b.controllerType).Distinct()) { var defaultBinding = new DefaultBinding { actionManifestVersion = manifestVersion, name = "Default Beat Saber Bindings", description = "Action bindings for Beat Saber.", controllerType = controllerType, category = "steamvr_input", bindings = MergeBindings(defaultBindings.Where(b => b.controllerType == controllerType)) }; string fileName = $"default_bindings_{defaultBinding.controllerType}.json"; combinedBindings.Add(new ManifestDefaultBinding { ControllerType = controllerType, BindingUrl = fileName }); using (StreamWriter writer = new StreamWriter(Path.Combine("DynamicOpenVR", fileName))) { writer.WriteLine(JsonConvert.SerializeObject(defaultBinding, Formatting.Indented)); } } return(combinedBindings); }
public void Update() { if (!initialized) { return; // do nothing until initialized } if (_actionSetHandles != null) { OpenVRWrapper.UpdateActionState(_actionSetHandles); } foreach (var action in _actions.Values.OfType <OVRInput>().ToList()) { try { action.UpdateData(); } catch (OpenVRInputException ex) { Logger.Error($"An unexpected OpenVR error occurred when fetching data for action '{action.name}'. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } catch (NullReferenceException ex) { Logger.Error($"A null reference exception occurred when fetching data for action '{action.name}'. This is most likely caused by an internal OpenVR issue. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } catch (Exception ex) { Logger.Error($"An unexpected error occurred when fetching data for action '{action.name}'. Action has been disabled."); Logger.Error(ex); DeregisterAction(action); } } }
public void RegisterAction(OVRAction action) { if (_actions.ContainsKey(action.id)) { throw new InvalidOperationException("Action was already registered."); } Logger.Trace($"Registering action '{action.name}' ({action.id})"); _actions.Add(action.id, action); if (initialized) { string actionSetName = action.GetActionSetName(); if (!_actionSetNames.Contains(actionSetName)) { TryAddActionSet(actionSetName); } TryUpdateHandle(action); } }
private List <Dictionary <string, string> > CombineLocalizations(IEnumerable <ActionManifest> manifests) { var combinedLocalizations = new Dictionary <string, Dictionary <string, string> >(); foreach (var manifest in manifests) { foreach (var language in manifest.localization) { if (!language.ContainsKey("language_tag")) { continue; } if (!combinedLocalizations.ContainsKey(language["language_tag"])) { combinedLocalizations.Add(language["language_tag"], new Dictionary <string, string>() { { "language_tag", language["language_tag"] } }); } foreach (var kvp in language.Where(kvp => kvp.Key != "language_tag")) { if (combinedLocalizations.ContainsKey(kvp.Key)) { Logger.Warn($"Duplicate entry '{kvp.Key}'"); } else { combinedLocalizations[language["language_tag"]].Add(kvp.Key, kvp.Value); } } } } return(combinedLocalizations.Values.ToList()); }
private void CombineAndWriteManifest() { string actionsFolder = Path.Combine(Directory.GetCurrentDirectory(), "DynamicOpenVR", "Actions"); if (!Directory.Exists(actionsFolder)) { Logger.Warn("Actions folder does not exist!"); return; } Logger.Trace($"Reading actions from '{actionsFolder}'"); string[] actionFiles = Directory.GetFiles(actionsFolder); var actionManifests = new List <ActionManifest>(); ushort version = 0; foreach (string actionFile in actionFiles) { try { Logger.Trace($"Reading '{actionFile}'"); using (var reader = new StreamReader(actionFile)) { string data = reader.ReadToEnd(); actionManifests.Add(JsonConvert.DeserializeObject <ActionManifest>(data)); version += BitConverter.ToUInt16(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(data)), 0); } } catch (Exception ex) { Logger.Error($"An error of type {ex.GetType().FullName} occured when trying to parse '{actionFile}': {ex.Message}"); } } List <ManifestDefaultBinding> defaultBindings = CombineAndWriteBindings(version); var manifest = new ActionManifest() { version = version, actions = actionManifests.SelectMany(m => m.actions).ToList(), actionSets = actionManifests.SelectMany(m => m.actionSets).ToList(), defaultBindings = defaultBindings, localization = CombineLocalizations(actionManifests) }; foreach (string actionSetName in manifest.actionSets.Select(a => a.Name)) { Logger.Trace($"Found defined action set '{actionSetName}'"); } foreach (string actionName in manifest.actions.Select(a => a.Name)) { Logger.Trace($"Found defined action '{actionName}'"); } foreach (string controllerType in manifest.defaultBindings.Select(a => a.ControllerType)) { Logger.Trace($"Found default binding for controller '{controllerType}'"); } Logger.Trace($"Writing action manifest to '{_actionManifestPath}'"); using (var writer = new StreamWriter(_actionManifestPath)) { writer.WriteLine(JsonConvert.SerializeObject(manifest, Formatting.Indented)); } }
public void DeregisterAction(OVRAction action) { Logger.Trace($"Deregistering action '{action.name}' ({action.id})"); _actions.Remove(action.id); }